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