OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/protocol/webrtc_transport.h" | 5 #include "remoting/protocol/webrtc_transport.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 explicit SetSessionDescriptionObserver(const ResultCallback& result_callback) | 128 explicit SetSessionDescriptionObserver(const ResultCallback& result_callback) |
129 : result_callback_(result_callback) {} | 129 : result_callback_(result_callback) {} |
130 ~SetSessionDescriptionObserver() override {} | 130 ~SetSessionDescriptionObserver() override {} |
131 | 131 |
132 private: | 132 private: |
133 ResultCallback result_callback_; | 133 ResultCallback result_callback_; |
134 | 134 |
135 DISALLOW_COPY_AND_ASSIGN(SetSessionDescriptionObserver); | 135 DISALLOW_COPY_AND_ASSIGN(SetSessionDescriptionObserver); |
136 }; | 136 }; |
137 | 137 |
| 138 } // namespace |
138 | 139 |
139 } // namespace | 140 class WebrtcTransport::PeerConnectionWrapper |
| 141 : public webrtc::PeerConnectionObserver { |
| 142 public: |
| 143 PeerConnectionWrapper( |
| 144 rtc::Thread* worker_thread, |
| 145 std::unique_ptr<cricket::WebRtcVideoEncoderFactory> encoder_factory, |
| 146 std::unique_ptr<cricket::PortAllocator> port_allocator, |
| 147 base::WeakPtr<WebrtcTransport> transport) |
| 148 : transport_(transport) { |
| 149 peer_connection_factory_ = webrtc::CreatePeerConnectionFactory( |
| 150 worker_thread, rtc::Thread::Current(), &fake_audio_device_module_, |
| 151 encoder_factory.release(), nullptr); |
| 152 |
| 153 webrtc::FakeConstraints constraints; |
| 154 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, |
| 155 webrtc::MediaConstraintsInterface::kValueTrue); |
| 156 peer_connection_ = peer_connection_factory_->CreatePeerConnection( |
| 157 webrtc::PeerConnectionInterface::RTCConfiguration(), &constraints, |
| 158 std::move(port_allocator), nullptr, this); |
| 159 } |
| 160 virtual ~PeerConnectionWrapper() { peer_connection_->Close(); } |
| 161 |
| 162 webrtc::PeerConnectionInterface* peer_connection() { |
| 163 return peer_connection_.get(); |
| 164 } |
| 165 |
| 166 webrtc::PeerConnectionFactoryInterface* peer_connection_factory() { |
| 167 return peer_connection_factory_.get(); |
| 168 } |
| 169 |
| 170 // webrtc::PeerConnectionObserver interface. |
| 171 void OnSignalingChange( |
| 172 webrtc::PeerConnectionInterface::SignalingState new_state) override { |
| 173 if (transport_) |
| 174 transport_->OnSignalingChange(new_state); |
| 175 } |
| 176 void OnAddStream( |
| 177 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) override { |
| 178 if (transport_) |
| 179 transport_->OnAddStream(stream); |
| 180 } |
| 181 void OnRemoveStream( |
| 182 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) override { |
| 183 if (transport_) |
| 184 transport_->OnRemoveStream(stream); |
| 185 } |
| 186 void OnDataChannel( |
| 187 rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel) override { |
| 188 if (transport_) |
| 189 transport_->OnDataChannel(data_channel); |
| 190 } |
| 191 void OnRenegotiationNeeded() override { |
| 192 if (transport_) |
| 193 transport_->OnRenegotiationNeeded(); |
| 194 } |
| 195 void OnIceConnectionChange( |
| 196 webrtc::PeerConnectionInterface::IceConnectionState new_state) override { |
| 197 if (transport_) |
| 198 transport_->OnIceConnectionChange(new_state); |
| 199 } |
| 200 void OnIceGatheringChange( |
| 201 webrtc::PeerConnectionInterface::IceGatheringState new_state) override { |
| 202 if (transport_) |
| 203 transport_->OnIceGatheringChange(new_state); |
| 204 } |
| 205 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override { |
| 206 if (transport_) |
| 207 transport_->OnIceCandidate(candidate); |
| 208 } |
| 209 |
| 210 private: |
| 211 webrtc::FakeAudioDeviceModule fake_audio_device_module_; |
| 212 scoped_refptr<webrtc::PeerConnectionFactoryInterface> |
| 213 peer_connection_factory_; |
| 214 scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_; |
| 215 |
| 216 base::WeakPtr<WebrtcTransport> transport_; |
| 217 |
| 218 DISALLOW_COPY_AND_ASSIGN(PeerConnectionWrapper); |
| 219 }; |
140 | 220 |
141 WebrtcTransport::WebrtcTransport( | 221 WebrtcTransport::WebrtcTransport( |
142 rtc::Thread* worker_thread, | 222 rtc::Thread* worker_thread, |
143 scoped_refptr<TransportContext> transport_context, | 223 scoped_refptr<TransportContext> transport_context, |
144 EventHandler* event_handler) | 224 EventHandler* event_handler) |
145 : worker_thread_(worker_thread), | 225 : worker_thread_(worker_thread), |
146 transport_context_(transport_context), | 226 transport_context_(transport_context), |
147 event_handler_(event_handler), | 227 event_handler_(event_handler), |
148 handshake_hmac_(crypto::HMAC::SHA256), | 228 handshake_hmac_(crypto::HMAC::SHA256), |
149 weak_factory_(this) { | 229 weak_factory_(this) { |
150 transport_context_->set_relay_mode(TransportContext::RelayMode::TURN); | 230 transport_context_->set_relay_mode(TransportContext::RelayMode::TURN); |
151 } | 231 } |
152 | 232 |
153 WebrtcTransport::~WebrtcTransport() {} | 233 WebrtcTransport::~WebrtcTransport() { |
| 234 Close(OK); |
| 235 } |
| 236 |
| 237 webrtc::PeerConnectionInterface* WebrtcTransport::peer_connection() { |
| 238 return peer_connection_wrapper_ ? peer_connection_wrapper_->peer_connection() |
| 239 : nullptr; |
| 240 } |
| 241 |
| 242 webrtc::PeerConnectionFactoryInterface* |
| 243 WebrtcTransport::peer_connection_factory() { |
| 244 return peer_connection_wrapper_ |
| 245 ? peer_connection_wrapper_->peer_connection_factory() |
| 246 : nullptr; |
| 247 } |
154 | 248 |
155 std::unique_ptr<MessagePipe> WebrtcTransport::CreateOutgoingChannel( | 249 std::unique_ptr<MessagePipe> WebrtcTransport::CreateOutgoingChannel( |
156 const std::string& name) { | 250 const std::string& name) { |
157 webrtc::DataChannelInit config; | 251 webrtc::DataChannelInit config; |
158 config.reliable = true; | 252 config.reliable = true; |
159 return base::WrapUnique(new WebrtcDataStreamAdapter( | 253 return base::WrapUnique(new WebrtcDataStreamAdapter( |
160 peer_connection_->CreateDataChannel(name, &config))); | 254 peer_connection()->CreateDataChannel(name, &config))); |
161 } | 255 } |
162 | 256 |
163 void WebrtcTransport::Start( | 257 void WebrtcTransport::Start( |
164 Authenticator* authenticator, | 258 Authenticator* authenticator, |
165 SendTransportInfoCallback send_transport_info_callback) { | 259 SendTransportInfoCallback send_transport_info_callback) { |
166 DCHECK(thread_checker_.CalledOnValidThread()); | 260 DCHECK(thread_checker_.CalledOnValidThread()); |
167 DCHECK(send_transport_info_callback_.is_null()); | 261 DCHECK(send_transport_info_callback_.is_null()); |
168 | 262 |
169 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); | 263 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); |
170 | 264 |
171 // TODO(sergeyu): Investigate if it's possible to avoid Send(). | 265 // TODO(sergeyu): Investigate if it's possible to avoid Send(). |
172 jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); | 266 jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); |
173 | 267 |
174 send_transport_info_callback_ = std::move(send_transport_info_callback); | 268 send_transport_info_callback_ = std::move(send_transport_info_callback); |
175 | 269 |
176 if (!handshake_hmac_.Init(authenticator->GetAuthKey())) { | 270 if (!handshake_hmac_.Init(authenticator->GetAuthKey())) { |
177 LOG(FATAL) << "HMAC::Init() failed."; | 271 LOG(FATAL) << "HMAC::Init() failed."; |
178 } | 272 } |
179 | 273 |
180 fake_audio_device_module_.reset(new webrtc::FakeAudioDeviceModule()); | |
181 video_encoder_factory_ = new remoting::WebrtcVideoEncoderFactory(); | 274 video_encoder_factory_ = new remoting::WebrtcVideoEncoderFactory(); |
182 | |
183 // Takes ownership of video_encoder_factory_ | |
184 peer_connection_factory_ = webrtc::CreatePeerConnectionFactory( | |
185 worker_thread_, rtc::Thread::Current(), fake_audio_device_module_.get(), | |
186 video_encoder_factory_, nullptr); | |
187 | |
188 webrtc::PeerConnectionInterface::IceServer stun_server; | |
189 stun_server.urls.push_back("stun:stun.l.google.com:19302"); | |
190 webrtc::PeerConnectionInterface::RTCConfiguration rtc_config; | |
191 rtc_config.servers.push_back(stun_server); | |
192 | |
193 webrtc::FakeConstraints constraints; | |
194 constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, | |
195 webrtc::MediaConstraintsInterface::kValueTrue); | |
196 | |
197 std::unique_ptr<cricket::PortAllocator> port_allocator = | 275 std::unique_ptr<cricket::PortAllocator> port_allocator = |
198 transport_context_->port_allocator_factory()->CreatePortAllocator( | 276 transport_context_->port_allocator_factory()->CreatePortAllocator( |
199 transport_context_); | 277 transport_context_); |
200 peer_connection_ = peer_connection_factory_->CreatePeerConnection( | 278 |
201 rtc_config, &constraints, std::move(port_allocator), nullptr, this); | 279 // Takes ownership of video_encoder_factory_. |
| 280 peer_connection_wrapper_.reset(new PeerConnectionWrapper( |
| 281 worker_thread_, base::WrapUnique(video_encoder_factory_), |
| 282 std::move(port_allocator), weak_factory_.GetWeakPtr())); |
202 | 283 |
203 event_handler_->OnWebrtcTransportConnecting(); | 284 event_handler_->OnWebrtcTransportConnecting(); |
204 | 285 |
205 if (transport_context_->role() == TransportRole::SERVER) | 286 if (transport_context_->role() == TransportRole::SERVER) |
206 RequestNegotiation(); | 287 RequestNegotiation(); |
207 } | 288 } |
208 | 289 |
209 bool WebrtcTransport::ProcessTransportInfo(XmlElement* transport_info) { | 290 bool WebrtcTransport::ProcessTransportInfo(XmlElement* transport_info) { |
210 DCHECK(thread_checker_.CalledOnValidThread()); | 291 DCHECK(thread_checker_.CalledOnValidThread()); |
211 | 292 |
212 if (transport_info->Name() != QName(kTransportNamespace, "transport")) | 293 if (transport_info->Name() != QName(kTransportNamespace, "transport")) |
213 return false; | 294 return false; |
214 | 295 |
215 if (!peer_connection_) | 296 if (!peer_connection()) |
216 return false; | 297 return false; |
217 | 298 |
218 XmlElement* session_description = transport_info->FirstNamed( | 299 XmlElement* session_description = transport_info->FirstNamed( |
219 QName(kTransportNamespace, "session-description")); | 300 QName(kTransportNamespace, "session-description")); |
220 if (session_description) { | 301 if (session_description) { |
221 webrtc::PeerConnectionInterface::SignalingState expected_state = | 302 webrtc::PeerConnectionInterface::SignalingState expected_state = |
222 transport_context_->role() == TransportRole::CLIENT | 303 transport_context_->role() == TransportRole::CLIENT |
223 ? webrtc::PeerConnectionInterface::kStable | 304 ? webrtc::PeerConnectionInterface::kStable |
224 : webrtc::PeerConnectionInterface::kHaveLocalOffer; | 305 : webrtc::PeerConnectionInterface::kHaveLocalOffer; |
225 if (peer_connection_->signaling_state() != expected_state) { | 306 if (peer_connection()->signaling_state() != expected_state) { |
226 LOG(ERROR) << "Received unexpected WebRTC session_description."; | 307 LOG(ERROR) << "Received unexpected WebRTC session_description."; |
227 return false; | 308 return false; |
228 } | 309 } |
229 | 310 |
230 std::string type = session_description->Attr(QName(std::string(), "type")); | 311 std::string type = session_description->Attr(QName(std::string(), "type")); |
231 std::string sdp = | 312 std::string sdp = |
232 NormalizeSessionDescription(session_description->BodyText()); | 313 NormalizeSessionDescription(session_description->BodyText()); |
233 if (!IsValidSessionDescriptionType(type) || sdp.empty()) { | 314 if (!IsValidSessionDescriptionType(type) || sdp.empty()) { |
234 LOG(ERROR) << "Incorrect session description format."; | 315 LOG(ERROR) << "Incorrect session description format."; |
235 return false; | 316 return false; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 | 353 |
273 webrtc::SdpParseError error; | 354 webrtc::SdpParseError error; |
274 std::unique_ptr<webrtc::SessionDescriptionInterface> session_description( | 355 std::unique_ptr<webrtc::SessionDescriptionInterface> session_description( |
275 webrtc::CreateSessionDescription(type, sdp, &error)); | 356 webrtc::CreateSessionDescription(type, sdp, &error)); |
276 if (!session_description) { | 357 if (!session_description) { |
277 LOG(ERROR) << "Failed to parse the session description: " | 358 LOG(ERROR) << "Failed to parse the session description: " |
278 << error.description << " line: " << error.line; | 359 << error.description << " line: " << error.line; |
279 return false; | 360 return false; |
280 } | 361 } |
281 | 362 |
282 peer_connection_->SetRemoteDescription( | 363 peer_connection()->SetRemoteDescription( |
283 SetSessionDescriptionObserver::Create( | 364 SetSessionDescriptionObserver::Create( |
284 base::Bind(&WebrtcTransport::OnRemoteDescriptionSet, | 365 base::Bind(&WebrtcTransport::OnRemoteDescriptionSet, |
285 weak_factory_.GetWeakPtr(), | 366 weak_factory_.GetWeakPtr(), |
286 type == webrtc::SessionDescriptionInterface::kOffer)), | 367 type == webrtc::SessionDescriptionInterface::kOffer)), |
287 session_description.release()); | 368 session_description.release()); |
288 } | 369 } |
289 | 370 |
290 XmlElement* candidate_element; | 371 XmlElement* candidate_element; |
291 QName candidate_qname(kTransportNamespace, "candidate"); | 372 QName candidate_qname(kTransportNamespace, "candidate"); |
292 for (candidate_element = transport_info->FirstNamed(candidate_qname); | 373 for (candidate_element = transport_info->FirstNamed(candidate_qname); |
(...skipping 14 matching lines...) Expand all Loading... |
307 webrtc::SdpParseError error; | 388 webrtc::SdpParseError error; |
308 std::unique_ptr<webrtc::IceCandidateInterface> candidate( | 389 std::unique_ptr<webrtc::IceCandidateInterface> candidate( |
309 webrtc::CreateIceCandidate(sdp_mid, sdp_mlineindex, candidate_str, | 390 webrtc::CreateIceCandidate(sdp_mid, sdp_mlineindex, candidate_str, |
310 &error)); | 391 &error)); |
311 if (!candidate) { | 392 if (!candidate) { |
312 LOG(ERROR) << "Failed to parse incoming candidate: " << error.description | 393 LOG(ERROR) << "Failed to parse incoming candidate: " << error.description |
313 << " line: " << error.line; | 394 << " line: " << error.line; |
314 return false; | 395 return false; |
315 } | 396 } |
316 | 397 |
317 if (peer_connection_->signaling_state() == | 398 if (peer_connection()->signaling_state() == |
318 webrtc::PeerConnectionInterface::kStable) { | 399 webrtc::PeerConnectionInterface::kStable) { |
319 if (!peer_connection_->AddIceCandidate(candidate.get())) { | 400 if (!peer_connection()->AddIceCandidate(candidate.get())) { |
320 LOG(ERROR) << "Failed to add incoming ICE candidate."; | 401 LOG(ERROR) << "Failed to add incoming ICE candidate."; |
321 return false; | 402 return false; |
322 } | 403 } |
323 } else { | 404 } else { |
324 pending_incoming_candidates_.push_back(std::move(candidate)); | 405 pending_incoming_candidates_.push_back(std::move(candidate)); |
325 } | 406 } |
326 } | 407 } |
327 | 408 |
328 return true; | 409 return true; |
329 } | 410 } |
330 | 411 |
331 void WebrtcTransport::OnLocalSessionDescriptionCreated( | 412 void WebrtcTransport::OnLocalSessionDescriptionCreated( |
332 std::unique_ptr<webrtc::SessionDescriptionInterface> description, | 413 std::unique_ptr<webrtc::SessionDescriptionInterface> description, |
333 const std::string& error) { | 414 const std::string& error) { |
334 DCHECK(thread_checker_.CalledOnValidThread()); | 415 DCHECK(thread_checker_.CalledOnValidThread()); |
335 | 416 |
336 if (!peer_connection_) | 417 if (!peer_connection()) |
337 return; | 418 return; |
338 | 419 |
339 if (!description) { | 420 if (!description) { |
340 LOG(ERROR) << "PeerConnection offer creation failed: " << error; | 421 LOG(ERROR) << "PeerConnection offer creation failed: " << error; |
341 Close(CHANNEL_CONNECTION_ERROR); | 422 Close(CHANNEL_CONNECTION_ERROR); |
342 return; | 423 return; |
343 } | 424 } |
344 | 425 |
345 std::string description_sdp; | 426 std::string description_sdp; |
346 if (!description->ToString(&description_sdp)) { | 427 if (!description->ToString(&description_sdp)) { |
(...skipping 16 matching lines...) Expand all Loading... |
363 digest.resize(handshake_hmac_.DigestLength()); | 444 digest.resize(handshake_hmac_.DigestLength()); |
364 CHECK(handshake_hmac_.Sign(description->type() + " " + description_sdp, | 445 CHECK(handshake_hmac_.Sign(description->type() + " " + description_sdp, |
365 reinterpret_cast<uint8_t*>(&(digest[0])), | 446 reinterpret_cast<uint8_t*>(&(digest[0])), |
366 digest.size())); | 447 digest.size())); |
367 std::string digest_base64; | 448 std::string digest_base64; |
368 base::Base64Encode(digest, &digest_base64); | 449 base::Base64Encode(digest, &digest_base64); |
369 offer_tag->SetAttr(QName(std::string(), "signature"), digest_base64); | 450 offer_tag->SetAttr(QName(std::string(), "signature"), digest_base64); |
370 | 451 |
371 send_transport_info_callback_.Run(std::move(transport_info)); | 452 send_transport_info_callback_.Run(std::move(transport_info)); |
372 | 453 |
373 peer_connection_->SetLocalDescription( | 454 peer_connection()->SetLocalDescription( |
374 SetSessionDescriptionObserver::Create(base::Bind( | 455 SetSessionDescriptionObserver::Create(base::Bind( |
375 &WebrtcTransport::OnLocalDescriptionSet, weak_factory_.GetWeakPtr())), | 456 &WebrtcTransport::OnLocalDescriptionSet, weak_factory_.GetWeakPtr())), |
376 description.release()); | 457 description.release()); |
377 } | 458 } |
378 | 459 |
379 void WebrtcTransport::OnLocalDescriptionSet(bool success, | 460 void WebrtcTransport::OnLocalDescriptionSet(bool success, |
380 const std::string& error) { | 461 const std::string& error) { |
381 DCHECK(thread_checker_.CalledOnValidThread()); | 462 DCHECK(thread_checker_.CalledOnValidThread()); |
382 | 463 |
383 if (!peer_connection_) | 464 if (!peer_connection()) |
384 return; | 465 return; |
385 | 466 |
386 if (!success) { | 467 if (!success) { |
387 LOG(ERROR) << "Failed to set local description: " << error; | 468 LOG(ERROR) << "Failed to set local description: " << error; |
388 Close(CHANNEL_CONNECTION_ERROR); | 469 Close(CHANNEL_CONNECTION_ERROR); |
389 return; | 470 return; |
390 } | 471 } |
391 | 472 |
392 AddPendingCandidatesIfPossible(); | 473 AddPendingCandidatesIfPossible(); |
393 } | 474 } |
394 | 475 |
395 void WebrtcTransport::OnRemoteDescriptionSet(bool send_answer, | 476 void WebrtcTransport::OnRemoteDescriptionSet(bool send_answer, |
396 bool success, | 477 bool success, |
397 const std::string& error) { | 478 const std::string& error) { |
398 DCHECK(thread_checker_.CalledOnValidThread()); | 479 DCHECK(thread_checker_.CalledOnValidThread()); |
399 | 480 |
400 if (!peer_connection_) | 481 if (!peer_connection()) |
401 return; | 482 return; |
402 | 483 |
403 if (!success) { | 484 if (!success) { |
404 LOG(ERROR) << "Failed to set local description: " << error; | 485 LOG(ERROR) << "Failed to set local description: " << error; |
405 Close(CHANNEL_CONNECTION_ERROR); | 486 Close(CHANNEL_CONNECTION_ERROR); |
406 return; | 487 return; |
407 } | 488 } |
408 | 489 |
409 // Create and send answer on the server. | 490 // Create and send answer on the server. |
410 if (send_answer) { | 491 if (send_answer) { |
411 peer_connection_->CreateAnswer( | 492 peer_connection()->CreateAnswer( |
412 CreateSessionDescriptionObserver::Create( | 493 CreateSessionDescriptionObserver::Create( |
413 base::Bind(&WebrtcTransport::OnLocalSessionDescriptionCreated, | 494 base::Bind(&WebrtcTransport::OnLocalSessionDescriptionCreated, |
414 weak_factory_.GetWeakPtr())), | 495 weak_factory_.GetWeakPtr())), |
415 nullptr); | 496 nullptr); |
416 } | 497 } |
417 | 498 |
418 AddPendingCandidatesIfPossible(); | 499 AddPendingCandidatesIfPossible(); |
419 } | 500 } |
420 | 501 |
421 void WebrtcTransport::OnSignalingChange( | 502 void WebrtcTransport::OnSignalingChange( |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 | 612 |
532 webrtc::FakeConstraints offer_config; | 613 webrtc::FakeConstraints offer_config; |
533 offer_config.AddMandatory( | 614 offer_config.AddMandatory( |
534 webrtc::MediaConstraintsInterface::kOfferToReceiveVideo, | 615 webrtc::MediaConstraintsInterface::kOfferToReceiveVideo, |
535 webrtc::MediaConstraintsInterface::kValueTrue); | 616 webrtc::MediaConstraintsInterface::kValueTrue); |
536 offer_config.AddMandatory( | 617 offer_config.AddMandatory( |
537 webrtc::MediaConstraintsInterface::kOfferToReceiveAudio, | 618 webrtc::MediaConstraintsInterface::kOfferToReceiveAudio, |
538 webrtc::MediaConstraintsInterface::kValueFalse); | 619 webrtc::MediaConstraintsInterface::kValueFalse); |
539 offer_config.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, | 620 offer_config.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, |
540 webrtc::MediaConstraintsInterface::kValueTrue); | 621 webrtc::MediaConstraintsInterface::kValueTrue); |
541 peer_connection_->CreateOffer( | 622 peer_connection()->CreateOffer( |
542 CreateSessionDescriptionObserver::Create( | 623 CreateSessionDescriptionObserver::Create( |
543 base::Bind(&WebrtcTransport::OnLocalSessionDescriptionCreated, | 624 base::Bind(&WebrtcTransport::OnLocalSessionDescriptionCreated, |
544 weak_factory_.GetWeakPtr())), | 625 weak_factory_.GetWeakPtr())), |
545 &offer_config); | 626 &offer_config); |
546 } | 627 } |
547 | 628 |
548 void WebrtcTransport::SendTransportInfo() { | 629 void WebrtcTransport::SendTransportInfo() { |
549 DCHECK(thread_checker_.CalledOnValidThread()); | 630 DCHECK(thread_checker_.CalledOnValidThread()); |
550 DCHECK(pending_transport_info_message_); | 631 DCHECK(pending_transport_info_message_); |
551 | 632 |
552 send_transport_info_callback_.Run(std::move(pending_transport_info_message_)); | 633 send_transport_info_callback_.Run(std::move(pending_transport_info_message_)); |
553 } | 634 } |
554 | 635 |
555 void WebrtcTransport::AddPendingCandidatesIfPossible() { | 636 void WebrtcTransport::AddPendingCandidatesIfPossible() { |
556 DCHECK(thread_checker_.CalledOnValidThread()); | 637 DCHECK(thread_checker_.CalledOnValidThread()); |
557 | 638 |
558 if (peer_connection_->signaling_state() == | 639 if (peer_connection()->signaling_state() == |
559 webrtc::PeerConnectionInterface::kStable) { | 640 webrtc::PeerConnectionInterface::kStable) { |
560 for (auto* candidate : pending_incoming_candidates_) { | 641 for (auto* candidate : pending_incoming_candidates_) { |
561 if (!peer_connection_->AddIceCandidate(candidate)) { | 642 if (!peer_connection()->AddIceCandidate(candidate)) { |
562 LOG(ERROR) << "Failed to add incoming candidate"; | 643 LOG(ERROR) << "Failed to add incoming candidate"; |
563 Close(INCOMPATIBLE_PROTOCOL); | 644 Close(INCOMPATIBLE_PROTOCOL); |
564 return; | 645 return; |
565 } | 646 } |
566 } | 647 } |
567 pending_incoming_candidates_.clear(); | 648 pending_incoming_candidates_.clear(); |
568 } | 649 } |
569 } | 650 } |
570 | 651 |
571 void WebrtcTransport::Close(ErrorCode error) { | 652 void WebrtcTransport::Close(ErrorCode error) { |
572 DCHECK(thread_checker_.CalledOnValidThread()); | 653 DCHECK(thread_checker_.CalledOnValidThread()); |
573 if (!peer_connection_) | 654 if (!peer_connection_wrapper_) |
574 return; | 655 return; |
575 | 656 |
576 weak_factory_.InvalidateWeakPtrs(); | 657 weak_factory_.InvalidateWeakPtrs(); |
577 | 658 |
578 peer_connection_->Close(); | 659 // Close and delete PeerConnection asynchronously. PeerConnection may be on |
579 peer_connection_ = nullptr; | 660 // the stack and so it must be destroyed later. |
580 peer_connection_factory_ = nullptr; | 661 base::ThreadTaskRunnerHandle::Get()->DeleteSoon( |
| 662 FROM_HERE, peer_connection_wrapper_.release()); |
581 | 663 |
582 if (error != OK) | 664 if (error != OK) |
583 event_handler_->OnWebrtcTransportError(error); | 665 event_handler_->OnWebrtcTransportError(error); |
584 } | 666 } |
585 | 667 |
586 } // namespace protocol | 668 } // namespace protocol |
587 } // namespace remoting | 669 } // namespace remoting |
OLD | NEW |