webrtc_connection_to_client.cc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  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
  3. // found in the LICENSE file.
  4. #include "remoting/protocol/webrtc_connection_to_client.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/location.h"
  8. #include "base/logging.h"
  9. #include "components/webrtc/thread_wrapper.h"
  10. #include "net/base/io_buffer.h"
  11. #include "remoting/codec/video_encoder.h"
  12. #include "remoting/codec/webrtc_video_encoder_vpx.h"
  13. #include "remoting/protocol/audio_source.h"
  14. #include "remoting/protocol/audio_stream.h"
  15. #include "remoting/protocol/clipboard_stub.h"
  16. #include "remoting/protocol/host_control_dispatcher.h"
  17. #include "remoting/protocol/host_event_dispatcher.h"
  18. #include "remoting/protocol/host_stub.h"
  19. #include "remoting/protocol/input_stub.h"
  20. #include "remoting/protocol/message_pipe.h"
  21. #include "remoting/protocol/transport_context.h"
  22. #include "remoting/protocol/webrtc_audio_stream.h"
  23. #include "remoting/protocol/webrtc_transport.h"
  24. #include "remoting/protocol/webrtc_video_encoder_factory.h"
  25. #include "remoting/protocol/webrtc_video_stream.h"
  26. #include "third_party/webrtc/api/media_stream_interface.h"
  27. #include "third_party/webrtc/api/peer_connection_interface.h"
  28. #include "third_party/webrtc/api/sctp_transport_interface.h"
  29. namespace remoting {
  30. namespace protocol {
  31. namespace {
  32. const char kVideoStatsStreamLabel[] = "screen_stream";
  33. } // namespace
  34. // Currently the network thread is also used as worker thread for webrtc.
  35. //
  36. // TODO(sergeyu): Figure out if we would benefit from using a separate
  37. // thread as a worker thread.
  38. WebrtcConnectionToClient::WebrtcConnectionToClient(
  39. std::unique_ptr<protocol::Session> session,
  40. scoped_refptr<protocol::TransportContext> transport_context,
  41. scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner)
  42. : session_(std::move(session)),
  43. video_stats_dispatcher_(kVideoStatsStreamLabel),
  44. audio_task_runner_(audio_task_runner),
  45. control_dispatcher_(new HostControlDispatcher()),
  46. event_dispatcher_(new HostEventDispatcher()) {
  47. auto video_encoder_factory = std::make_unique<WebrtcVideoEncoderFactory>();
  48. video_encoder_factory_ = video_encoder_factory.get();
  49. transport_ = std::make_unique<WebrtcTransport>(
  50. webrtc::ThreadWrapper::current(), transport_context,
  51. std::move(video_encoder_factory), this);
  52. session_->SetEventHandler(this);
  53. session_->SetTransport(transport_.get());
  54. }
  55. WebrtcConnectionToClient::~WebrtcConnectionToClient() {
  56. DCHECK(thread_checker_.CalledOnValidThread());
  57. }
  58. void WebrtcConnectionToClient::SetEventHandler(
  59. ConnectionToClient::EventHandler* event_handler) {
  60. DCHECK(thread_checker_.CalledOnValidThread());
  61. event_handler_ = event_handler;
  62. }
  63. protocol::Session* WebrtcConnectionToClient::session() {
  64. DCHECK(thread_checker_.CalledOnValidThread());
  65. return session_.get();
  66. }
  67. void WebrtcConnectionToClient::Disconnect(ErrorCode error) {
  68. DCHECK(thread_checker_.CalledOnValidThread());
  69. // This should trigger OnConnectionClosed() event and this object
  70. // may be destroyed as the result.
  71. session_->Close(error);
  72. }
  73. std::unique_ptr<VideoStream> WebrtcConnectionToClient::StartVideoStream(
  74. const std::string& stream_name,
  75. std::unique_ptr<webrtc::DesktopCapturer> desktop_capturer) {
  76. DCHECK(thread_checker_.CalledOnValidThread());
  77. DCHECK(transport_);
  78. auto stream =
  79. std::make_unique<WebrtcVideoStream>(stream_name, session_options_);
  80. stream->set_video_stats_dispatcher(video_stats_dispatcher_.GetWeakPtr());
  81. stream->Start(std::move(desktop_capturer), transport_.get(),
  82. video_encoder_factory_);
  83. stream->SetEventTimestampsSource(
  84. event_dispatcher_->event_timestamps_source());
  85. return std::move(stream);
  86. }
  87. std::unique_ptr<AudioStream> WebrtcConnectionToClient::StartAudioStream(
  88. std::unique_ptr<AudioSource> audio_source) {
  89. DCHECK(thread_checker_.CalledOnValidThread());
  90. DCHECK(transport_);
  91. std::unique_ptr<WebrtcAudioStream> stream(new WebrtcAudioStream());
  92. stream->Start(audio_task_runner_, std::move(audio_source), transport_.get());
  93. return std::move(stream);
  94. }
  95. // Return pointer to ClientStub.
  96. ClientStub* WebrtcConnectionToClient::client_stub() {
  97. DCHECK(thread_checker_.CalledOnValidThread());
  98. return control_dispatcher_.get();
  99. }
  100. void WebrtcConnectionToClient::set_clipboard_stub(
  101. protocol::ClipboardStub* clipboard_stub) {
  102. DCHECK(thread_checker_.CalledOnValidThread());
  103. control_dispatcher_->set_clipboard_stub(clipboard_stub);
  104. }
  105. void WebrtcConnectionToClient::set_host_stub(protocol::HostStub* host_stub) {
  106. DCHECK(thread_checker_.CalledOnValidThread());
  107. control_dispatcher_->set_host_stub(host_stub);
  108. }
  109. void WebrtcConnectionToClient::set_input_stub(protocol::InputStub* input_stub) {
  110. DCHECK(thread_checker_.CalledOnValidThread());
  111. event_dispatcher_->set_input_stub(input_stub);
  112. }
  113. void WebrtcConnectionToClient::ApplySessionOptions(
  114. const SessionOptions& options) {
  115. session_options_ = options;
  116. DCHECK(transport_);
  117. transport_->ApplySessionOptions(options);
  118. video_encoder_factory_->ApplySessionOptions(options);
  119. }
  120. PeerConnectionControls* WebrtcConnectionToClient::peer_connection_controls() {
  121. return transport_.get();
  122. }
  123. WebrtcEventLogData* WebrtcConnectionToClient::rtc_event_log() {
  124. return transport_->rtc_event_log();
  125. }
  126. void WebrtcConnectionToClient::OnSessionStateChange(Session::State state) {
  127. DCHECK(thread_checker_.CalledOnValidThread());
  128. DCHECK(event_handler_);
  129. switch (state) {
  130. case Session::INITIALIZING:
  131. case Session::CONNECTING:
  132. case Session::ACCEPTING:
  133. case Session::ACCEPTED:
  134. // Don't care about these events.
  135. break;
  136. case Session::AUTHENTICATING:
  137. event_handler_->OnConnectionAuthenticating();
  138. break;
  139. case Session::AUTHENTICATED: {
  140. base::WeakPtr<WebrtcConnectionToClient> self = weak_factory_.GetWeakPtr();
  141. event_handler_->OnConnectionAuthenticated();
  142. // OnConnectionAuthenticated() call above may result in the connection
  143. // being torn down.
  144. if (self)
  145. event_handler_->CreateMediaStreams();
  146. break;
  147. }
  148. case Session::CLOSED:
  149. case Session::FAILED:
  150. control_dispatcher_.reset();
  151. event_dispatcher_.reset();
  152. transport_->Close(state == Session::CLOSED ? OK : session_->error());
  153. transport_.reset();
  154. event_handler_->OnConnectionClosed(
  155. state == Session::CLOSED ? OK : session_->error());
  156. break;
  157. }
  158. }
  159. void WebrtcConnectionToClient::OnWebrtcTransportConnecting() {
  160. DCHECK(thread_checker_.CalledOnValidThread());
  161. // Create outgoing control channel. |event_dispatcher_| is initialized later
  162. // because event channel is expected to be created by the client.
  163. control_dispatcher_->Init(
  164. transport_->CreateOutgoingChannel(control_dispatcher_->channel_name()),
  165. this);
  166. // Create channel for sending per-frame statistics. The video-stream will
  167. // only try to send any stats after this channel is connected.
  168. video_stats_dispatcher_.Init(
  169. transport_->CreateOutgoingChannel(video_stats_dispatcher_.channel_name()),
  170. this);
  171. }
  172. void WebrtcConnectionToClient::OnWebrtcTransportConnected() {
  173. DCHECK(thread_checker_.CalledOnValidThread());
  174. auto sctp_transport = transport_->peer_connection()->GetSctpTransport();
  175. if (sctp_transport) {
  176. absl::optional<double> max_message_size =
  177. sctp_transport->Information().MaxMessageSize();
  178. if (max_message_size && *max_message_size > 0) {
  179. control_dispatcher_->set_max_message_size(*max_message_size);
  180. }
  181. }
  182. }
  183. void WebrtcConnectionToClient::OnWebrtcTransportError(ErrorCode error) {
  184. DCHECK(thread_checker_.CalledOnValidThread());
  185. Disconnect(error);
  186. }
  187. void WebrtcConnectionToClient::OnWebrtcTransportProtocolChanged() {
  188. DCHECK(thread_checker_.CalledOnValidThread());
  189. // If not all channels are connected, this call will be deferred to
  190. // OnChannelInitialized() when all channels are connected.
  191. if (allChannelsConnected()) {
  192. event_handler_->OnTransportProtocolChange(transport_->transport_protocol());
  193. }
  194. }
  195. void WebrtcConnectionToClient::OnWebrtcTransportIncomingDataChannel(
  196. const std::string& name,
  197. std::unique_ptr<MessagePipe> pipe) {
  198. DCHECK(thread_checker_.CalledOnValidThread());
  199. DCHECK(event_handler_);
  200. if (name == event_dispatcher_->channel_name() &&
  201. !event_dispatcher_->is_connected()) {
  202. event_dispatcher_->Init(std::move(pipe), this);
  203. return;
  204. }
  205. event_handler_->OnIncomingDataChannel(name, std::move(pipe));
  206. }
  207. void WebrtcConnectionToClient::OnWebrtcTransportMediaStreamAdded(
  208. rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) {
  209. DCHECK(thread_checker_.CalledOnValidThread());
  210. LOG(WARNING) << "The client created an unexpected media stream.";
  211. }
  212. void WebrtcConnectionToClient::OnWebrtcTransportMediaStreamRemoved(
  213. rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) {
  214. DCHECK(thread_checker_.CalledOnValidThread());
  215. }
  216. void WebrtcConnectionToClient::OnWebrtcTransportRouteChanged(
  217. const TransportRoute& route) {
  218. DCHECK(thread_checker_.CalledOnValidThread());
  219. DCHECK(event_handler_);
  220. // WebRTC route-change events are triggered at the transport level, so the
  221. // channel name is not meaningful here.
  222. std::string channel_name;
  223. event_handler_->OnRouteChange(channel_name, route);
  224. }
  225. void WebrtcConnectionToClient::OnChannelInitialized(
  226. ChannelDispatcherBase* channel_dispatcher) {
  227. DCHECK(thread_checker_.CalledOnValidThread());
  228. if (allChannelsConnected()) {
  229. event_handler_->OnConnectionChannelsConnected();
  230. if (!transport_->transport_protocol().empty()) {
  231. event_handler_->OnTransportProtocolChange(
  232. transport_->transport_protocol());
  233. }
  234. }
  235. }
  236. void WebrtcConnectionToClient::OnChannelClosed(
  237. ChannelDispatcherBase* channel_dispatcher) {
  238. DCHECK(thread_checker_.CalledOnValidThread());
  239. if (channel_dispatcher == &video_stats_dispatcher_) {
  240. LOG(WARNING) << "video_stats channel was closed.";
  241. return;
  242. }
  243. LOG(ERROR) << "Channel " << channel_dispatcher->channel_name()
  244. << " was closed unexpectedly.";
  245. Disconnect(INCOMPATIBLE_PROTOCOL);
  246. }
  247. bool WebrtcConnectionToClient::allChannelsConnected() {
  248. return control_dispatcher_ && control_dispatcher_->is_connected() &&
  249. event_dispatcher_ && event_dispatcher_->is_connected();
  250. }
  251. } // namespace protocol
  252. } // namespace remoting