xref: /aosp_15_r20/external/webrtc/examples/peerconnection/client/conductor.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2012 The WebRTC Project Authors. All rights reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #include "examples/peerconnection/client/conductor.h"
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include <stddef.h>
14*d9f75844SAndroid Build Coastguard Worker #include <stdint.h>
15*d9f75844SAndroid Build Coastguard Worker 
16*d9f75844SAndroid Build Coastguard Worker #include <memory>
17*d9f75844SAndroid Build Coastguard Worker #include <utility>
18*d9f75844SAndroid Build Coastguard Worker #include <vector>
19*d9f75844SAndroid Build Coastguard Worker 
20*d9f75844SAndroid Build Coastguard Worker #include "absl/memory/memory.h"
21*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h"
22*d9f75844SAndroid Build Coastguard Worker #include "api/audio/audio_mixer.h"
23*d9f75844SAndroid Build Coastguard Worker #include "api/audio_codecs/audio_decoder_factory.h"
24*d9f75844SAndroid Build Coastguard Worker #include "api/audio_codecs/audio_encoder_factory.h"
25*d9f75844SAndroid Build Coastguard Worker #include "api/audio_codecs/builtin_audio_decoder_factory.h"
26*d9f75844SAndroid Build Coastguard Worker #include "api/audio_codecs/builtin_audio_encoder_factory.h"
27*d9f75844SAndroid Build Coastguard Worker #include "api/audio_options.h"
28*d9f75844SAndroid Build Coastguard Worker #include "api/create_peerconnection_factory.h"
29*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_sender_interface.h"
30*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/builtin_video_decoder_factory.h"
31*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/builtin_video_encoder_factory.h"
32*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/video_decoder_factory.h"
33*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/video_encoder_factory.h"
34*d9f75844SAndroid Build Coastguard Worker #include "examples/peerconnection/client/defaults.h"
35*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_device/include/audio_device.h"
36*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_processing/include/audio_processing.h"
37*d9f75844SAndroid Build Coastguard Worker #include "modules/video_capture/video_capture.h"
38*d9f75844SAndroid Build Coastguard Worker #include "modules/video_capture/video_capture_factory.h"
39*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/port_allocator.h"
40*d9f75844SAndroid Build Coastguard Worker #include "pc/video_track_source.h"
41*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
42*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/logging.h"
43*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/rtc_certificate_generator.h"
44*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/strings/json.h"
45*d9f75844SAndroid Build Coastguard Worker #include "test/vcm_capturer.h"
46*d9f75844SAndroid Build Coastguard Worker 
47*d9f75844SAndroid Build Coastguard Worker namespace {
48*d9f75844SAndroid Build Coastguard Worker // Names used for a IceCandidate JSON object.
49*d9f75844SAndroid Build Coastguard Worker const char kCandidateSdpMidName[] = "sdpMid";
50*d9f75844SAndroid Build Coastguard Worker const char kCandidateSdpMlineIndexName[] = "sdpMLineIndex";
51*d9f75844SAndroid Build Coastguard Worker const char kCandidateSdpName[] = "candidate";
52*d9f75844SAndroid Build Coastguard Worker 
53*d9f75844SAndroid Build Coastguard Worker // Names used for a SessionDescription JSON object.
54*d9f75844SAndroid Build Coastguard Worker const char kSessionDescriptionTypeName[] = "type";
55*d9f75844SAndroid Build Coastguard Worker const char kSessionDescriptionSdpName[] = "sdp";
56*d9f75844SAndroid Build Coastguard Worker 
57*d9f75844SAndroid Build Coastguard Worker class DummySetSessionDescriptionObserver
58*d9f75844SAndroid Build Coastguard Worker     : public webrtc::SetSessionDescriptionObserver {
59*d9f75844SAndroid Build Coastguard Worker  public:
Create()60*d9f75844SAndroid Build Coastguard Worker   static rtc::scoped_refptr<DummySetSessionDescriptionObserver> Create() {
61*d9f75844SAndroid Build Coastguard Worker     return rtc::make_ref_counted<DummySetSessionDescriptionObserver>();
62*d9f75844SAndroid Build Coastguard Worker   }
OnSuccess()63*d9f75844SAndroid Build Coastguard Worker   virtual void OnSuccess() { RTC_LOG(LS_INFO) << __FUNCTION__; }
OnFailure(webrtc::RTCError error)64*d9f75844SAndroid Build Coastguard Worker   virtual void OnFailure(webrtc::RTCError error) {
65*d9f75844SAndroid Build Coastguard Worker     RTC_LOG(LS_INFO) << __FUNCTION__ << " " << ToString(error.type()) << ": "
66*d9f75844SAndroid Build Coastguard Worker                      << error.message();
67*d9f75844SAndroid Build Coastguard Worker   }
68*d9f75844SAndroid Build Coastguard Worker };
69*d9f75844SAndroid Build Coastguard Worker 
70*d9f75844SAndroid Build Coastguard Worker class CapturerTrackSource : public webrtc::VideoTrackSource {
71*d9f75844SAndroid Build Coastguard Worker  public:
Create()72*d9f75844SAndroid Build Coastguard Worker   static rtc::scoped_refptr<CapturerTrackSource> Create() {
73*d9f75844SAndroid Build Coastguard Worker     const size_t kWidth = 640;
74*d9f75844SAndroid Build Coastguard Worker     const size_t kHeight = 480;
75*d9f75844SAndroid Build Coastguard Worker     const size_t kFps = 30;
76*d9f75844SAndroid Build Coastguard Worker     std::unique_ptr<webrtc::test::VcmCapturer> capturer;
77*d9f75844SAndroid Build Coastguard Worker     std::unique_ptr<webrtc::VideoCaptureModule::DeviceInfo> info(
78*d9f75844SAndroid Build Coastguard Worker         webrtc::VideoCaptureFactory::CreateDeviceInfo());
79*d9f75844SAndroid Build Coastguard Worker     if (!info) {
80*d9f75844SAndroid Build Coastguard Worker       return nullptr;
81*d9f75844SAndroid Build Coastguard Worker     }
82*d9f75844SAndroid Build Coastguard Worker     int num_devices = info->NumberOfDevices();
83*d9f75844SAndroid Build Coastguard Worker     for (int i = 0; i < num_devices; ++i) {
84*d9f75844SAndroid Build Coastguard Worker       capturer = absl::WrapUnique(
85*d9f75844SAndroid Build Coastguard Worker           webrtc::test::VcmCapturer::Create(kWidth, kHeight, kFps, i));
86*d9f75844SAndroid Build Coastguard Worker       if (capturer) {
87*d9f75844SAndroid Build Coastguard Worker         return rtc::make_ref_counted<CapturerTrackSource>(std::move(capturer));
88*d9f75844SAndroid Build Coastguard Worker       }
89*d9f75844SAndroid Build Coastguard Worker     }
90*d9f75844SAndroid Build Coastguard Worker 
91*d9f75844SAndroid Build Coastguard Worker     return nullptr;
92*d9f75844SAndroid Build Coastguard Worker   }
93*d9f75844SAndroid Build Coastguard Worker 
94*d9f75844SAndroid Build Coastguard Worker  protected:
CapturerTrackSource(std::unique_ptr<webrtc::test::VcmCapturer> capturer)95*d9f75844SAndroid Build Coastguard Worker   explicit CapturerTrackSource(
96*d9f75844SAndroid Build Coastguard Worker       std::unique_ptr<webrtc::test::VcmCapturer> capturer)
97*d9f75844SAndroid Build Coastguard Worker       : VideoTrackSource(/*remote=*/false), capturer_(std::move(capturer)) {}
98*d9f75844SAndroid Build Coastguard Worker 
99*d9f75844SAndroid Build Coastguard Worker  private:
source()100*d9f75844SAndroid Build Coastguard Worker   rtc::VideoSourceInterface<webrtc::VideoFrame>* source() override {
101*d9f75844SAndroid Build Coastguard Worker     return capturer_.get();
102*d9f75844SAndroid Build Coastguard Worker   }
103*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<webrtc::test::VcmCapturer> capturer_;
104*d9f75844SAndroid Build Coastguard Worker };
105*d9f75844SAndroid Build Coastguard Worker 
106*d9f75844SAndroid Build Coastguard Worker }  // namespace
107*d9f75844SAndroid Build Coastguard Worker 
Conductor(PeerConnectionClient * client,MainWindow * main_wnd)108*d9f75844SAndroid Build Coastguard Worker Conductor::Conductor(PeerConnectionClient* client, MainWindow* main_wnd)
109*d9f75844SAndroid Build Coastguard Worker     : peer_id_(-1), loopback_(false), client_(client), main_wnd_(main_wnd) {
110*d9f75844SAndroid Build Coastguard Worker   client_->RegisterObserver(this);
111*d9f75844SAndroid Build Coastguard Worker   main_wnd->RegisterObserver(this);
112*d9f75844SAndroid Build Coastguard Worker }
113*d9f75844SAndroid Build Coastguard Worker 
~Conductor()114*d9f75844SAndroid Build Coastguard Worker Conductor::~Conductor() {
115*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK(!peer_connection_);
116*d9f75844SAndroid Build Coastguard Worker }
117*d9f75844SAndroid Build Coastguard Worker 
connection_active() const118*d9f75844SAndroid Build Coastguard Worker bool Conductor::connection_active() const {
119*d9f75844SAndroid Build Coastguard Worker   return peer_connection_ != nullptr;
120*d9f75844SAndroid Build Coastguard Worker }
121*d9f75844SAndroid Build Coastguard Worker 
Close()122*d9f75844SAndroid Build Coastguard Worker void Conductor::Close() {
123*d9f75844SAndroid Build Coastguard Worker   client_->SignOut();
124*d9f75844SAndroid Build Coastguard Worker   DeletePeerConnection();
125*d9f75844SAndroid Build Coastguard Worker }
126*d9f75844SAndroid Build Coastguard Worker 
InitializePeerConnection()127*d9f75844SAndroid Build Coastguard Worker bool Conductor::InitializePeerConnection() {
128*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK(!peer_connection_factory_);
129*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK(!peer_connection_);
130*d9f75844SAndroid Build Coastguard Worker 
131*d9f75844SAndroid Build Coastguard Worker   if (!signaling_thread_.get()) {
132*d9f75844SAndroid Build Coastguard Worker     signaling_thread_ = rtc::Thread::CreateWithSocketServer();
133*d9f75844SAndroid Build Coastguard Worker     signaling_thread_->Start();
134*d9f75844SAndroid Build Coastguard Worker   }
135*d9f75844SAndroid Build Coastguard Worker   peer_connection_factory_ = webrtc::CreatePeerConnectionFactory(
136*d9f75844SAndroid Build Coastguard Worker       nullptr /* network_thread */, nullptr /* worker_thread */,
137*d9f75844SAndroid Build Coastguard Worker       signaling_thread_.get(), nullptr /* default_adm */,
138*d9f75844SAndroid Build Coastguard Worker       webrtc::CreateBuiltinAudioEncoderFactory(),
139*d9f75844SAndroid Build Coastguard Worker       webrtc::CreateBuiltinAudioDecoderFactory(),
140*d9f75844SAndroid Build Coastguard Worker       webrtc::CreateBuiltinVideoEncoderFactory(),
141*d9f75844SAndroid Build Coastguard Worker       webrtc::CreateBuiltinVideoDecoderFactory(), nullptr /* audio_mixer */,
142*d9f75844SAndroid Build Coastguard Worker       nullptr /* audio_processing */);
143*d9f75844SAndroid Build Coastguard Worker 
144*d9f75844SAndroid Build Coastguard Worker   if (!peer_connection_factory_) {
145*d9f75844SAndroid Build Coastguard Worker     main_wnd_->MessageBox("Error", "Failed to initialize PeerConnectionFactory",
146*d9f75844SAndroid Build Coastguard Worker                           true);
147*d9f75844SAndroid Build Coastguard Worker     DeletePeerConnection();
148*d9f75844SAndroid Build Coastguard Worker     return false;
149*d9f75844SAndroid Build Coastguard Worker   }
150*d9f75844SAndroid Build Coastguard Worker 
151*d9f75844SAndroid Build Coastguard Worker   if (!CreatePeerConnection()) {
152*d9f75844SAndroid Build Coastguard Worker     main_wnd_->MessageBox("Error", "CreatePeerConnection failed", true);
153*d9f75844SAndroid Build Coastguard Worker     DeletePeerConnection();
154*d9f75844SAndroid Build Coastguard Worker   }
155*d9f75844SAndroid Build Coastguard Worker 
156*d9f75844SAndroid Build Coastguard Worker   AddTracks();
157*d9f75844SAndroid Build Coastguard Worker 
158*d9f75844SAndroid Build Coastguard Worker   return peer_connection_ != nullptr;
159*d9f75844SAndroid Build Coastguard Worker }
160*d9f75844SAndroid Build Coastguard Worker 
ReinitializePeerConnectionForLoopback()161*d9f75844SAndroid Build Coastguard Worker bool Conductor::ReinitializePeerConnectionForLoopback() {
162*d9f75844SAndroid Build Coastguard Worker   loopback_ = true;
163*d9f75844SAndroid Build Coastguard Worker   std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> senders =
164*d9f75844SAndroid Build Coastguard Worker       peer_connection_->GetSenders();
165*d9f75844SAndroid Build Coastguard Worker   peer_connection_ = nullptr;
166*d9f75844SAndroid Build Coastguard Worker   // Loopback is only possible if encryption is disabled.
167*d9f75844SAndroid Build Coastguard Worker   webrtc::PeerConnectionFactoryInterface::Options options;
168*d9f75844SAndroid Build Coastguard Worker   options.disable_encryption = true;
169*d9f75844SAndroid Build Coastguard Worker   peer_connection_factory_->SetOptions(options);
170*d9f75844SAndroid Build Coastguard Worker   if (CreatePeerConnection()) {
171*d9f75844SAndroid Build Coastguard Worker     for (const auto& sender : senders) {
172*d9f75844SAndroid Build Coastguard Worker       peer_connection_->AddTrack(sender->track(), sender->stream_ids());
173*d9f75844SAndroid Build Coastguard Worker     }
174*d9f75844SAndroid Build Coastguard Worker     peer_connection_->CreateOffer(
175*d9f75844SAndroid Build Coastguard Worker         this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());
176*d9f75844SAndroid Build Coastguard Worker   }
177*d9f75844SAndroid Build Coastguard Worker   options.disable_encryption = false;
178*d9f75844SAndroid Build Coastguard Worker   peer_connection_factory_->SetOptions(options);
179*d9f75844SAndroid Build Coastguard Worker   return peer_connection_ != nullptr;
180*d9f75844SAndroid Build Coastguard Worker }
181*d9f75844SAndroid Build Coastguard Worker 
CreatePeerConnection()182*d9f75844SAndroid Build Coastguard Worker bool Conductor::CreatePeerConnection() {
183*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK(peer_connection_factory_);
184*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK(!peer_connection_);
185*d9f75844SAndroid Build Coastguard Worker 
186*d9f75844SAndroid Build Coastguard Worker   webrtc::PeerConnectionInterface::RTCConfiguration config;
187*d9f75844SAndroid Build Coastguard Worker   config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
188*d9f75844SAndroid Build Coastguard Worker   webrtc::PeerConnectionInterface::IceServer server;
189*d9f75844SAndroid Build Coastguard Worker   server.uri = GetPeerConnectionString();
190*d9f75844SAndroid Build Coastguard Worker   config.servers.push_back(server);
191*d9f75844SAndroid Build Coastguard Worker 
192*d9f75844SAndroid Build Coastguard Worker   webrtc::PeerConnectionDependencies pc_dependencies(this);
193*d9f75844SAndroid Build Coastguard Worker   auto error_or_peer_connection =
194*d9f75844SAndroid Build Coastguard Worker       peer_connection_factory_->CreatePeerConnectionOrError(
195*d9f75844SAndroid Build Coastguard Worker           config, std::move(pc_dependencies));
196*d9f75844SAndroid Build Coastguard Worker   if (error_or_peer_connection.ok()) {
197*d9f75844SAndroid Build Coastguard Worker     peer_connection_ = std::move(error_or_peer_connection.value());
198*d9f75844SAndroid Build Coastguard Worker   }
199*d9f75844SAndroid Build Coastguard Worker   return peer_connection_ != nullptr;
200*d9f75844SAndroid Build Coastguard Worker }
201*d9f75844SAndroid Build Coastguard Worker 
DeletePeerConnection()202*d9f75844SAndroid Build Coastguard Worker void Conductor::DeletePeerConnection() {
203*d9f75844SAndroid Build Coastguard Worker   main_wnd_->StopLocalRenderer();
204*d9f75844SAndroid Build Coastguard Worker   main_wnd_->StopRemoteRenderer();
205*d9f75844SAndroid Build Coastguard Worker   peer_connection_ = nullptr;
206*d9f75844SAndroid Build Coastguard Worker   peer_connection_factory_ = nullptr;
207*d9f75844SAndroid Build Coastguard Worker   peer_id_ = -1;
208*d9f75844SAndroid Build Coastguard Worker   loopback_ = false;
209*d9f75844SAndroid Build Coastguard Worker }
210*d9f75844SAndroid Build Coastguard Worker 
EnsureStreamingUI()211*d9f75844SAndroid Build Coastguard Worker void Conductor::EnsureStreamingUI() {
212*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK(peer_connection_);
213*d9f75844SAndroid Build Coastguard Worker   if (main_wnd_->IsWindow()) {
214*d9f75844SAndroid Build Coastguard Worker     if (main_wnd_->current_ui() != MainWindow::STREAMING)
215*d9f75844SAndroid Build Coastguard Worker       main_wnd_->SwitchToStreamingUI();
216*d9f75844SAndroid Build Coastguard Worker   }
217*d9f75844SAndroid Build Coastguard Worker }
218*d9f75844SAndroid Build Coastguard Worker 
219*d9f75844SAndroid Build Coastguard Worker //
220*d9f75844SAndroid Build Coastguard Worker // PeerConnectionObserver implementation.
221*d9f75844SAndroid Build Coastguard Worker //
222*d9f75844SAndroid Build Coastguard Worker 
OnAddTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver,const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>> & streams)223*d9f75844SAndroid Build Coastguard Worker void Conductor::OnAddTrack(
224*d9f75844SAndroid Build Coastguard Worker     rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver,
225*d9f75844SAndroid Build Coastguard Worker     const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>&
226*d9f75844SAndroid Build Coastguard Worker         streams) {
227*d9f75844SAndroid Build Coastguard Worker   RTC_LOG(LS_INFO) << __FUNCTION__ << " " << receiver->id();
228*d9f75844SAndroid Build Coastguard Worker   main_wnd_->QueueUIThreadCallback(NEW_TRACK_ADDED,
229*d9f75844SAndroid Build Coastguard Worker                                    receiver->track().release());
230*d9f75844SAndroid Build Coastguard Worker }
231*d9f75844SAndroid Build Coastguard Worker 
OnRemoveTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver)232*d9f75844SAndroid Build Coastguard Worker void Conductor::OnRemoveTrack(
233*d9f75844SAndroid Build Coastguard Worker     rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver) {
234*d9f75844SAndroid Build Coastguard Worker   RTC_LOG(LS_INFO) << __FUNCTION__ << " " << receiver->id();
235*d9f75844SAndroid Build Coastguard Worker   main_wnd_->QueueUIThreadCallback(TRACK_REMOVED, receiver->track().release());
236*d9f75844SAndroid Build Coastguard Worker }
237*d9f75844SAndroid Build Coastguard Worker 
OnIceCandidate(const webrtc::IceCandidateInterface * candidate)238*d9f75844SAndroid Build Coastguard Worker void Conductor::OnIceCandidate(const webrtc::IceCandidateInterface* candidate) {
239*d9f75844SAndroid Build Coastguard Worker   RTC_LOG(LS_INFO) << __FUNCTION__ << " " << candidate->sdp_mline_index();
240*d9f75844SAndroid Build Coastguard Worker   // For loopback test. To save some connecting delay.
241*d9f75844SAndroid Build Coastguard Worker   if (loopback_) {
242*d9f75844SAndroid Build Coastguard Worker     if (!peer_connection_->AddIceCandidate(candidate)) {
243*d9f75844SAndroid Build Coastguard Worker       RTC_LOG(LS_WARNING) << "Failed to apply the received candidate";
244*d9f75844SAndroid Build Coastguard Worker     }
245*d9f75844SAndroid Build Coastguard Worker     return;
246*d9f75844SAndroid Build Coastguard Worker   }
247*d9f75844SAndroid Build Coastguard Worker 
248*d9f75844SAndroid Build Coastguard Worker   Json::Value jmessage;
249*d9f75844SAndroid Build Coastguard Worker   jmessage[kCandidateSdpMidName] = candidate->sdp_mid();
250*d9f75844SAndroid Build Coastguard Worker   jmessage[kCandidateSdpMlineIndexName] = candidate->sdp_mline_index();
251*d9f75844SAndroid Build Coastguard Worker   std::string sdp;
252*d9f75844SAndroid Build Coastguard Worker   if (!candidate->ToString(&sdp)) {
253*d9f75844SAndroid Build Coastguard Worker     RTC_LOG(LS_ERROR) << "Failed to serialize candidate";
254*d9f75844SAndroid Build Coastguard Worker     return;
255*d9f75844SAndroid Build Coastguard Worker   }
256*d9f75844SAndroid Build Coastguard Worker   jmessage[kCandidateSdpName] = sdp;
257*d9f75844SAndroid Build Coastguard Worker 
258*d9f75844SAndroid Build Coastguard Worker   Json::StreamWriterBuilder factory;
259*d9f75844SAndroid Build Coastguard Worker   SendMessage(Json::writeString(factory, jmessage));
260*d9f75844SAndroid Build Coastguard Worker }
261*d9f75844SAndroid Build Coastguard Worker 
262*d9f75844SAndroid Build Coastguard Worker //
263*d9f75844SAndroid Build Coastguard Worker // PeerConnectionClientObserver implementation.
264*d9f75844SAndroid Build Coastguard Worker //
265*d9f75844SAndroid Build Coastguard Worker 
OnSignedIn()266*d9f75844SAndroid Build Coastguard Worker void Conductor::OnSignedIn() {
267*d9f75844SAndroid Build Coastguard Worker   RTC_LOG(LS_INFO) << __FUNCTION__;
268*d9f75844SAndroid Build Coastguard Worker   main_wnd_->SwitchToPeerList(client_->peers());
269*d9f75844SAndroid Build Coastguard Worker }
270*d9f75844SAndroid Build Coastguard Worker 
OnDisconnected()271*d9f75844SAndroid Build Coastguard Worker void Conductor::OnDisconnected() {
272*d9f75844SAndroid Build Coastguard Worker   RTC_LOG(LS_INFO) << __FUNCTION__;
273*d9f75844SAndroid Build Coastguard Worker 
274*d9f75844SAndroid Build Coastguard Worker   DeletePeerConnection();
275*d9f75844SAndroid Build Coastguard Worker 
276*d9f75844SAndroid Build Coastguard Worker   if (main_wnd_->IsWindow())
277*d9f75844SAndroid Build Coastguard Worker     main_wnd_->SwitchToConnectUI();
278*d9f75844SAndroid Build Coastguard Worker }
279*d9f75844SAndroid Build Coastguard Worker 
OnPeerConnected(int id,const std::string & name)280*d9f75844SAndroid Build Coastguard Worker void Conductor::OnPeerConnected(int id, const std::string& name) {
281*d9f75844SAndroid Build Coastguard Worker   RTC_LOG(LS_INFO) << __FUNCTION__;
282*d9f75844SAndroid Build Coastguard Worker   // Refresh the list if we're showing it.
283*d9f75844SAndroid Build Coastguard Worker   if (main_wnd_->current_ui() == MainWindow::LIST_PEERS)
284*d9f75844SAndroid Build Coastguard Worker     main_wnd_->SwitchToPeerList(client_->peers());
285*d9f75844SAndroid Build Coastguard Worker }
286*d9f75844SAndroid Build Coastguard Worker 
OnPeerDisconnected(int id)287*d9f75844SAndroid Build Coastguard Worker void Conductor::OnPeerDisconnected(int id) {
288*d9f75844SAndroid Build Coastguard Worker   RTC_LOG(LS_INFO) << __FUNCTION__;
289*d9f75844SAndroid Build Coastguard Worker   if (id == peer_id_) {
290*d9f75844SAndroid Build Coastguard Worker     RTC_LOG(LS_INFO) << "Our peer disconnected";
291*d9f75844SAndroid Build Coastguard Worker     main_wnd_->QueueUIThreadCallback(PEER_CONNECTION_CLOSED, NULL);
292*d9f75844SAndroid Build Coastguard Worker   } else {
293*d9f75844SAndroid Build Coastguard Worker     // Refresh the list if we're showing it.
294*d9f75844SAndroid Build Coastguard Worker     if (main_wnd_->current_ui() == MainWindow::LIST_PEERS)
295*d9f75844SAndroid Build Coastguard Worker       main_wnd_->SwitchToPeerList(client_->peers());
296*d9f75844SAndroid Build Coastguard Worker   }
297*d9f75844SAndroid Build Coastguard Worker }
298*d9f75844SAndroid Build Coastguard Worker 
OnMessageFromPeer(int peer_id,const std::string & message)299*d9f75844SAndroid Build Coastguard Worker void Conductor::OnMessageFromPeer(int peer_id, const std::string& message) {
300*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK(peer_id_ == peer_id || peer_id_ == -1);
301*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK(!message.empty());
302*d9f75844SAndroid Build Coastguard Worker 
303*d9f75844SAndroid Build Coastguard Worker   if (!peer_connection_.get()) {
304*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK(peer_id_ == -1);
305*d9f75844SAndroid Build Coastguard Worker     peer_id_ = peer_id;
306*d9f75844SAndroid Build Coastguard Worker 
307*d9f75844SAndroid Build Coastguard Worker     if (!InitializePeerConnection()) {
308*d9f75844SAndroid Build Coastguard Worker       RTC_LOG(LS_ERROR) << "Failed to initialize our PeerConnection instance";
309*d9f75844SAndroid Build Coastguard Worker       client_->SignOut();
310*d9f75844SAndroid Build Coastguard Worker       return;
311*d9f75844SAndroid Build Coastguard Worker     }
312*d9f75844SAndroid Build Coastguard Worker   } else if (peer_id != peer_id_) {
313*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK(peer_id_ != -1);
314*d9f75844SAndroid Build Coastguard Worker     RTC_LOG(LS_WARNING)
315*d9f75844SAndroid Build Coastguard Worker         << "Received a message from unknown peer while already in a "
316*d9f75844SAndroid Build Coastguard Worker            "conversation with a different peer.";
317*d9f75844SAndroid Build Coastguard Worker     return;
318*d9f75844SAndroid Build Coastguard Worker   }
319*d9f75844SAndroid Build Coastguard Worker 
320*d9f75844SAndroid Build Coastguard Worker   Json::CharReaderBuilder factory;
321*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<Json::CharReader> reader =
322*d9f75844SAndroid Build Coastguard Worker       absl::WrapUnique(factory.newCharReader());
323*d9f75844SAndroid Build Coastguard Worker   Json::Value jmessage;
324*d9f75844SAndroid Build Coastguard Worker   if (!reader->parse(message.data(), message.data() + message.length(),
325*d9f75844SAndroid Build Coastguard Worker                      &jmessage, nullptr)) {
326*d9f75844SAndroid Build Coastguard Worker     RTC_LOG(LS_WARNING) << "Received unknown message. " << message;
327*d9f75844SAndroid Build Coastguard Worker     return;
328*d9f75844SAndroid Build Coastguard Worker   }
329*d9f75844SAndroid Build Coastguard Worker   std::string type_str;
330*d9f75844SAndroid Build Coastguard Worker   std::string json_object;
331*d9f75844SAndroid Build Coastguard Worker 
332*d9f75844SAndroid Build Coastguard Worker   rtc::GetStringFromJsonObject(jmessage, kSessionDescriptionTypeName,
333*d9f75844SAndroid Build Coastguard Worker                                &type_str);
334*d9f75844SAndroid Build Coastguard Worker   if (!type_str.empty()) {
335*d9f75844SAndroid Build Coastguard Worker     if (type_str == "offer-loopback") {
336*d9f75844SAndroid Build Coastguard Worker       // This is a loopback call.
337*d9f75844SAndroid Build Coastguard Worker       // Recreate the peerconnection with DTLS disabled.
338*d9f75844SAndroid Build Coastguard Worker       if (!ReinitializePeerConnectionForLoopback()) {
339*d9f75844SAndroid Build Coastguard Worker         RTC_LOG(LS_ERROR) << "Failed to initialize our PeerConnection instance";
340*d9f75844SAndroid Build Coastguard Worker         DeletePeerConnection();
341*d9f75844SAndroid Build Coastguard Worker         client_->SignOut();
342*d9f75844SAndroid Build Coastguard Worker       }
343*d9f75844SAndroid Build Coastguard Worker       return;
344*d9f75844SAndroid Build Coastguard Worker     }
345*d9f75844SAndroid Build Coastguard Worker     absl::optional<webrtc::SdpType> type_maybe =
346*d9f75844SAndroid Build Coastguard Worker         webrtc::SdpTypeFromString(type_str);
347*d9f75844SAndroid Build Coastguard Worker     if (!type_maybe) {
348*d9f75844SAndroid Build Coastguard Worker       RTC_LOG(LS_ERROR) << "Unknown SDP type: " << type_str;
349*d9f75844SAndroid Build Coastguard Worker       return;
350*d9f75844SAndroid Build Coastguard Worker     }
351*d9f75844SAndroid Build Coastguard Worker     webrtc::SdpType type = *type_maybe;
352*d9f75844SAndroid Build Coastguard Worker     std::string sdp;
353*d9f75844SAndroid Build Coastguard Worker     if (!rtc::GetStringFromJsonObject(jmessage, kSessionDescriptionSdpName,
354*d9f75844SAndroid Build Coastguard Worker                                       &sdp)) {
355*d9f75844SAndroid Build Coastguard Worker       RTC_LOG(LS_WARNING)
356*d9f75844SAndroid Build Coastguard Worker           << "Can't parse received session description message.";
357*d9f75844SAndroid Build Coastguard Worker       return;
358*d9f75844SAndroid Build Coastguard Worker     }
359*d9f75844SAndroid Build Coastguard Worker     webrtc::SdpParseError error;
360*d9f75844SAndroid Build Coastguard Worker     std::unique_ptr<webrtc::SessionDescriptionInterface> session_description =
361*d9f75844SAndroid Build Coastguard Worker         webrtc::CreateSessionDescription(type, sdp, &error);
362*d9f75844SAndroid Build Coastguard Worker     if (!session_description) {
363*d9f75844SAndroid Build Coastguard Worker       RTC_LOG(LS_WARNING)
364*d9f75844SAndroid Build Coastguard Worker           << "Can't parse received session description message. "
365*d9f75844SAndroid Build Coastguard Worker              "SdpParseError was: "
366*d9f75844SAndroid Build Coastguard Worker           << error.description;
367*d9f75844SAndroid Build Coastguard Worker       return;
368*d9f75844SAndroid Build Coastguard Worker     }
369*d9f75844SAndroid Build Coastguard Worker     RTC_LOG(LS_INFO) << " Received session description :" << message;
370*d9f75844SAndroid Build Coastguard Worker     peer_connection_->SetRemoteDescription(
371*d9f75844SAndroid Build Coastguard Worker         DummySetSessionDescriptionObserver::Create().get(),
372*d9f75844SAndroid Build Coastguard Worker         session_description.release());
373*d9f75844SAndroid Build Coastguard Worker     if (type == webrtc::SdpType::kOffer) {
374*d9f75844SAndroid Build Coastguard Worker       peer_connection_->CreateAnswer(
375*d9f75844SAndroid Build Coastguard Worker           this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());
376*d9f75844SAndroid Build Coastguard Worker     }
377*d9f75844SAndroid Build Coastguard Worker   } else {
378*d9f75844SAndroid Build Coastguard Worker     std::string sdp_mid;
379*d9f75844SAndroid Build Coastguard Worker     int sdp_mlineindex = 0;
380*d9f75844SAndroid Build Coastguard Worker     std::string sdp;
381*d9f75844SAndroid Build Coastguard Worker     if (!rtc::GetStringFromJsonObject(jmessage, kCandidateSdpMidName,
382*d9f75844SAndroid Build Coastguard Worker                                       &sdp_mid) ||
383*d9f75844SAndroid Build Coastguard Worker         !rtc::GetIntFromJsonObject(jmessage, kCandidateSdpMlineIndexName,
384*d9f75844SAndroid Build Coastguard Worker                                    &sdp_mlineindex) ||
385*d9f75844SAndroid Build Coastguard Worker         !rtc::GetStringFromJsonObject(jmessage, kCandidateSdpName, &sdp)) {
386*d9f75844SAndroid Build Coastguard Worker       RTC_LOG(LS_WARNING) << "Can't parse received message.";
387*d9f75844SAndroid Build Coastguard Worker       return;
388*d9f75844SAndroid Build Coastguard Worker     }
389*d9f75844SAndroid Build Coastguard Worker     webrtc::SdpParseError error;
390*d9f75844SAndroid Build Coastguard Worker     std::unique_ptr<webrtc::IceCandidateInterface> candidate(
391*d9f75844SAndroid Build Coastguard Worker         webrtc::CreateIceCandidate(sdp_mid, sdp_mlineindex, sdp, &error));
392*d9f75844SAndroid Build Coastguard Worker     if (!candidate.get()) {
393*d9f75844SAndroid Build Coastguard Worker       RTC_LOG(LS_WARNING) << "Can't parse received candidate message. "
394*d9f75844SAndroid Build Coastguard Worker                              "SdpParseError was: "
395*d9f75844SAndroid Build Coastguard Worker                           << error.description;
396*d9f75844SAndroid Build Coastguard Worker       return;
397*d9f75844SAndroid Build Coastguard Worker     }
398*d9f75844SAndroid Build Coastguard Worker     if (!peer_connection_->AddIceCandidate(candidate.get())) {
399*d9f75844SAndroid Build Coastguard Worker       RTC_LOG(LS_WARNING) << "Failed to apply the received candidate";
400*d9f75844SAndroid Build Coastguard Worker       return;
401*d9f75844SAndroid Build Coastguard Worker     }
402*d9f75844SAndroid Build Coastguard Worker     RTC_LOG(LS_INFO) << " Received candidate :" << message;
403*d9f75844SAndroid Build Coastguard Worker   }
404*d9f75844SAndroid Build Coastguard Worker }
405*d9f75844SAndroid Build Coastguard Worker 
OnMessageSent(int err)406*d9f75844SAndroid Build Coastguard Worker void Conductor::OnMessageSent(int err) {
407*d9f75844SAndroid Build Coastguard Worker   // Process the next pending message if any.
408*d9f75844SAndroid Build Coastguard Worker   main_wnd_->QueueUIThreadCallback(SEND_MESSAGE_TO_PEER, NULL);
409*d9f75844SAndroid Build Coastguard Worker }
410*d9f75844SAndroid Build Coastguard Worker 
OnServerConnectionFailure()411*d9f75844SAndroid Build Coastguard Worker void Conductor::OnServerConnectionFailure() {
412*d9f75844SAndroid Build Coastguard Worker   main_wnd_->MessageBox("Error", ("Failed to connect to " + server_).c_str(),
413*d9f75844SAndroid Build Coastguard Worker                         true);
414*d9f75844SAndroid Build Coastguard Worker }
415*d9f75844SAndroid Build Coastguard Worker 
416*d9f75844SAndroid Build Coastguard Worker //
417*d9f75844SAndroid Build Coastguard Worker // MainWndCallback implementation.
418*d9f75844SAndroid Build Coastguard Worker //
419*d9f75844SAndroid Build Coastguard Worker 
StartLogin(const std::string & server,int port)420*d9f75844SAndroid Build Coastguard Worker void Conductor::StartLogin(const std::string& server, int port) {
421*d9f75844SAndroid Build Coastguard Worker   if (client_->is_connected())
422*d9f75844SAndroid Build Coastguard Worker     return;
423*d9f75844SAndroid Build Coastguard Worker   server_ = server;
424*d9f75844SAndroid Build Coastguard Worker   client_->Connect(server, port, GetPeerName());
425*d9f75844SAndroid Build Coastguard Worker }
426*d9f75844SAndroid Build Coastguard Worker 
DisconnectFromServer()427*d9f75844SAndroid Build Coastguard Worker void Conductor::DisconnectFromServer() {
428*d9f75844SAndroid Build Coastguard Worker   if (client_->is_connected())
429*d9f75844SAndroid Build Coastguard Worker     client_->SignOut();
430*d9f75844SAndroid Build Coastguard Worker }
431*d9f75844SAndroid Build Coastguard Worker 
ConnectToPeer(int peer_id)432*d9f75844SAndroid Build Coastguard Worker void Conductor::ConnectToPeer(int peer_id) {
433*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK(peer_id_ == -1);
434*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK(peer_id != -1);
435*d9f75844SAndroid Build Coastguard Worker 
436*d9f75844SAndroid Build Coastguard Worker   if (peer_connection_.get()) {
437*d9f75844SAndroid Build Coastguard Worker     main_wnd_->MessageBox(
438*d9f75844SAndroid Build Coastguard Worker         "Error", "We only support connecting to one peer at a time", true);
439*d9f75844SAndroid Build Coastguard Worker     return;
440*d9f75844SAndroid Build Coastguard Worker   }
441*d9f75844SAndroid Build Coastguard Worker 
442*d9f75844SAndroid Build Coastguard Worker   if (InitializePeerConnection()) {
443*d9f75844SAndroid Build Coastguard Worker     peer_id_ = peer_id;
444*d9f75844SAndroid Build Coastguard Worker     peer_connection_->CreateOffer(
445*d9f75844SAndroid Build Coastguard Worker         this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());
446*d9f75844SAndroid Build Coastguard Worker   } else {
447*d9f75844SAndroid Build Coastguard Worker     main_wnd_->MessageBox("Error", "Failed to initialize PeerConnection", true);
448*d9f75844SAndroid Build Coastguard Worker   }
449*d9f75844SAndroid Build Coastguard Worker }
450*d9f75844SAndroid Build Coastguard Worker 
AddTracks()451*d9f75844SAndroid Build Coastguard Worker void Conductor::AddTracks() {
452*d9f75844SAndroid Build Coastguard Worker   if (!peer_connection_->GetSenders().empty()) {
453*d9f75844SAndroid Build Coastguard Worker     return;  // Already added tracks.
454*d9f75844SAndroid Build Coastguard Worker   }
455*d9f75844SAndroid Build Coastguard Worker 
456*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
457*d9f75844SAndroid Build Coastguard Worker       peer_connection_factory_->CreateAudioTrack(
458*d9f75844SAndroid Build Coastguard Worker           kAudioLabel,
459*d9f75844SAndroid Build Coastguard Worker           peer_connection_factory_->CreateAudioSource(cricket::AudioOptions())
460*d9f75844SAndroid Build Coastguard Worker               .get()));
461*d9f75844SAndroid Build Coastguard Worker   auto result_or_error = peer_connection_->AddTrack(audio_track, {kStreamId});
462*d9f75844SAndroid Build Coastguard Worker   if (!result_or_error.ok()) {
463*d9f75844SAndroid Build Coastguard Worker     RTC_LOG(LS_ERROR) << "Failed to add audio track to PeerConnection: "
464*d9f75844SAndroid Build Coastguard Worker                       << result_or_error.error().message();
465*d9f75844SAndroid Build Coastguard Worker   }
466*d9f75844SAndroid Build Coastguard Worker 
467*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<CapturerTrackSource> video_device =
468*d9f75844SAndroid Build Coastguard Worker       CapturerTrackSource::Create();
469*d9f75844SAndroid Build Coastguard Worker   if (video_device) {
470*d9f75844SAndroid Build Coastguard Worker     rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track_(
471*d9f75844SAndroid Build Coastguard Worker         peer_connection_factory_->CreateVideoTrack(kVideoLabel,
472*d9f75844SAndroid Build Coastguard Worker                                                    video_device.get()));
473*d9f75844SAndroid Build Coastguard Worker     main_wnd_->StartLocalRenderer(video_track_.get());
474*d9f75844SAndroid Build Coastguard Worker 
475*d9f75844SAndroid Build Coastguard Worker     result_or_error = peer_connection_->AddTrack(video_track_, {kStreamId});
476*d9f75844SAndroid Build Coastguard Worker     if (!result_or_error.ok()) {
477*d9f75844SAndroid Build Coastguard Worker       RTC_LOG(LS_ERROR) << "Failed to add video track to PeerConnection: "
478*d9f75844SAndroid Build Coastguard Worker                         << result_or_error.error().message();
479*d9f75844SAndroid Build Coastguard Worker     }
480*d9f75844SAndroid Build Coastguard Worker   } else {
481*d9f75844SAndroid Build Coastguard Worker     RTC_LOG(LS_ERROR) << "OpenVideoCaptureDevice failed";
482*d9f75844SAndroid Build Coastguard Worker   }
483*d9f75844SAndroid Build Coastguard Worker 
484*d9f75844SAndroid Build Coastguard Worker   main_wnd_->SwitchToStreamingUI();
485*d9f75844SAndroid Build Coastguard Worker }
486*d9f75844SAndroid Build Coastguard Worker 
DisconnectFromCurrentPeer()487*d9f75844SAndroid Build Coastguard Worker void Conductor::DisconnectFromCurrentPeer() {
488*d9f75844SAndroid Build Coastguard Worker   RTC_LOG(LS_INFO) << __FUNCTION__;
489*d9f75844SAndroid Build Coastguard Worker   if (peer_connection_.get()) {
490*d9f75844SAndroid Build Coastguard Worker     client_->SendHangUp(peer_id_);
491*d9f75844SAndroid Build Coastguard Worker     DeletePeerConnection();
492*d9f75844SAndroid Build Coastguard Worker   }
493*d9f75844SAndroid Build Coastguard Worker 
494*d9f75844SAndroid Build Coastguard Worker   if (main_wnd_->IsWindow())
495*d9f75844SAndroid Build Coastguard Worker     main_wnd_->SwitchToPeerList(client_->peers());
496*d9f75844SAndroid Build Coastguard Worker }
497*d9f75844SAndroid Build Coastguard Worker 
UIThreadCallback(int msg_id,void * data)498*d9f75844SAndroid Build Coastguard Worker void Conductor::UIThreadCallback(int msg_id, void* data) {
499*d9f75844SAndroid Build Coastguard Worker   switch (msg_id) {
500*d9f75844SAndroid Build Coastguard Worker     case PEER_CONNECTION_CLOSED:
501*d9f75844SAndroid Build Coastguard Worker       RTC_LOG(LS_INFO) << "PEER_CONNECTION_CLOSED";
502*d9f75844SAndroid Build Coastguard Worker       DeletePeerConnection();
503*d9f75844SAndroid Build Coastguard Worker 
504*d9f75844SAndroid Build Coastguard Worker       if (main_wnd_->IsWindow()) {
505*d9f75844SAndroid Build Coastguard Worker         if (client_->is_connected()) {
506*d9f75844SAndroid Build Coastguard Worker           main_wnd_->SwitchToPeerList(client_->peers());
507*d9f75844SAndroid Build Coastguard Worker         } else {
508*d9f75844SAndroid Build Coastguard Worker           main_wnd_->SwitchToConnectUI();
509*d9f75844SAndroid Build Coastguard Worker         }
510*d9f75844SAndroid Build Coastguard Worker       } else {
511*d9f75844SAndroid Build Coastguard Worker         DisconnectFromServer();
512*d9f75844SAndroid Build Coastguard Worker       }
513*d9f75844SAndroid Build Coastguard Worker       break;
514*d9f75844SAndroid Build Coastguard Worker 
515*d9f75844SAndroid Build Coastguard Worker     case SEND_MESSAGE_TO_PEER: {
516*d9f75844SAndroid Build Coastguard Worker       RTC_LOG(LS_INFO) << "SEND_MESSAGE_TO_PEER";
517*d9f75844SAndroid Build Coastguard Worker       std::string* msg = reinterpret_cast<std::string*>(data);
518*d9f75844SAndroid Build Coastguard Worker       if (msg) {
519*d9f75844SAndroid Build Coastguard Worker         // For convenience, we always run the message through the queue.
520*d9f75844SAndroid Build Coastguard Worker         // This way we can be sure that messages are sent to the server
521*d9f75844SAndroid Build Coastguard Worker         // in the same order they were signaled without much hassle.
522*d9f75844SAndroid Build Coastguard Worker         pending_messages_.push_back(msg);
523*d9f75844SAndroid Build Coastguard Worker       }
524*d9f75844SAndroid Build Coastguard Worker 
525*d9f75844SAndroid Build Coastguard Worker       if (!pending_messages_.empty() && !client_->IsSendingMessage()) {
526*d9f75844SAndroid Build Coastguard Worker         msg = pending_messages_.front();
527*d9f75844SAndroid Build Coastguard Worker         pending_messages_.pop_front();
528*d9f75844SAndroid Build Coastguard Worker 
529*d9f75844SAndroid Build Coastguard Worker         if (!client_->SendToPeer(peer_id_, *msg) && peer_id_ != -1) {
530*d9f75844SAndroid Build Coastguard Worker           RTC_LOG(LS_ERROR) << "SendToPeer failed";
531*d9f75844SAndroid Build Coastguard Worker           DisconnectFromServer();
532*d9f75844SAndroid Build Coastguard Worker         }
533*d9f75844SAndroid Build Coastguard Worker         delete msg;
534*d9f75844SAndroid Build Coastguard Worker       }
535*d9f75844SAndroid Build Coastguard Worker 
536*d9f75844SAndroid Build Coastguard Worker       if (!peer_connection_.get())
537*d9f75844SAndroid Build Coastguard Worker         peer_id_ = -1;
538*d9f75844SAndroid Build Coastguard Worker 
539*d9f75844SAndroid Build Coastguard Worker       break;
540*d9f75844SAndroid Build Coastguard Worker     }
541*d9f75844SAndroid Build Coastguard Worker 
542*d9f75844SAndroid Build Coastguard Worker     case NEW_TRACK_ADDED: {
543*d9f75844SAndroid Build Coastguard Worker       auto* track = reinterpret_cast<webrtc::MediaStreamTrackInterface*>(data);
544*d9f75844SAndroid Build Coastguard Worker       if (track->kind() == webrtc::MediaStreamTrackInterface::kVideoKind) {
545*d9f75844SAndroid Build Coastguard Worker         auto* video_track = static_cast<webrtc::VideoTrackInterface*>(track);
546*d9f75844SAndroid Build Coastguard Worker         main_wnd_->StartRemoteRenderer(video_track);
547*d9f75844SAndroid Build Coastguard Worker       }
548*d9f75844SAndroid Build Coastguard Worker       track->Release();
549*d9f75844SAndroid Build Coastguard Worker       break;
550*d9f75844SAndroid Build Coastguard Worker     }
551*d9f75844SAndroid Build Coastguard Worker 
552*d9f75844SAndroid Build Coastguard Worker     case TRACK_REMOVED: {
553*d9f75844SAndroid Build Coastguard Worker       // Remote peer stopped sending a track.
554*d9f75844SAndroid Build Coastguard Worker       auto* track = reinterpret_cast<webrtc::MediaStreamTrackInterface*>(data);
555*d9f75844SAndroid Build Coastguard Worker       track->Release();
556*d9f75844SAndroid Build Coastguard Worker       break;
557*d9f75844SAndroid Build Coastguard Worker     }
558*d9f75844SAndroid Build Coastguard Worker 
559*d9f75844SAndroid Build Coastguard Worker     default:
560*d9f75844SAndroid Build Coastguard Worker       RTC_DCHECK_NOTREACHED();
561*d9f75844SAndroid Build Coastguard Worker       break;
562*d9f75844SAndroid Build Coastguard Worker   }
563*d9f75844SAndroid Build Coastguard Worker }
564*d9f75844SAndroid Build Coastguard Worker 
OnSuccess(webrtc::SessionDescriptionInterface * desc)565*d9f75844SAndroid Build Coastguard Worker void Conductor::OnSuccess(webrtc::SessionDescriptionInterface* desc) {
566*d9f75844SAndroid Build Coastguard Worker   peer_connection_->SetLocalDescription(
567*d9f75844SAndroid Build Coastguard Worker       DummySetSessionDescriptionObserver::Create().get(), desc);
568*d9f75844SAndroid Build Coastguard Worker 
569*d9f75844SAndroid Build Coastguard Worker   std::string sdp;
570*d9f75844SAndroid Build Coastguard Worker   desc->ToString(&sdp);
571*d9f75844SAndroid Build Coastguard Worker 
572*d9f75844SAndroid Build Coastguard Worker   // For loopback test. To save some connecting delay.
573*d9f75844SAndroid Build Coastguard Worker   if (loopback_) {
574*d9f75844SAndroid Build Coastguard Worker     // Replace message type from "offer" to "answer"
575*d9f75844SAndroid Build Coastguard Worker     std::unique_ptr<webrtc::SessionDescriptionInterface> session_description =
576*d9f75844SAndroid Build Coastguard Worker         webrtc::CreateSessionDescription(webrtc::SdpType::kAnswer, sdp);
577*d9f75844SAndroid Build Coastguard Worker     peer_connection_->SetRemoteDescription(
578*d9f75844SAndroid Build Coastguard Worker         DummySetSessionDescriptionObserver::Create().get(),
579*d9f75844SAndroid Build Coastguard Worker         session_description.release());
580*d9f75844SAndroid Build Coastguard Worker     return;
581*d9f75844SAndroid Build Coastguard Worker   }
582*d9f75844SAndroid Build Coastguard Worker 
583*d9f75844SAndroid Build Coastguard Worker   Json::Value jmessage;
584*d9f75844SAndroid Build Coastguard Worker   jmessage[kSessionDescriptionTypeName] =
585*d9f75844SAndroid Build Coastguard Worker       webrtc::SdpTypeToString(desc->GetType());
586*d9f75844SAndroid Build Coastguard Worker   jmessage[kSessionDescriptionSdpName] = sdp;
587*d9f75844SAndroid Build Coastguard Worker 
588*d9f75844SAndroid Build Coastguard Worker   Json::StreamWriterBuilder factory;
589*d9f75844SAndroid Build Coastguard Worker   SendMessage(Json::writeString(factory, jmessage));
590*d9f75844SAndroid Build Coastguard Worker }
591*d9f75844SAndroid Build Coastguard Worker 
OnFailure(webrtc::RTCError error)592*d9f75844SAndroid Build Coastguard Worker void Conductor::OnFailure(webrtc::RTCError error) {
593*d9f75844SAndroid Build Coastguard Worker   RTC_LOG(LS_ERROR) << ToString(error.type()) << ": " << error.message();
594*d9f75844SAndroid Build Coastguard Worker }
595*d9f75844SAndroid Build Coastguard Worker 
SendMessage(const std::string & json_object)596*d9f75844SAndroid Build Coastguard Worker void Conductor::SendMessage(const std::string& json_object) {
597*d9f75844SAndroid Build Coastguard Worker   std::string* msg = new std::string(json_object);
598*d9f75844SAndroid Build Coastguard Worker   main_wnd_->QueueUIThreadCallback(SEND_MESSAGE_TO_PEER, msg);
599*d9f75844SAndroid Build Coastguard Worker }
600