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 |