| Index: remoting/protocol/webrtc_transport.cc
|
| diff --git a/remoting/protocol/webrtc_transport.cc b/remoting/protocol/webrtc_transport.cc
|
| index a3943f8d5d91c1dac48d7587d988b424e718f9fd..c813e6e91135265fed737091e7211470beff5266 100644
|
| --- a/remoting/protocol/webrtc_transport.cc
|
| +++ b/remoting/protocol/webrtc_transport.cc
|
| @@ -135,9 +135,89 @@ class SetSessionDescriptionObserver
|
| DISALLOW_COPY_AND_ASSIGN(SetSessionDescriptionObserver);
|
| };
|
|
|
| -
|
| } // namespace
|
|
|
| +class WebrtcTransport::PeerConnectionWrapper
|
| + : public webrtc::PeerConnectionObserver {
|
| + public:
|
| + PeerConnectionWrapper(
|
| + rtc::Thread* worker_thread,
|
| + std::unique_ptr<cricket::WebRtcVideoEncoderFactory> encoder_factory,
|
| + std::unique_ptr<cricket::PortAllocator> port_allocator,
|
| + base::WeakPtr<WebrtcTransport> transport)
|
| + : transport_(transport) {
|
| + peer_connection_factory_ = webrtc::CreatePeerConnectionFactory(
|
| + worker_thread, rtc::Thread::Current(), &fake_audio_device_module_,
|
| + encoder_factory.release(), nullptr);
|
| +
|
| + webrtc::FakeConstraints constraints;
|
| + constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
|
| + webrtc::MediaConstraintsInterface::kValueTrue);
|
| + peer_connection_ = peer_connection_factory_->CreatePeerConnection(
|
| + webrtc::PeerConnectionInterface::RTCConfiguration(), &constraints,
|
| + std::move(port_allocator), nullptr, this);
|
| + }
|
| + virtual ~PeerConnectionWrapper() { peer_connection_->Close(); }
|
| +
|
| + webrtc::PeerConnectionInterface* peer_connection() {
|
| + return peer_connection_.get();
|
| + }
|
| +
|
| + webrtc::PeerConnectionFactoryInterface* peer_connection_factory() {
|
| + return peer_connection_factory_.get();
|
| + }
|
| +
|
| + // webrtc::PeerConnectionObserver interface.
|
| + void OnSignalingChange(
|
| + webrtc::PeerConnectionInterface::SignalingState new_state) override {
|
| + if (transport_)
|
| + transport_->OnSignalingChange(new_state);
|
| + }
|
| + void OnAddStream(
|
| + rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) override {
|
| + if (transport_)
|
| + transport_->OnAddStream(stream);
|
| + }
|
| + void OnRemoveStream(
|
| + rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) override {
|
| + if (transport_)
|
| + transport_->OnRemoveStream(stream);
|
| + }
|
| + void OnDataChannel(
|
| + rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel) override {
|
| + if (transport_)
|
| + transport_->OnDataChannel(data_channel);
|
| + }
|
| + void OnRenegotiationNeeded() override {
|
| + if (transport_)
|
| + transport_->OnRenegotiationNeeded();
|
| + }
|
| + void OnIceConnectionChange(
|
| + webrtc::PeerConnectionInterface::IceConnectionState new_state) override {
|
| + if (transport_)
|
| + transport_->OnIceConnectionChange(new_state);
|
| + }
|
| + void OnIceGatheringChange(
|
| + webrtc::PeerConnectionInterface::IceGatheringState new_state) override {
|
| + if (transport_)
|
| + transport_->OnIceGatheringChange(new_state);
|
| + }
|
| + void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
|
| + if (transport_)
|
| + transport_->OnIceCandidate(candidate);
|
| + }
|
| +
|
| + private:
|
| + webrtc::FakeAudioDeviceModule fake_audio_device_module_;
|
| + scoped_refptr<webrtc::PeerConnectionFactoryInterface>
|
| + peer_connection_factory_;
|
| + scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
|
| +
|
| + base::WeakPtr<WebrtcTransport> transport_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(PeerConnectionWrapper);
|
| +};
|
| +
|
| WebrtcTransport::WebrtcTransport(
|
| rtc::Thread* worker_thread,
|
| scoped_refptr<TransportContext> transport_context,
|
| @@ -150,14 +230,28 @@ WebrtcTransport::WebrtcTransport(
|
| transport_context_->set_relay_mode(TransportContext::RelayMode::TURN);
|
| }
|
|
|
| -WebrtcTransport::~WebrtcTransport() {}
|
| +WebrtcTransport::~WebrtcTransport() {
|
| + Close(OK);
|
| +}
|
| +
|
| +webrtc::PeerConnectionInterface* WebrtcTransport::peer_connection() {
|
| + return peer_connection_wrapper_ ? peer_connection_wrapper_->peer_connection()
|
| + : nullptr;
|
| +}
|
| +
|
| +webrtc::PeerConnectionFactoryInterface*
|
| +WebrtcTransport::peer_connection_factory() {
|
| + return peer_connection_wrapper_
|
| + ? peer_connection_wrapper_->peer_connection_factory()
|
| + : nullptr;
|
| +}
|
|
|
| std::unique_ptr<MessagePipe> WebrtcTransport::CreateOutgoingChannel(
|
| const std::string& name) {
|
| webrtc::DataChannelInit config;
|
| config.reliable = true;
|
| return base::WrapUnique(new WebrtcDataStreamAdapter(
|
| - peer_connection_->CreateDataChannel(name, &config)));
|
| + peer_connection()->CreateDataChannel(name, &config)));
|
| }
|
|
|
| void WebrtcTransport::Start(
|
| @@ -177,28 +271,15 @@ void WebrtcTransport::Start(
|
| LOG(FATAL) << "HMAC::Init() failed.";
|
| }
|
|
|
| - fake_audio_device_module_.reset(new webrtc::FakeAudioDeviceModule());
|
| video_encoder_factory_ = new remoting::WebrtcVideoEncoderFactory();
|
| -
|
| - // Takes ownership of video_encoder_factory_
|
| - peer_connection_factory_ = webrtc::CreatePeerConnectionFactory(
|
| - worker_thread_, rtc::Thread::Current(), fake_audio_device_module_.get(),
|
| - video_encoder_factory_, nullptr);
|
| -
|
| - webrtc::PeerConnectionInterface::IceServer stun_server;
|
| - stun_server.urls.push_back("stun:stun.l.google.com:19302");
|
| - webrtc::PeerConnectionInterface::RTCConfiguration rtc_config;
|
| - rtc_config.servers.push_back(stun_server);
|
| -
|
| - webrtc::FakeConstraints constraints;
|
| - constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
|
| - webrtc::MediaConstraintsInterface::kValueTrue);
|
| -
|
| std::unique_ptr<cricket::PortAllocator> port_allocator =
|
| transport_context_->port_allocator_factory()->CreatePortAllocator(
|
| transport_context_);
|
| - peer_connection_ = peer_connection_factory_->CreatePeerConnection(
|
| - rtc_config, &constraints, std::move(port_allocator), nullptr, this);
|
| +
|
| + // Takes ownership of video_encoder_factory_.
|
| + peer_connection_wrapper_.reset(new PeerConnectionWrapper(
|
| + worker_thread_, base::WrapUnique(video_encoder_factory_),
|
| + std::move(port_allocator), weak_factory_.GetWeakPtr()));
|
|
|
| event_handler_->OnWebrtcTransportConnecting();
|
|
|
| @@ -212,7 +293,7 @@ bool WebrtcTransport::ProcessTransportInfo(XmlElement* transport_info) {
|
| if (transport_info->Name() != QName(kTransportNamespace, "transport"))
|
| return false;
|
|
|
| - if (!peer_connection_)
|
| + if (!peer_connection())
|
| return false;
|
|
|
| XmlElement* session_description = transport_info->FirstNamed(
|
| @@ -222,7 +303,7 @@ bool WebrtcTransport::ProcessTransportInfo(XmlElement* transport_info) {
|
| transport_context_->role() == TransportRole::CLIENT
|
| ? webrtc::PeerConnectionInterface::kStable
|
| : webrtc::PeerConnectionInterface::kHaveLocalOffer;
|
| - if (peer_connection_->signaling_state() != expected_state) {
|
| + if (peer_connection()->signaling_state() != expected_state) {
|
| LOG(ERROR) << "Received unexpected WebRTC session_description.";
|
| return false;
|
| }
|
| @@ -279,7 +360,7 @@ bool WebrtcTransport::ProcessTransportInfo(XmlElement* transport_info) {
|
| return false;
|
| }
|
|
|
| - peer_connection_->SetRemoteDescription(
|
| + peer_connection()->SetRemoteDescription(
|
| SetSessionDescriptionObserver::Create(
|
| base::Bind(&WebrtcTransport::OnRemoteDescriptionSet,
|
| weak_factory_.GetWeakPtr(),
|
| @@ -314,9 +395,9 @@ bool WebrtcTransport::ProcessTransportInfo(XmlElement* transport_info) {
|
| return false;
|
| }
|
|
|
| - if (peer_connection_->signaling_state() ==
|
| + if (peer_connection()->signaling_state() ==
|
| webrtc::PeerConnectionInterface::kStable) {
|
| - if (!peer_connection_->AddIceCandidate(candidate.get())) {
|
| + if (!peer_connection()->AddIceCandidate(candidate.get())) {
|
| LOG(ERROR) << "Failed to add incoming ICE candidate.";
|
| return false;
|
| }
|
| @@ -333,7 +414,7 @@ void WebrtcTransport::OnLocalSessionDescriptionCreated(
|
| const std::string& error) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
| - if (!peer_connection_)
|
| + if (!peer_connection())
|
| return;
|
|
|
| if (!description) {
|
| @@ -370,7 +451,7 @@ void WebrtcTransport::OnLocalSessionDescriptionCreated(
|
|
|
| send_transport_info_callback_.Run(std::move(transport_info));
|
|
|
| - peer_connection_->SetLocalDescription(
|
| + peer_connection()->SetLocalDescription(
|
| SetSessionDescriptionObserver::Create(base::Bind(
|
| &WebrtcTransport::OnLocalDescriptionSet, weak_factory_.GetWeakPtr())),
|
| description.release());
|
| @@ -380,7 +461,7 @@ void WebrtcTransport::OnLocalDescriptionSet(bool success,
|
| const std::string& error) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
| - if (!peer_connection_)
|
| + if (!peer_connection())
|
| return;
|
|
|
| if (!success) {
|
| @@ -397,7 +478,7 @@ void WebrtcTransport::OnRemoteDescriptionSet(bool send_answer,
|
| const std::string& error) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
| - if (!peer_connection_)
|
| + if (!peer_connection())
|
| return;
|
|
|
| if (!success) {
|
| @@ -408,7 +489,7 @@ void WebrtcTransport::OnRemoteDescriptionSet(bool send_answer,
|
|
|
| // Create and send answer on the server.
|
| if (send_answer) {
|
| - peer_connection_->CreateAnswer(
|
| + peer_connection()->CreateAnswer(
|
| CreateSessionDescriptionObserver::Create(
|
| base::Bind(&WebrtcTransport::OnLocalSessionDescriptionCreated,
|
| weak_factory_.GetWeakPtr())),
|
| @@ -538,7 +619,7 @@ void WebrtcTransport::SendOffer() {
|
| webrtc::MediaConstraintsInterface::kValueFalse);
|
| offer_config.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
|
| webrtc::MediaConstraintsInterface::kValueTrue);
|
| - peer_connection_->CreateOffer(
|
| + peer_connection()->CreateOffer(
|
| CreateSessionDescriptionObserver::Create(
|
| base::Bind(&WebrtcTransport::OnLocalSessionDescriptionCreated,
|
| weak_factory_.GetWeakPtr())),
|
| @@ -555,10 +636,10 @@ void WebrtcTransport::SendTransportInfo() {
|
| void WebrtcTransport::AddPendingCandidatesIfPossible() {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
| - if (peer_connection_->signaling_state() ==
|
| + if (peer_connection()->signaling_state() ==
|
| webrtc::PeerConnectionInterface::kStable) {
|
| for (auto* candidate : pending_incoming_candidates_) {
|
| - if (!peer_connection_->AddIceCandidate(candidate)) {
|
| + if (!peer_connection()->AddIceCandidate(candidate)) {
|
| LOG(ERROR) << "Failed to add incoming candidate";
|
| Close(INCOMPATIBLE_PROTOCOL);
|
| return;
|
| @@ -570,14 +651,15 @@ void WebrtcTransport::AddPendingCandidatesIfPossible() {
|
|
|
| void WebrtcTransport::Close(ErrorCode error) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| - if (!peer_connection_)
|
| + if (!peer_connection_wrapper_)
|
| return;
|
|
|
| weak_factory_.InvalidateWeakPtrs();
|
|
|
| - peer_connection_->Close();
|
| - peer_connection_ = nullptr;
|
| - peer_connection_factory_ = nullptr;
|
| + // Close and delete PeerConnection asynchronously. PeerConnection may be on
|
| + // the stack and so it must be destroyed later.
|
| + base::ThreadTaskRunnerHandle::Get()->DeleteSoon(
|
| + FROM_HERE, peer_connection_wrapper_.release());
|
|
|
| if (error != OK)
|
| event_handler_->OnWebrtcTransportError(error);
|
|
|