Chromium Code Reviews| Index: remoting/protocol/webrtc_transport.cc |
| diff --git a/remoting/protocol/webrtc_transport.cc b/remoting/protocol/webrtc_transport.cc |
| index 3a6ad6ffa8bc15acac88eabc886310099870f38c..6dcbb972cfa16a9322846612c283e421f583708c 100644 |
| --- a/remoting/protocol/webrtc_transport.cc |
| +++ b/remoting/protocol/webrtc_transport.cc |
| @@ -8,6 +8,7 @@ |
| #include "base/single_thread_task_runner.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/task_runner_util.h" |
| +#include "base/thread_task_runner_handle.h" |
| #include "jingle/glue/thread_wrapper.h" |
| #include "third_party/libjingle/source/talk/app/webrtc/test/fakeconstraints.h" |
| #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" |
| @@ -29,15 +30,6 @@ const int kTransportInfoSendDelayMs = 20; |
| // XML namespace for the transport elements. |
| const char kTransportNamespace[] = "google:remoting:webrtc"; |
| -rtc::Thread* InitAndGetRtcThread() { |
| - jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); |
| - |
| - // TODO(sergeyu): Investigate if it's possible to avoid Send(). |
| - jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); |
| - |
| - return jingle_glue::JingleThreadWrapper::current(); |
| -} |
| - |
| // A webrtc::CreateSessionDescriptionObserver implementation used to receive the |
| // results of creating descriptions for this end of the PeerConnection. |
| class CreateSessionDescriptionObserver |
| @@ -108,13 +100,13 @@ class SetSessionDescriptionObserver |
| } // namespace |
| WebrtcTransport::WebrtcTransport( |
| + rtc::Thread* worker_thread, |
| rtc::scoped_refptr<webrtc::PortAllocatorFactoryInterface> |
| port_allocator_factory, |
| - TransportRole role, |
| - scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner) |
| + TransportRole role) |
| : port_allocator_factory_(port_allocator_factory), |
| role_(role), |
| - worker_task_runner_(worker_task_runner), |
| + worker_thread_(worker_thread), |
| weak_factory_(this) {} |
| WebrtcTransport::~WebrtcTransport() {} |
| @@ -126,10 +118,34 @@ void WebrtcTransport::Start(EventHandler* event_handler, |
| event_handler_ = event_handler; |
| // TODO(sergeyu): Use the |authenticator| to authenticate PeerConnection. |
| + jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); |
| + |
| + // TODO(sergeyu): Investigate if it's possible to avoid Send(). |
| + jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); |
| + |
| + fake_audio_device_module_.reset(new webrtc::FakeAudioDeviceModule()); |
| + |
| + peer_connection_factory_ = webrtc::CreatePeerConnectionFactory( |
| + worker_thread_, rtc::Thread::Current(), |
| + fake_audio_device_module_.get(), nullptr, 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; |
|
Jamie
2015/12/09 19:42:22
Unrelated to this CL, but why are we using FakeCon
Sergey Ulanov
2015/12/09 19:57:06
PeerConnection gets MediaConstraintsInterface. Fak
|
| + constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, |
| + webrtc::MediaConstraintsInterface::kValueTrue); |
| + |
| + peer_connection_ = peer_connection_factory_->CreatePeerConnection( |
| + rtc_config, &constraints, port_allocator_factory_, nullptr, this); |
| + |
| + data_stream_adapter_.Initialize(peer_connection_, |
| + role_ == TransportRole::SERVER); |
| - base::PostTaskAndReplyWithResult( |
| - worker_task_runner_.get(), FROM_HERE, base::Bind(&InitAndGetRtcThread), |
| - base::Bind(&WebrtcTransport::DoStart, weak_factory_.GetWeakPtr())); |
| + if (role_ == TransportRole::SERVER) |
| + RequestNegotiation(); |
| } |
| bool WebrtcTransport::ProcessTransportInfo(XmlElement* transport_info) { |
| @@ -145,7 +161,7 @@ bool WebrtcTransport::ProcessTransportInfo(XmlElement* transport_info) { |
| QName(kTransportNamespace, "session-description")); |
| if (session_description) { |
| webrtc::PeerConnectionInterface::SignalingState expected_state = |
| - role_ == TransportRole::SERVER |
| + role_ == TransportRole::CLIENT |
| ? webrtc::PeerConnectionInterface::kStable |
| : webrtc::PeerConnectionInterface::kHaveLocalOffer; |
| if (peer_connection_->signaling_state() != expected_state) { |
| @@ -156,7 +172,7 @@ bool WebrtcTransport::ProcessTransportInfo(XmlElement* transport_info) { |
| std::string type = session_description->Attr(QName(std::string(), "type")); |
| std::string sdp = session_description->BodyText(); |
| if (type.empty() || sdp.empty()) { |
| - LOG(ERROR) << "Incorrect session_description format."; |
| + LOG(ERROR) << "Incorrect session description format."; |
| return false; |
| } |
| @@ -164,15 +180,16 @@ bool WebrtcTransport::ProcessTransportInfo(XmlElement* transport_info) { |
| scoped_ptr<webrtc::SessionDescriptionInterface> session_description( |
| webrtc::CreateSessionDescription(type, sdp, &error)); |
| if (!session_description) { |
| - LOG(ERROR) << "Failed to parse the offer: " << error.description |
| - << " line: " << error.line; |
| + LOG(ERROR) << "Failed to parse the session description: " |
| + << error.description << " line: " << error.line; |
| return false; |
| } |
| peer_connection_->SetRemoteDescription( |
| SetSessionDescriptionObserver::Create( |
| base::Bind(&WebrtcTransport::OnRemoteDescriptionSet, |
| - weak_factory_.GetWeakPtr())), |
| + weak_factory_.GetWeakPtr(), |
| + type == webrtc::SessionDescriptionInterface::kOffer)), |
| session_description.release()); |
| } |
| @@ -227,54 +244,6 @@ StreamChannelFactory* WebrtcTransport::GetMultiplexedChannelFactory() { |
| return GetStreamChannelFactory(); |
| } |
| -void WebrtcTransport::DoStart(rtc::Thread* worker_thread) { |
| - DCHECK(thread_checker_.CalledOnValidThread()); |
| - |
| - jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); |
| - |
| - // TODO(sergeyu): Investigate if it's possible to avoid Send(). |
| - jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); |
| - |
| - fake_audio_device_module_.reset(new webrtc::FakeAudioDeviceModule()); |
| - |
| - peer_connection_factory_ = webrtc::CreatePeerConnectionFactory( |
| - worker_thread, rtc::Thread::Current(), |
| - fake_audio_device_module_.get(), nullptr, 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); |
| - |
| - peer_connection_ = peer_connection_factory_->CreatePeerConnection( |
| - rtc_config, &constraints, port_allocator_factory_, nullptr, this); |
| - |
| - data_stream_adapter_.Initialize(peer_connection_, |
| - role_ == TransportRole::SERVER); |
| - |
| - if (role_ == TransportRole::CLIENT) { |
| - webrtc::FakeConstraints offer_config; |
| - offer_config.AddMandatory( |
| - webrtc::MediaConstraintsInterface::kOfferToReceiveVideo, |
| - webrtc::MediaConstraintsInterface::kValueTrue); |
| - offer_config.AddMandatory( |
| - webrtc::MediaConstraintsInterface::kOfferToReceiveAudio, |
| - webrtc::MediaConstraintsInterface::kValueFalse); |
| - offer_config.AddMandatory( |
| - webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, |
| - webrtc::MediaConstraintsInterface::kValueTrue); |
| - peer_connection_->CreateOffer( |
| - CreateSessionDescriptionObserver::Create( |
| - base::Bind(&WebrtcTransport::OnLocalSessionDescriptionCreated, |
| - weak_factory_.GetWeakPtr())), |
| - &offer_config); |
| - } |
| -} |
| - |
| void WebrtcTransport::OnLocalSessionDescriptionCreated( |
| scoped_ptr<webrtc::SessionDescriptionInterface> description, |
| const std::string& error) { |
| @@ -329,7 +298,8 @@ void WebrtcTransport::OnLocalDescriptionSet(bool success, |
| AddPendingCandidatesIfPossible(); |
| } |
| -void WebrtcTransport::OnRemoteDescriptionSet(bool success, |
| +void WebrtcTransport::OnRemoteDescriptionSet(bool send_answer, |
| + bool success, |
| const std::string& error) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| @@ -343,7 +313,7 @@ void WebrtcTransport::OnRemoteDescriptionSet(bool success, |
| } |
| // Create and send answer on the server. |
| - if (role_ == TransportRole::SERVER) { |
| + if (send_answer) { |
| peer_connection_->CreateAnswer( |
| CreateSessionDescriptionObserver::Create( |
| base::Bind(&WebrtcTransport::OnLocalSessionDescriptionCreated, |
| @@ -389,7 +359,25 @@ void WebrtcTransport::OnDataChannel( |
| void WebrtcTransport::OnRenegotiationNeeded() { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - // TODO(sergeyu): Figure out what needs to happen here. |
| + |
| + if (role_ == TransportRole::SERVER) { |
| + RequestNegotiation(); |
| + } else { |
| + // TODO(sergeyu): Is it necessary to support renegotiation initiated by the |
| + // client? |
| + NOTIMPLEMENTED(); |
| + } |
| +} |
| + |
| +void WebrtcTransport::RequestNegotiation() { |
| + DCHECK(role_ == TransportRole::SERVER); |
| + |
| + if (!negotiation_pending_) { |
| + negotiation_pending_ = true; |
| + base::ThreadTaskRunnerHandle::Get()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&WebrtcTransport::SendOffer, weak_factory_.GetWeakPtr())); |
| + } |
| } |
| void WebrtcTransport::OnIceConnectionChange( |
| @@ -446,6 +434,28 @@ void WebrtcTransport::EnsurePendingTransportInfoMessage() { |
| } |
| } |
| +void WebrtcTransport::SendOffer() { |
| + DCHECK(role_ == TransportRole::SERVER); |
| + |
| + DCHECK(negotiation_pending_); |
| + negotiation_pending_ = false; |
| + |
| + webrtc::FakeConstraints offer_config; |
| + offer_config.AddMandatory( |
| + webrtc::MediaConstraintsInterface::kOfferToReceiveVideo, |
| + webrtc::MediaConstraintsInterface::kValueTrue); |
| + offer_config.AddMandatory( |
| + webrtc::MediaConstraintsInterface::kOfferToReceiveAudio, |
| + webrtc::MediaConstraintsInterface::kValueFalse); |
| + offer_config.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, |
| + webrtc::MediaConstraintsInterface::kValueTrue); |
| + peer_connection_->CreateOffer( |
| + CreateSessionDescriptionObserver::Create( |
| + base::Bind(&WebrtcTransport::OnLocalSessionDescriptionCreated, |
| + weak_factory_.GetWeakPtr())), |
| + &offer_config); |
| +} |
| + |
| void WebrtcTransport::SendTransportInfo() { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| DCHECK(pending_transport_info_message_); |
| @@ -472,23 +482,21 @@ void WebrtcTransport::AddPendingCandidatesIfPossible() { |
| } |
| WebrtcTransportFactory::WebrtcTransportFactory( |
| + rtc::Thread* worker_thread, |
| SignalStrategy* signal_strategy, |
| rtc::scoped_refptr<webrtc::PortAllocatorFactoryInterface> |
| port_allocator_factory, |
| TransportRole role) |
| - : signal_strategy_(signal_strategy), |
| + : worker_thread_(worker_thread), |
| + signal_strategy_(signal_strategy), |
| port_allocator_factory_(port_allocator_factory), |
| - role_(role), |
| - worker_thread_("ChromotingWebrtcWorkerThread") { |
| - worker_thread_.StartWithOptions( |
| - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); |
| -} |
| + role_(role) {} |
| WebrtcTransportFactory::~WebrtcTransportFactory() {} |
| scoped_ptr<Transport> WebrtcTransportFactory::CreateTransport() { |
| - return make_scoped_ptr(new WebrtcTransport(port_allocator_factory_, role_, |
| - worker_thread_.task_runner())); |
| + return make_scoped_ptr( |
| + new WebrtcTransport(worker_thread_, port_allocator_factory_, role_)); |
| } |
| } // namespace protocol |