| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/host/client_session.h" | 5 #include "remoting/host/client_session.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 12 #include "base/single_thread_task_runner.h" | 12 #include "base/single_thread_task_runner.h" |
| 13 #include "base/threading/thread_task_runner_handle.h" | 13 #include "base/threading/thread_task_runner_handle.h" |
| 14 #include "build/build_config.h" | 14 #include "build/build_config.h" |
| 15 #include "remoting/base/capabilities.h" | 15 #include "remoting/base/capabilities.h" |
| 16 #include "remoting/base/constants.h" | 16 #include "remoting/base/constants.h" |
| 17 #include "remoting/base/logging.h" | 17 #include "remoting/base/logging.h" |
| 18 #include "remoting/codec/audio_encoder.h" | |
| 19 #include "remoting/codec/audio_encoder_opus.h" | |
| 20 #include "remoting/codec/audio_encoder_verbatim.h" | |
| 21 #include "remoting/host/audio_capturer.h" | 18 #include "remoting/host/audio_capturer.h" |
| 22 #include "remoting/host/audio_pump.h" | |
| 23 #include "remoting/host/desktop_environment.h" | 19 #include "remoting/host/desktop_environment.h" |
| 24 #include "remoting/host/host_extension_session.h" | 20 #include "remoting/host/host_extension_session.h" |
| 25 #include "remoting/host/input_injector.h" | 21 #include "remoting/host/input_injector.h" |
| 26 #include "remoting/host/mouse_shape_pump.h" | 22 #include "remoting/host/mouse_shape_pump.h" |
| 27 #include "remoting/host/screen_controls.h" | 23 #include "remoting/host/screen_controls.h" |
| 28 #include "remoting/host/screen_resolution.h" | 24 #include "remoting/host/screen_resolution.h" |
| 29 #include "remoting/proto/control.pb.h" | 25 #include "remoting/proto/control.pb.h" |
| 30 #include "remoting/proto/event.pb.h" | 26 #include "remoting/proto/event.pb.h" |
| 27 #include "remoting/protocol/audio_stream.h" |
| 31 #include "remoting/protocol/client_stub.h" | 28 #include "remoting/protocol/client_stub.h" |
| 32 #include "remoting/protocol/clipboard_thread_proxy.h" | 29 #include "remoting/protocol/clipboard_thread_proxy.h" |
| 33 #include "remoting/protocol/pairing_registry.h" | 30 #include "remoting/protocol/pairing_registry.h" |
| 34 #include "remoting/protocol/session.h" | 31 #include "remoting/protocol/session.h" |
| 35 #include "remoting/protocol/session_config.h" | 32 #include "remoting/protocol/session_config.h" |
| 36 #include "remoting/protocol/video_frame_pump.h" | 33 #include "remoting/protocol/video_frame_pump.h" |
| 37 #include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h" | 34 #include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h" |
| 38 | 35 |
| 39 namespace remoting { | 36 namespace remoting { |
| 40 | 37 |
| 41 namespace { | 38 namespace { |
| 42 | 39 |
| 43 // Name of command-line flag to disable use of I444 by default. | 40 // Name of command-line flag to disable use of I444 by default. |
| 44 const char kDisableI444SwitchName[] = "disable-i444"; | 41 const char kDisableI444SwitchName[] = "disable-i444"; |
| 45 | 42 |
| 46 std::unique_ptr<AudioEncoder> CreateAudioEncoder( | |
| 47 const protocol::SessionConfig& config) { | |
| 48 const protocol::ChannelConfig& audio_config = config.audio_config(); | |
| 49 | |
| 50 if (audio_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) { | |
| 51 return base::MakeUnique<AudioEncoderVerbatim>(); | |
| 52 } else if (audio_config.codec == protocol::ChannelConfig::CODEC_OPUS) { | |
| 53 return base::MakeUnique<AudioEncoderOpus>(); | |
| 54 } | |
| 55 | |
| 56 NOTREACHED(); | |
| 57 return nullptr; | |
| 58 } | |
| 59 | |
| 60 } // namespace | 43 } // namespace |
| 61 | 44 |
| 62 ClientSession::ClientSession( | 45 ClientSession::ClientSession( |
| 63 EventHandler* event_handler, | 46 EventHandler* event_handler, |
| 64 scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, | |
| 65 std::unique_ptr<protocol::ConnectionToClient> connection, | 47 std::unique_ptr<protocol::ConnectionToClient> connection, |
| 66 DesktopEnvironmentFactory* desktop_environment_factory, | 48 DesktopEnvironmentFactory* desktop_environment_factory, |
| 67 const base::TimeDelta& max_duration, | 49 const base::TimeDelta& max_duration, |
| 68 scoped_refptr<protocol::PairingRegistry> pairing_registry, | 50 scoped_refptr<protocol::PairingRegistry> pairing_registry, |
| 69 const std::vector<HostExtension*>& extensions) | 51 const std::vector<HostExtension*>& extensions) |
| 70 : event_handler_(event_handler), | 52 : event_handler_(event_handler), |
| 71 connection_(std::move(connection)), | 53 connection_(std::move(connection)), |
| 72 client_jid_(connection_->session()->jid()), | 54 client_jid_(connection_->session()->jid()), |
| 73 desktop_environment_factory_(desktop_environment_factory), | 55 desktop_environment_factory_(desktop_environment_factory), |
| 74 input_tracker_(&host_input_filter_), | 56 input_tracker_(&host_input_filter_), |
| 75 remote_input_filter_(&input_tracker_), | 57 remote_input_filter_(&input_tracker_), |
| 76 mouse_clamping_filter_(&remote_input_filter_), | 58 mouse_clamping_filter_(&remote_input_filter_), |
| 77 disable_input_filter_(&mouse_clamping_filter_), | 59 disable_input_filter_(&mouse_clamping_filter_), |
| 78 disable_clipboard_filter_(clipboard_echo_filter_.host_filter()), | 60 disable_clipboard_filter_(clipboard_echo_filter_.host_filter()), |
| 79 client_clipboard_factory_(clipboard_echo_filter_.client_filter()), | 61 client_clipboard_factory_(clipboard_echo_filter_.client_filter()), |
| 80 max_duration_(max_duration), | 62 max_duration_(max_duration), |
| 81 audio_task_runner_(audio_task_runner), | |
| 82 pairing_registry_(pairing_registry), | 63 pairing_registry_(pairing_registry), |
| 83 // Note that |lossless_video_color_| defaults to true, but actually only | 64 // Note that |lossless_video_color_| defaults to true, but actually only |
| 84 // controls VP9 video stream color quality. | 65 // controls VP9 video stream color quality. |
| 85 lossless_video_color_(!base::CommandLine::ForCurrentProcess()->HasSwitch( | 66 lossless_video_color_(!base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 86 kDisableI444SwitchName)), | 67 kDisableI444SwitchName)), |
| 87 weak_factory_(this) { | 68 weak_factory_(this) { |
| 88 connection_->SetEventHandler(this); | 69 connection_->SetEventHandler(this); |
| 89 | 70 |
| 90 // Create a manager for the configured extensions, if any. | 71 // Create a manager for the configured extensions, if any. |
| 91 extension_manager_.reset(new HostExtensionSessionManager(extensions, this)); | 72 extension_manager_.reset(new HostExtensionSessionManager(extensions, this)); |
| 92 | 73 |
| 93 #if defined(OS_WIN) | 74 #if defined(OS_WIN) |
| 94 // LocalInputMonitorWin filters out an echo of the injected input before it | 75 // LocalInputMonitorWin filters out an echo of the injected input before it |
| 95 // reaches |remote_input_filter_|. | 76 // reaches |remote_input_filter_|. |
| 96 remote_input_filter_.SetExpectLocalEcho(false); | 77 remote_input_filter_.SetExpectLocalEcho(false); |
| 97 #endif // defined(OS_WIN) | 78 #endif // defined(OS_WIN) |
| 98 } | 79 } |
| 99 | 80 |
| 100 ClientSession::~ClientSession() { | 81 ClientSession::~ClientSession() { |
| 101 DCHECK(CalledOnValidThread()); | 82 DCHECK(CalledOnValidThread()); |
| 102 DCHECK(!audio_pump_); | 83 DCHECK(!audio_stream_); |
| 103 DCHECK(!desktop_environment_); | 84 DCHECK(!desktop_environment_); |
| 104 DCHECK(!input_injector_); | 85 DCHECK(!input_injector_); |
| 105 DCHECK(!screen_controls_); | 86 DCHECK(!screen_controls_); |
| 106 DCHECK(!video_stream_); | 87 DCHECK(!video_stream_); |
| 107 | 88 |
| 108 connection_.reset(); | 89 connection_.reset(); |
| 109 } | 90 } |
| 110 | 91 |
| 111 void ClientSession::NotifyClientResolution( | 92 void ClientSession::NotifyClientResolution( |
| 112 const protocol::ClientResolution& resolution) { | 93 const protocol::ClientResolution& resolution) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 video_stream_->SetLosslessColor(lossless_video_color_); | 147 video_stream_->SetLosslessColor(lossless_video_color_); |
| 167 } | 148 } |
| 168 } | 149 } |
| 169 | 150 |
| 170 void ClientSession::ControlAudio(const protocol::AudioControl& audio_control) { | 151 void ClientSession::ControlAudio(const protocol::AudioControl& audio_control) { |
| 171 DCHECK(CalledOnValidThread()); | 152 DCHECK(CalledOnValidThread()); |
| 172 | 153 |
| 173 if (audio_control.has_enable()) { | 154 if (audio_control.has_enable()) { |
| 174 VLOG(1) << "Received AudioControl (enable=" | 155 VLOG(1) << "Received AudioControl (enable=" |
| 175 << audio_control.enable() << ")"; | 156 << audio_control.enable() << ")"; |
| 176 if (audio_pump_) | 157 if (audio_stream_) |
| 177 audio_pump_->Pause(!audio_control.enable()); | 158 audio_stream_->Pause(!audio_control.enable()); |
| 178 } | 159 } |
| 179 } | 160 } |
| 180 | 161 |
| 181 void ClientSession::SetCapabilities( | 162 void ClientSession::SetCapabilities( |
| 182 const protocol::Capabilities& capabilities) { | 163 const protocol::Capabilities& capabilities) { |
| 183 DCHECK(CalledOnValidThread()); | 164 DCHECK(CalledOnValidThread()); |
| 184 | 165 |
| 185 // Ignore all the messages but the 1st one. | 166 // Ignore all the messages but the 1st one. |
| 186 if (client_capabilities_) { | 167 if (client_capabilities_) { |
| 187 LOG(WARNING) << "protocol::Capabilities has been received already."; | 168 LOG(WARNING) << "protocol::Capabilities has been received already."; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 | 217 |
| 237 void ClientSession::OnConnectionAuthenticating( | 218 void ClientSession::OnConnectionAuthenticating( |
| 238 protocol::ConnectionToClient* connection) { | 219 protocol::ConnectionToClient* connection) { |
| 239 event_handler_->OnSessionAuthenticating(this); | 220 event_handler_->OnSessionAuthenticating(this); |
| 240 } | 221 } |
| 241 | 222 |
| 242 void ClientSession::OnConnectionAuthenticated( | 223 void ClientSession::OnConnectionAuthenticated( |
| 243 protocol::ConnectionToClient* connection) { | 224 protocol::ConnectionToClient* connection) { |
| 244 DCHECK(CalledOnValidThread()); | 225 DCHECK(CalledOnValidThread()); |
| 245 DCHECK_EQ(connection_.get(), connection); | 226 DCHECK_EQ(connection_.get(), connection); |
| 246 DCHECK(!audio_pump_); | 227 DCHECK(!audio_stream_); |
| 247 DCHECK(!desktop_environment_); | 228 DCHECK(!desktop_environment_); |
| 248 DCHECK(!input_injector_); | 229 DCHECK(!input_injector_); |
| 249 DCHECK(!screen_controls_); | 230 DCHECK(!screen_controls_); |
| 250 DCHECK(!video_stream_); | 231 DCHECK(!video_stream_); |
| 251 | 232 |
| 252 is_authenticated_ = true; | 233 is_authenticated_ = true; |
| 253 | 234 |
| 254 if (max_duration_ > base::TimeDelta()) { | 235 if (max_duration_ > base::TimeDelta()) { |
| 255 max_duration_timer_.Start( | 236 max_duration_timer_.Start( |
| 256 FROM_HERE, max_duration_, | 237 FROM_HERE, max_duration_, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 // Connect the host input stubs. | 269 // Connect the host input stubs. |
| 289 connection_->set_input_stub(&disable_input_filter_); | 270 connection_->set_input_stub(&disable_input_filter_); |
| 290 host_input_filter_.set_input_stub(input_injector_.get()); | 271 host_input_filter_.set_input_stub(input_injector_.get()); |
| 291 | 272 |
| 292 // Connect the clipboard stubs. | 273 // Connect the clipboard stubs. |
| 293 connection_->set_clipboard_stub(&disable_clipboard_filter_); | 274 connection_->set_clipboard_stub(&disable_clipboard_filter_); |
| 294 clipboard_echo_filter_.set_host_stub(input_injector_.get()); | 275 clipboard_echo_filter_.set_host_stub(input_injector_.get()); |
| 295 clipboard_echo_filter_.set_client_stub(connection_->client_stub()); | 276 clipboard_echo_filter_.set_client_stub(connection_->client_stub()); |
| 296 } | 277 } |
| 297 | 278 |
| 298 void ClientSession::CreateVideoStreams( | 279 void ClientSession::CreateMediaStreams( |
| 299 protocol::ConnectionToClient* connection) { | 280 protocol::ConnectionToClient* connection) { |
| 300 DCHECK(CalledOnValidThread()); | 281 DCHECK(CalledOnValidThread()); |
| 301 DCHECK_EQ(connection_.get(), connection); | 282 DCHECK_EQ(connection_.get(), connection); |
| 302 | 283 |
| 303 // Create a VideoStream to pump frames from the capturer to the client. | 284 // Create a VideoStream to pump frames from the capturer to the client. |
| 304 video_stream_ = connection_->StartVideoStream( | 285 video_stream_ = connection_->StartVideoStream( |
| 305 desktop_environment_->CreateVideoCapturer()); | 286 desktop_environment_->CreateVideoCapturer()); |
| 306 | 287 |
| 288 // Create a AudioStream to pump audio from the capturer to the client. |
| 289 audio_stream_ = connection_->StartAudioStream( |
| 290 desktop_environment_->CreateAudioCapturer()); |
| 291 |
| 307 video_stream_->SetObserver(this); | 292 video_stream_->SetObserver(this); |
| 308 | 293 |
| 309 // Apply video-control parameters to the new stream. | 294 // Apply video-control parameters to the new stream. |
| 310 video_stream_->SetLosslessEncode(lossless_video_encode_); | 295 video_stream_->SetLosslessEncode(lossless_video_encode_); |
| 311 video_stream_->SetLosslessColor(lossless_video_color_); | 296 video_stream_->SetLosslessColor(lossless_video_color_); |
| 312 | 297 |
| 313 // Pause capturing if necessary. | 298 // Pause capturing if necessary. |
| 314 video_stream_->Pause(pause_video_); | 299 video_stream_->Pause(pause_video_); |
| 315 } | 300 } |
| 316 | 301 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 330 | 315 |
| 331 // Start the event executor. | 316 // Start the event executor. |
| 332 input_injector_->Start(CreateClipboardProxy()); | 317 input_injector_->Start(CreateClipboardProxy()); |
| 333 SetDisableInputs(false); | 318 SetDisableInputs(false); |
| 334 | 319 |
| 335 // Create MouseShapePump to send mouse cursor shape. | 320 // Create MouseShapePump to send mouse cursor shape. |
| 336 mouse_shape_pump_.reset( | 321 mouse_shape_pump_.reset( |
| 337 new MouseShapePump(desktop_environment_->CreateMouseCursorMonitor(), | 322 new MouseShapePump(desktop_environment_->CreateMouseCursorMonitor(), |
| 338 connection_->client_stub())); | 323 connection_->client_stub())); |
| 339 | 324 |
| 340 // Create an AudioPump if audio is enabled, to pump audio samples. | |
| 341 if (connection_->session()->config().is_audio_enabled()) { | |
| 342 std::unique_ptr<AudioEncoder> audio_encoder = | |
| 343 CreateAudioEncoder(connection_->session()->config()); | |
| 344 audio_pump_.reset(new AudioPump( | |
| 345 audio_task_runner_, desktop_environment_->CreateAudioCapturer(), | |
| 346 std::move(audio_encoder), connection_->audio_stub())); | |
| 347 } | |
| 348 | |
| 349 if (pending_video_layout_message_) { | 325 if (pending_video_layout_message_) { |
| 350 connection_->client_stub()->SetVideoLayout(*pending_video_layout_message_); | 326 connection_->client_stub()->SetVideoLayout(*pending_video_layout_message_); |
| 351 pending_video_layout_message_.reset(); | 327 pending_video_layout_message_.reset(); |
| 352 } | 328 } |
| 353 | 329 |
| 354 // Notify the event handler that all our channels are now connected. | 330 // Notify the event handler that all our channels are now connected. |
| 355 event_handler_->OnSessionChannelsConnected(this); | 331 event_handler_->OnSessionChannelsConnected(this); |
| 356 } | 332 } |
| 357 | 333 |
| 358 void ClientSession::OnConnectionClosed( | 334 void ClientSession::OnConnectionClosed( |
| 359 protocol::ConnectionToClient* connection, | 335 protocol::ConnectionToClient* connection, |
| 360 protocol::ErrorCode error) { | 336 protocol::ErrorCode error) { |
| 361 DCHECK(CalledOnValidThread()); | 337 DCHECK(CalledOnValidThread()); |
| 362 DCHECK_EQ(connection_.get(), connection); | 338 DCHECK_EQ(connection_.get(), connection); |
| 363 | 339 |
| 364 HOST_LOG << "Client disconnected: " << client_jid_ << "; error = " << error; | 340 HOST_LOG << "Client disconnected: " << client_jid_ << "; error = " << error; |
| 365 | 341 |
| 366 // Ignore any further callbacks. | 342 // Ignore any further callbacks. |
| 367 weak_factory_.InvalidateWeakPtrs(); | 343 weak_factory_.InvalidateWeakPtrs(); |
| 368 | 344 |
| 369 // If the client never authenticated then the session failed. | 345 // If the client never authenticated then the session failed. |
| 370 if (!is_authenticated_) | 346 if (!is_authenticated_) |
| 371 event_handler_->OnSessionAuthenticationFailed(this); | 347 event_handler_->OnSessionAuthenticationFailed(this); |
| 372 | 348 |
| 373 // Ensure that any pressed keys or buttons are released. | 349 // Ensure that any pressed keys or buttons are released. |
| 374 input_tracker_.ReleaseAll(); | 350 input_tracker_.ReleaseAll(); |
| 375 | 351 |
| 376 // Stop components access the client, audio or video stubs, which are no | 352 // Stop components access the client, audio or video stubs, which are no |
| 377 // longer valid once ConnectionToClient calls OnConnectionClosed(). | 353 // longer valid once ConnectionToClient calls OnConnectionClosed(). |
| 378 audio_pump_.reset(); | 354 audio_stream_.reset(); |
| 379 video_stream_.reset(); | 355 video_stream_.reset(); |
| 380 mouse_shape_pump_.reset(); | 356 mouse_shape_pump_.reset(); |
| 381 client_clipboard_factory_.InvalidateWeakPtrs(); | 357 client_clipboard_factory_.InvalidateWeakPtrs(); |
| 382 input_injector_.reset(); | 358 input_injector_.reset(); |
| 383 screen_controls_.reset(); | 359 screen_controls_.reset(); |
| 384 desktop_environment_.reset(); | 360 desktop_environment_.reset(); |
| 385 | 361 |
| 386 // Notify the ChromotingHost that this client is disconnected. | 362 // Notify the ChromotingHost that this client is disconnected. |
| 387 event_handler_->OnSessionClosed(this); | 363 event_handler_->OnSessionClosed(this); |
| 388 } | 364 } |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 } | 474 } |
| 499 } | 475 } |
| 500 | 476 |
| 501 void ClientSession::OnVideoFrameSent(protocol::VideoStream* stream, | 477 void ClientSession::OnVideoFrameSent(protocol::VideoStream* stream, |
| 502 uint32_t frame_id, | 478 uint32_t frame_id, |
| 503 int64_t input_event_timestamp) { | 479 int64_t input_event_timestamp) { |
| 504 // TODO(sergeyu): Send a message to the client to notify about the new frame. | 480 // TODO(sergeyu): Send a message to the client to notify about the new frame. |
| 505 } | 481 } |
| 506 | 482 |
| 507 } // namespace remoting | 483 } // namespace remoting |
| OLD | NEW |