Update PeerConnection client example to Unified Plan APIs

Bug: webrtc:9154
Change-Id: Icd53cfb57d96325a59c7964efe6276c10a3aebcd
Reviewed-on: https://webrtc-review.googlesource.com/70341
Commit-Queue: Steve Anton <steveanton@webrtc.org>
Reviewed-by: Seth Hampson <shampson@webrtc.org>
Reviewed-by: Tommi <tommi@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22912}
diff --git a/examples/peerconnection/client/conductor.cc b/examples/peerconnection/client/conductor.cc
index 5e56592..7e36746 100644
--- a/examples/peerconnection/client/conductor.cc
+++ b/examples/peerconnection/client/conductor.cc
@@ -24,8 +24,6 @@
 #include "rtc_base/json.h"
 #include "rtc_base/logging.h"
 
-using webrtc::SdpType;
-
 // Names used for a IceCandidate JSON object.
 const char kCandidateSdpMidName[] = "sdpMid";
 const char kCandidateSdpMlineIndexName[] = "sdpMLineIndex";
@@ -35,9 +33,6 @@
 const char kSessionDescriptionTypeName[] = "type";
 const char kSessionDescriptionSdpName[] = "sdp";
 
-#define DTLS_ON  true
-#define DTLS_OFF false
-
 class DummySetSessionDescriptionObserver
     : public webrtc::SetSessionDescriptionObserver {
  public:
@@ -49,10 +44,6 @@
   virtual void OnFailure(const std::string& error) {
     RTC_LOG(INFO) << __FUNCTION__ << " " << error;
   }
-
- protected:
-  DummySetSessionDescriptionObserver() {}
-  ~DummySetSessionDescriptionObserver() {}
 };
 
 Conductor::Conductor(PeerConnectionClient* client, MainWindow* main_wnd)
@@ -65,11 +56,11 @@
 }
 
 Conductor::~Conductor() {
-  RTC_DCHECK(peer_connection_.get() == NULL);
+  RTC_DCHECK(!peer_connection_);
 }
 
 bool Conductor::connection_active() const {
-  return peer_connection_.get() != NULL;
+  return peer_connection_ != nullptr;
 }
 
 void Conductor::Close() {
@@ -78,77 +69,73 @@
 }
 
 bool Conductor::InitializePeerConnection() {
-  RTC_DCHECK(peer_connection_factory_.get() == NULL);
-  RTC_DCHECK(peer_connection_.get() == NULL);
+  RTC_DCHECK(!peer_connection_factory_);
+  RTC_DCHECK(!peer_connection_);
 
   peer_connection_factory_ = webrtc::CreatePeerConnectionFactory(
       webrtc::CreateBuiltinAudioEncoderFactory(),
       webrtc::CreateBuiltinAudioDecoderFactory());
 
-  if (!peer_connection_factory_.get()) {
+  if (!peer_connection_factory_) {
     main_wnd_->MessageBox("Error",
         "Failed to initialize PeerConnectionFactory", true);
     DeletePeerConnection();
     return false;
   }
 
-  if (!CreatePeerConnection(DTLS_ON)) {
+  if (!CreatePeerConnection(/*dtls=*/true)) {
     main_wnd_->MessageBox("Error",
         "CreatePeerConnection failed", true);
     DeletePeerConnection();
   }
-  AddStreams();
-  return peer_connection_.get() != NULL;
+
+  AddTracks();
+
+  return peer_connection_ != nullptr;
 }
 
 bool Conductor::ReinitializePeerConnectionForLoopback() {
   loopback_ = true;
-  rtc::scoped_refptr<webrtc::StreamCollectionInterface> streams(
-      peer_connection_->local_streams());
-  peer_connection_ = NULL;
-  if (CreatePeerConnection(DTLS_OFF)) {
-    for (size_t i = 0; i < streams->count(); ++i)
-      peer_connection_->AddStream(streams->at(i));
-    peer_connection_->CreateOffer(this, NULL);
+  std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> senders =
+      peer_connection_->GetSenders();
+  peer_connection_ = nullptr;
+  if (CreatePeerConnection(/*dtls=*/false)) {
+    for (const auto& sender : senders) {
+      peer_connection_->AddTrack(sender->track(), sender->stream_ids());
+    }
+    peer_connection_->CreateOffer(
+        this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());
   }
-  return peer_connection_.get() != NULL;
+  return peer_connection_ != nullptr;
 }
 
 bool Conductor::CreatePeerConnection(bool dtls) {
-  RTC_DCHECK(peer_connection_factory_.get() != NULL);
-  RTC_DCHECK(peer_connection_.get() == NULL);
+  RTC_DCHECK(peer_connection_factory_);
+  RTC_DCHECK(!peer_connection_);
 
   webrtc::PeerConnectionInterface::RTCConfiguration config;
+  config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
+  config.enable_dtls_srtp = dtls;
   webrtc::PeerConnectionInterface::IceServer server;
   server.uri = GetPeerConnectionString();
   config.servers.push_back(server);
 
-  webrtc::FakeConstraints constraints;
-  if (dtls) {
-    constraints.AddOptional(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
-                            "true");
-  } else {
-    constraints.AddOptional(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
-                            "false");
-  }
-
   peer_connection_ = peer_connection_factory_->CreatePeerConnection(
-      config, &constraints, NULL, NULL, this);
-  return peer_connection_.get() != NULL;
+      config, nullptr, nullptr, this);
+  return peer_connection_ != nullptr;
 }
 
 void Conductor::DeletePeerConnection() {
-  peer_connection_ = NULL;
-  active_streams_.clear();
   main_wnd_->StopLocalRenderer();
   main_wnd_->StopRemoteRenderer();
-  peer_connection_factory_ = NULL;
+  peer_connection_ = nullptr;
+  peer_connection_factory_ = nullptr;
   peer_id_ = -1;
   loopback_ = false;
 }
 
 void Conductor::EnsureStreamingUI() {
-  RTC_DCHECK(peer_connection_.get() != NULL);
+  RTC_DCHECK(peer_connection_);
   if (main_wnd_->IsWindow()) {
     if (main_wnd_->current_ui() != MainWindow::STREAMING)
       main_wnd_->SwitchToStreamingUI();
@@ -159,17 +146,19 @@
 // PeerConnectionObserver implementation.
 //
 
-// Called when a remote stream is added
-void Conductor::OnAddStream(
-    rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) {
-  RTC_LOG(INFO) << __FUNCTION__ << " " << stream->id();
-  main_wnd_->QueueUIThreadCallback(NEW_STREAM_ADDED, stream.release());
+void Conductor::OnAddTrack(
+    rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver,
+    const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>&
+        streams) {
+  RTC_LOG(INFO) << __FUNCTION__ << " " << receiver->id();
+  main_wnd_->QueueUIThreadCallback(NEW_TRACK_ADDED,
+                                   receiver->track().release());
 }
 
-void Conductor::OnRemoveStream(
-    rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) {
-  RTC_LOG(INFO) << __FUNCTION__ << " " << stream->id();
-  main_wnd_->QueueUIThreadCallback(STREAM_REMOVED, stream.release());
+void Conductor::OnRemoveTrack(
+    rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver) {
+  RTC_LOG(INFO) << __FUNCTION__ << " " << receiver->id();
+  main_wnd_->QueueUIThreadCallback(TRACK_REMOVED, receiver->track().release());
 }
 
 void Conductor::OnIceCandidate(const webrtc::IceCandidateInterface* candidate) {
@@ -276,12 +265,13 @@
       }
       return;
     }
-    rtc::Optional<SdpType> type_maybe = webrtc::SdpTypeFromString(type_str);
+    rtc::Optional<webrtc::SdpType> type_maybe =
+        webrtc::SdpTypeFromString(type_str);
     if (!type_maybe) {
       RTC_LOG(LS_ERROR) << "Unknown SDP type: " << type_str;
       return;
     }
-    SdpType type = *type_maybe;
+    webrtc::SdpType type = *type_maybe;
     std::string sdp;
     if (!rtc::GetStringFromJsonObject(jmessage, kSessionDescriptionSdpName,
                                       &sdp)) {
@@ -300,10 +290,10 @@
     peer_connection_->SetRemoteDescription(
         DummySetSessionDescriptionObserver::Create(),
         session_description.release());
-    if (type == SdpType::kOffer) {
-      peer_connection_->CreateAnswer(this, NULL);
+    if (type == webrtc::SdpType::kOffer) {
+      peer_connection_->CreateAnswer(
+          this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());
     }
-    return;
   } else {
     std::string sdp_mid;
     int sdp_mlineindex = 0;
@@ -329,7 +319,6 @@
       return;
     }
     RTC_LOG(INFO) << " Received candidate :" << message;
-    return;
   }
 }
 
@@ -339,8 +328,8 @@
 }
 
 void Conductor::OnServerConnectionFailure() {
-    main_wnd_->MessageBox("Error", ("Failed to connect to " + server_).c_str(),
-                          true);
+  main_wnd_->MessageBox("Error", ("Failed to connect to " + server_).c_str(),
+                        true);
 }
 
 //
@@ -371,7 +360,8 @@
 
   if (InitializePeerConnection()) {
     peer_id_ = peer_id;
-    peer_connection_->CreateOffer(this, NULL);
+    peer_connection_->CreateOffer(
+        this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());
   } else {
     main_wnd_->MessageBox("Error", "Failed to initialize PeerConnection", true);
   }
@@ -407,41 +397,38 @@
   return capturer;
 }
 
-void Conductor::AddStreams() {
-  if (active_streams_.find(kStreamId) != active_streams_.end())
-    return;  // Already added.
+void Conductor::AddTracks() {
+  if (!peer_connection_->GetSenders().empty()) {
+    return;  // Already added tracks.
+  }
 
   rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
       peer_connection_factory_->CreateAudioTrack(
-          kAudioLabel, peer_connection_factory_->CreateAudioSource(NULL)));
+          kAudioLabel, peer_connection_factory_->CreateAudioSource(nullptr)));
+  auto result_or_error = peer_connection_->AddTrack(audio_track, {kStreamId});
+  if (!result_or_error.ok()) {
+    RTC_LOG(LS_ERROR) << "Failed to add audio track to PeerConnection: "
+                      << result_or_error.error().message();
+  }
 
-  rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track;
-  auto video_device(OpenVideoCaptureDevice());
+  std::unique_ptr<cricket::VideoCapturer> video_device =
+      OpenVideoCaptureDevice();
   if (video_device) {
-    video_track =
+    rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track_(
         peer_connection_factory_->CreateVideoTrack(
-            kVideoLabel,
-            peer_connection_factory_->CreateVideoSource(std::move(video_device),
-                                                        NULL));
-    main_wnd_->StartLocalRenderer(video_track);
+            kVideoLabel, peer_connection_factory_->CreateVideoSource(
+                             std::move(video_device), nullptr)));
+    main_wnd_->StartLocalRenderer(video_track_);
+
+    result_or_error = peer_connection_->AddTrack(video_track_, {kStreamId});
+    if (!result_or_error.ok()) {
+      RTC_LOG(LS_ERROR) << "Failed to add video track to PeerConnection: "
+                        << result_or_error.error().message();
+    }
   } else {
     RTC_LOG(LS_ERROR) << "OpenVideoCaptureDevice failed";
   }
 
-  rtc::scoped_refptr<webrtc::MediaStreamInterface> stream =
-      peer_connection_factory_->CreateLocalMediaStream(kStreamId);
-
-  stream->AddTrack(audio_track);
-  if (video_track)
-    stream->AddTrack(video_track);
-
-  if (!peer_connection_->AddStream(stream)) {
-    RTC_LOG(LS_ERROR) << "Adding stream to PeerConnection failed";
-  }
-  typedef std::pair<std::string,
-                    rtc::scoped_refptr<webrtc::MediaStreamInterface> >
-      MediaStreamPair;
-  active_streams_.insert(MediaStreamPair(stream->id(), stream));
   main_wnd_->SwitchToStreamingUI();
 }
 
@@ -462,8 +449,6 @@
       RTC_LOG(INFO) << "PEER_CONNECTION_CLOSED";
       DeletePeerConnection();
 
-      RTC_DCHECK(active_streams_.empty());
-
       if (main_wnd_->IsWindow()) {
         if (client_->is_connected()) {
           main_wnd_->SwitchToPeerList(client_->peers());
@@ -502,26 +487,20 @@
       break;
     }
 
-    case NEW_STREAM_ADDED: {
-      webrtc::MediaStreamInterface* stream =
-          reinterpret_cast<webrtc::MediaStreamInterface*>(
-          data);
-      webrtc::VideoTrackVector tracks = stream->GetVideoTracks();
-      // Only render the first track.
-      if (!tracks.empty()) {
-        webrtc::VideoTrackInterface* track = tracks[0];
-        main_wnd_->StartRemoteRenderer(track);
+    case NEW_TRACK_ADDED: {
+      auto* track = reinterpret_cast<webrtc::MediaStreamTrackInterface*>(data);
+      if (track->kind() == webrtc::MediaStreamTrackInterface::kVideoKind) {
+        auto* video_track = static_cast<webrtc::VideoTrackInterface*>(track);
+        main_wnd_->StartRemoteRenderer(video_track);
       }
-      stream->Release();
+      track->Release();
       break;
     }
 
-    case STREAM_REMOVED: {
-      // Remote peer stopped sending a stream.
-      webrtc::MediaStreamInterface* stream =
-          reinterpret_cast<webrtc::MediaStreamInterface*>(
-          data);
-      stream->Release();
+    case TRACK_REMOVED: {
+      // Remote peer stopped sending a track.
+      auto* track = reinterpret_cast<webrtc::MediaStreamTrackInterface*>(data);
+      track->Release();
       break;
     }
 
@@ -542,7 +521,7 @@
   if (loopback_) {
     // Replace message type from "offer" to "answer"
     std::unique_ptr<webrtc::SessionDescriptionInterface> session_description =
-        webrtc::CreateSessionDescription(SdpType::kAnswer, sdp);
+        webrtc::CreateSessionDescription(webrtc::SdpType::kAnswer, sdp);
     peer_connection_->SetRemoteDescription(
         DummySetSessionDescriptionObserver::Create(),
         session_description.release());