ice_connection_to_client.cc 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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/ice_connection_to_client.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/location.h"
  8. #include "base/memory/ptr_util.h"
  9. #include "build/build_config.h"
  10. #include "net/base/io_buffer.h"
  11. #include "remoting/codec/audio_encoder.h"
  12. #include "remoting/codec/audio_encoder_opus.h"
  13. #include "remoting/codec/video_encoder.h"
  14. #include "remoting/protocol/audio_pump.h"
  15. #include "remoting/protocol/audio_source.h"
  16. #include "remoting/protocol/audio_writer.h"
  17. #include "remoting/protocol/clipboard_stub.h"
  18. #include "remoting/protocol/host_control_dispatcher.h"
  19. #include "remoting/protocol/host_event_dispatcher.h"
  20. #include "remoting/protocol/host_stub.h"
  21. #include "remoting/protocol/host_video_dispatcher.h"
  22. #include "remoting/protocol/input_stub.h"
  23. #include "remoting/protocol/transport_context.h"
  24. #include "remoting/protocol/video_frame_pump.h"
  25. namespace remoting {
  26. namespace protocol {
  27. namespace {
  28. std::unique_ptr<AudioEncoder> CreateAudioEncoder(
  29. const protocol::SessionConfig& config) {
  30. #if BUILDFLAG(IS_IOS)
  31. // TODO(nicholss): iOS should not use Opus. This is to prevent us from
  32. // depending on //media. In the future we will use webrtc for connection
  33. // and this will be a non-issue.
  34. return nullptr;
  35. #else
  36. const protocol::ChannelConfig& audio_config = config.audio_config();
  37. if (audio_config.codec == protocol::ChannelConfig::CODEC_OPUS) {
  38. return base::WrapUnique(new AudioEncoderOpus());
  39. }
  40. #endif
  41. NOTREACHED();
  42. return nullptr;
  43. }
  44. } // namespace
  45. IceConnectionToClient::IceConnectionToClient(
  46. std::unique_ptr<protocol::Session> session,
  47. scoped_refptr<TransportContext> transport_context,
  48. scoped_refptr<base::SingleThreadTaskRunner> video_encode_task_runner,
  49. scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner)
  50. : event_handler_(nullptr),
  51. session_(std::move(session)),
  52. video_encode_task_runner_(std::move(video_encode_task_runner)),
  53. audio_task_runner_(std::move(audio_task_runner)),
  54. transport_(transport_context, this),
  55. control_dispatcher_(new HostControlDispatcher()),
  56. event_dispatcher_(new HostEventDispatcher()),
  57. video_dispatcher_(new HostVideoDispatcher()) {
  58. session_->SetEventHandler(this);
  59. session_->SetTransport(&transport_);
  60. }
  61. IceConnectionToClient::~IceConnectionToClient() {
  62. DCHECK(thread_checker_.CalledOnValidThread());
  63. }
  64. void IceConnectionToClient::SetEventHandler(
  65. ConnectionToClient::EventHandler* event_handler) {
  66. DCHECK(thread_checker_.CalledOnValidThread());
  67. event_handler_ = event_handler;
  68. }
  69. protocol::Session* IceConnectionToClient::session() {
  70. DCHECK(thread_checker_.CalledOnValidThread());
  71. return session_.get();
  72. }
  73. void IceConnectionToClient::Disconnect(ErrorCode error) {
  74. DCHECK(thread_checker_.CalledOnValidThread());
  75. // This should trigger OnConnectionClosed() event and this object
  76. // may be destroyed as the result.
  77. session_->Close(error);
  78. }
  79. std::unique_ptr<VideoStream> IceConnectionToClient::StartVideoStream(
  80. const std::string& stream_name,
  81. std::unique_ptr<webrtc::DesktopCapturer> desktop_capturer) {
  82. DCHECK(thread_checker_.CalledOnValidThread());
  83. std::unique_ptr<VideoEncoder> video_encoder =
  84. VideoEncoder::Create(session_->config());
  85. std::unique_ptr<VideoFramePump> pump(
  86. new VideoFramePump(video_encode_task_runner_, std::move(desktop_capturer),
  87. std::move(video_encoder), video_dispatcher_.get()));
  88. pump->SetEventTimestampsSource(event_dispatcher_->event_timestamps_source());
  89. video_dispatcher_->set_video_feedback_stub(pump->video_feedback_stub());
  90. return std::move(pump);
  91. }
  92. std::unique_ptr<AudioStream> IceConnectionToClient::StartAudioStream(
  93. std::unique_ptr<AudioSource> audio_source) {
  94. DCHECK(thread_checker_.CalledOnValidThread());
  95. // Audio channel is disabled.
  96. if (!audio_writer_)
  97. return nullptr;
  98. std::unique_ptr<AudioEncoder> audio_encoder =
  99. CreateAudioEncoder(session_->config());
  100. return base::WrapUnique(
  101. new AudioPump(audio_task_runner_, std::move(audio_source),
  102. std::move(audio_encoder), audio_writer_.get()));
  103. }
  104. // Return pointer to ClientStub.
  105. ClientStub* IceConnectionToClient::client_stub() {
  106. DCHECK(thread_checker_.CalledOnValidThread());
  107. return control_dispatcher_.get();
  108. }
  109. void IceConnectionToClient::set_clipboard_stub(
  110. protocol::ClipboardStub* clipboard_stub) {
  111. DCHECK(thread_checker_.CalledOnValidThread());
  112. control_dispatcher_->set_clipboard_stub(clipboard_stub);
  113. }
  114. void IceConnectionToClient::set_host_stub(protocol::HostStub* host_stub) {
  115. DCHECK(thread_checker_.CalledOnValidThread());
  116. control_dispatcher_->set_host_stub(host_stub);
  117. }
  118. void IceConnectionToClient::set_input_stub(protocol::InputStub* input_stub) {
  119. DCHECK(thread_checker_.CalledOnValidThread());
  120. event_dispatcher_->set_input_stub(input_stub);
  121. }
  122. PeerConnectionControls* IceConnectionToClient::peer_connection_controls() {
  123. return nullptr;
  124. }
  125. WebrtcEventLogData* IceConnectionToClient::rtc_event_log() {
  126. return nullptr;
  127. }
  128. void IceConnectionToClient::OnSessionStateChange(Session::State state) {
  129. DCHECK(thread_checker_.CalledOnValidThread());
  130. DCHECK(event_handler_);
  131. switch (state) {
  132. case Session::INITIALIZING:
  133. case Session::CONNECTING:
  134. case Session::ACCEPTING:
  135. case Session::ACCEPTED:
  136. // Don't care about these events.
  137. break;
  138. case Session::AUTHENTICATING:
  139. event_handler_->OnConnectionAuthenticating();
  140. break;
  141. case Session::AUTHENTICATED:
  142. // Initialize channels.
  143. control_dispatcher_->Init(transport_.GetMultiplexedChannelFactory(),
  144. this);
  145. event_dispatcher_->Init(transport_.GetMultiplexedChannelFactory(), this);
  146. video_dispatcher_->Init(transport_.GetChannelFactory(), this);
  147. audio_writer_ = AudioWriter::Create(session_->config());
  148. if (audio_writer_)
  149. audio_writer_->Init(transport_.GetMultiplexedChannelFactory(), this);
  150. // Notify the handler after initializing the channels, so that
  151. // ClientSession can get a client clipboard stub.
  152. event_handler_->OnConnectionAuthenticated();
  153. break;
  154. case Session::CLOSED:
  155. case Session::FAILED:
  156. CloseChannels();
  157. event_handler_->OnConnectionClosed(
  158. state == Session::FAILED ? session_->error() : OK);
  159. break;
  160. }
  161. }
  162. void IceConnectionToClient::OnIceTransportRouteChange(
  163. const std::string& channel_name,
  164. const TransportRoute& route) {
  165. event_handler_->OnRouteChange(channel_name, route);
  166. }
  167. void IceConnectionToClient::OnIceTransportError(ErrorCode error) {
  168. DCHECK(thread_checker_.CalledOnValidThread());
  169. Disconnect(error);
  170. }
  171. void IceConnectionToClient::OnChannelInitialized(
  172. ChannelDispatcherBase* channel_dispatcher) {
  173. DCHECK(thread_checker_.CalledOnValidThread());
  174. NotifyIfChannelsReady();
  175. }
  176. void IceConnectionToClient::OnChannelClosed(
  177. ChannelDispatcherBase* channel_dispatcher) {
  178. DCHECK(thread_checker_.CalledOnValidThread());
  179. Disconnect(OK);
  180. }
  181. void IceConnectionToClient::NotifyIfChannelsReady() {
  182. DCHECK(thread_checker_.CalledOnValidThread());
  183. if (!control_dispatcher_ || !control_dispatcher_->is_connected())
  184. return;
  185. if (!event_dispatcher_ || !event_dispatcher_->is_connected())
  186. return;
  187. if (!video_dispatcher_ || !video_dispatcher_->is_connected())
  188. return;
  189. if ((!audio_writer_ || !audio_writer_->is_connected()) &&
  190. session_->config().is_audio_enabled()) {
  191. return;
  192. }
  193. event_handler_->OnConnectionChannelsConnected();
  194. event_handler_->CreateMediaStreams();
  195. }
  196. void IceConnectionToClient::CloseChannels() {
  197. control_dispatcher_.reset();
  198. event_dispatcher_.reset();
  199. video_dispatcher_.reset();
  200. audio_writer_.reset();
  201. }
  202. } // namespace protocol
  203. } // namespace remoting