Added a callback function OnAddTrack to PeerConnectionObserver

Added the callback in native c++ API.
The callback function is called when a track is added and a new RtpReceiver is created.
The application can tell when tracks are added to the streams by listening to this callback.

BUG=webrtc:6112

Review-Url: https://codereview.webrtc.org/2505173002
Cr-Commit-Position: refs/heads/master@{#15142}
diff --git a/webrtc/api/peerconnection.cc b/webrtc/api/peerconnection.cc
index a1ce6ab..46bdec5 100644
--- a/webrtc/api/peerconnection.cc
+++ b/webrtc/api/peerconnection.cc
@@ -1426,20 +1426,29 @@
 void PeerConnection::CreateAudioReceiver(MediaStreamInterface* stream,
                                          const std::string& track_id,
                                          uint32_t ssrc) {
-  receivers_.push_back(
-      RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
+  rtc::scoped_refptr<RtpReceiverProxyWithInternal<RtpReceiverInternal>>
+      receiver = RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
           signaling_thread(), new AudioRtpReceiver(stream, track_id, ssrc,
-                                                   session_->voice_channel())));
+                                                   session_->voice_channel()));
+
+  receivers_.push_back(receiver);
+  std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams;
+  streams.push_back(rtc::scoped_refptr<MediaStreamInterface>(stream));
+  observer_->OnAddTrack(receiver, streams);
 }
 
 void PeerConnection::CreateVideoReceiver(MediaStreamInterface* stream,
                                          const std::string& track_id,
                                          uint32_t ssrc) {
-  receivers_.push_back(
-      RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
+  rtc::scoped_refptr<RtpReceiverProxyWithInternal<RtpReceiverInternal>>
+      receiver = RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
           signaling_thread(),
           new VideoRtpReceiver(stream, track_id, factory_->worker_thread(),
-                               ssrc, session_->video_channel())));
+                               ssrc, session_->video_channel()));
+  receivers_.push_back(receiver);
+  std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams;
+  streams.push_back(rtc::scoped_refptr<MediaStreamInterface>(stream));
+  observer_->OnAddTrack(receiver, streams);
 }
 
 // TODO(deadbeef): Keep RtpReceivers around even if track goes away in remote
diff --git a/webrtc/api/peerconnectioninterface.h b/webrtc/api/peerconnectioninterface.h
index a597c98..b304b14 100644
--- a/webrtc/api/peerconnectioninterface.h
+++ b/webrtc/api/peerconnectioninterface.h
@@ -598,6 +598,13 @@
   // Called when the ICE connection receiving status changes.
   virtual void OnIceConnectionReceivingChange(bool receiving) {}
 
+  // Called when a track is added to streams.
+  // TODO(zhihuang) Make this a pure virtual method when all its subclasses
+  // implement it.
+  virtual void OnAddTrack(
+      rtc::scoped_refptr<RtpReceiverInterface> receiver,
+      std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams) {}
+
  protected:
   // Dtor protected as objects shouldn't be deleted via this interface.
   ~PeerConnectionObserver() {}
diff --git a/webrtc/api/peerconnectioninterface_unittest.cc b/webrtc/api/peerconnectioninterface_unittest.cc
index 245e81c..c351412 100644
--- a/webrtc/api/peerconnectioninterface_unittest.cc
+++ b/webrtc/api/peerconnectioninterface_unittest.cc
@@ -91,6 +91,25 @@
     "a=ssrc:2 mslabel:stream1\r\n"
     "a=ssrc:2 label:videotrack0\r\n";
 
+// Reference SDP with a MediaStream with label "stream1" and audio track with
+// id "audio_1";
+static const char kSdpStringWithStream1AudioTrackOnly[] =
+    "v=0\r\n"
+    "o=- 0 0 IN IP4 127.0.0.1\r\n"
+    "s=-\r\n"
+    "t=0 0\r\n"
+    "a=ice-ufrag:e5785931\r\n"
+    "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
+    "a=fingerprint:sha-256 58:AB:6E:F5:F1:E4:57:B7:E9:46:F4:86:04:28:F9:A7:ED:"
+    "BD:AB:AE:40:EF:CE:9A:51:2C:2A:B1:9B:8B:78:84\r\n"
+    "m=audio 1 RTP/AVPF 103\r\n"
+    "a=mid:audio\r\n"
+    "a=sendrecv\r\n"
+    "a=rtpmap:103 ISAC/16000\r\n"
+    "a=ssrc:1 cname:stream1\r\n"
+    "a=ssrc:1 mslabel:stream1\r\n"
+    "a=ssrc:1 label:audiotrack0\r\n";
+
 // Reference SDP with two MediaStreams with label "stream1" and "stream2. Each
 // MediaStreams have one audio track and one video track.
 // This uses MSID.
@@ -499,13 +518,13 @@
   void OnIceConnectionChange(
       PeerConnectionInterface::IceConnectionState new_state) override {
     EXPECT_EQ(pc_->ice_connection_state(), new_state);
-    callback_triggered = true;
+    callback_triggered_ = true;
   }
   void OnIceGatheringChange(
       PeerConnectionInterface::IceGatheringState new_state) override {
     EXPECT_EQ(pc_->ice_gathering_state(), new_state);
     ice_complete_ = new_state == PeerConnectionInterface::kIceGatheringComplete;
-    callback_triggered = true;
+    callback_triggered_ = true;
   }
   void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
     EXPECT_NE(PeerConnectionInterface::kIceGatheringNew,
@@ -517,16 +536,24 @@
     last_candidate_.reset(webrtc::CreateIceCandidate(candidate->sdp_mid(),
         candidate->sdp_mline_index(), sdp, NULL));
     EXPECT_TRUE(last_candidate_.get() != NULL);
-    callback_triggered = true;
+    callback_triggered_ = true;
   }
 
   void OnIceCandidatesRemoved(
       const std::vector<cricket::Candidate>& candidates) override {
-    callback_triggered = true;
+    callback_triggered_ = true;
   }
 
   void OnIceConnectionReceivingChange(bool receiving) override {
-    callback_triggered = true;
+    callback_triggered_ = true;
+  }
+
+  void OnAddTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver,
+                  std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>
+                      streams) override {
+    EXPECT_TRUE(receiver != nullptr);
+    num_added_tracks_++;
+    last_added_track_label_ = receiver->id();
   }
 
   // Returns the label of the last added stream.
@@ -549,7 +576,9 @@
   rtc::scoped_refptr<StreamCollection> remote_streams_;
   bool renegotiation_needed_ = false;
   bool ice_complete_ = false;
-  bool callback_triggered = false;
+  bool callback_triggered_ = false;
+  int num_added_tracks_ = 0;
+  std::string last_added_track_label_;
 
  private:
   rtc::scoped_refptr<MediaStreamInterface> last_added_stream_;
@@ -1070,7 +1099,7 @@
   pc->Close();
 
   // No callbacks is expected to be called.
-  observer_.callback_triggered = false;
+  observer_.callback_triggered_ = false;
   std::vector<cricket::Candidate> candidates;
   pc_factory_for_test_->transport_controller->SignalGatheringState(
       cricket::IceGatheringState{});
@@ -1081,7 +1110,7 @@
   pc_factory_for_test_->transport_controller->SignalCandidatesRemoved(
       candidates);
   pc_factory_for_test_->transport_controller->SignalReceiving(false);
-  EXPECT_FALSE(observer_.callback_triggered);
+  EXPECT_FALSE(observer_.callback_triggered_);
 }
 
 // Generate different CNAMEs when PeerConnections are created.
@@ -2666,6 +2695,22 @@
   EXPECT_TRUE(ContainsSender(new_senders, kVideoTracks[0], kStreams[1]));
 }
 
+// This tests that PeerConnectionObserver::OnAddTrack is correctly called.
+TEST_F(PeerConnectionInterfaceTest, OnAddTrackCallback) {
+  FakeConstraints constraints;
+  constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
+                           true);
+  CreatePeerConnection(&constraints);
+  CreateAndSetRemoteOffer(kSdpStringWithStream1AudioTrackOnly);
+  EXPECT_EQ(observer_.num_added_tracks_, 1);
+  EXPECT_EQ(observer_.last_added_track_label_, kAudioTracks[0]);
+
+  // Create and set the updated remote SDP.
+  CreateAndSetRemoteOffer(kSdpStringWithStream1);
+  EXPECT_EQ(observer_.num_added_tracks_, 2);
+  EXPECT_EQ(observer_.last_added_track_label_, kVideoTracks[0]);
+}
+
 class PeerConnectionMediaConfigTest : public testing::Test {
  protected:
   void SetUp() override {