blob: acb96037f0e6f5b4b26b5e67bf91be65ee030a04 [file] [log] [blame]
[email protected]91e4b7f62012-01-25 23:23:021// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]44f60762011-03-23 12:13:352// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "remoting/host/client_session.h"
6
[email protected]4fe827a2011-08-10 03:30:197#include <algorithm>
sergeyu1417e0132015-12-23 19:01:228#include <utility>
[email protected]4fe827a2011-08-10 03:30:199
wez43ac2662015-06-10 18:22:2910#include "base/command_line.h"
dcheng0765c492016-04-06 22:41:5311#include "base/memory/ptr_util.h"
anujk.sharmabb802932015-05-05 21:57:2912#include "base/single_thread_task_runner.h"
13#include "base/thread_task_runner_handle.h"
avic5960f32015-12-22 22:49:4814#include "build/build_config.h"
[email protected]a5d181f2013-04-19 14:55:3715#include "remoting/base/capabilities.h"
sergeyu00a67b12016-04-01 00:07:0016#include "remoting/base/constants.h"
[email protected]6f742dd02013-11-26 23:19:5017#include "remoting/base/logging.h"
[email protected]170cba42012-09-12 22:28:3918#include "remoting/codec/audio_encoder.h"
[email protected]a6ccb7722012-10-23 21:10:4319#include "remoting/codec/audio_encoder_opus.h"
[email protected]170cba42012-09-12 22:28:3920#include "remoting/codec/audio_encoder_verbatim.h"
[email protected]ce404ca2013-01-16 17:23:5321#include "remoting/host/audio_capturer.h"
sergeyu7bc87602015-02-13 20:33:2822#include "remoting/host/audio_pump.h"
[email protected]170cba42012-09-12 22:28:3923#include "remoting/host/desktop_environment.h"
[email protected]399b4f62014-05-30 20:13:1524#include "remoting/host/host_extension_session.h"
[email protected]b0b72f112013-03-24 03:42:4225#include "remoting/host/input_injector.h"
sergeyu1afb35a12015-02-13 18:45:3026#include "remoting/host/mouse_shape_pump.h"
[email protected]231316a2013-03-25 06:01:1227#include "remoting/host/screen_controls.h"
[email protected]739e2802013-03-18 01:03:4828#include "remoting/host/screen_resolution.h"
[email protected]50d71c72012-05-03 01:28:5529#include "remoting/proto/control.pb.h"
[email protected]c78669c92011-06-13 22:42:3830#include "remoting/proto/event.pb.h"
[email protected]ff3761a12012-05-22 22:29:2431#include "remoting/protocol/client_stub.h"
[email protected]7f44ba42012-05-31 20:26:2932#include "remoting/protocol/clipboard_thread_proxy.h"
[email protected]88356922013-06-04 06:26:0133#include "remoting/protocol/pairing_registry.h"
sergeyub031cd22015-11-19 22:17:1334#include "remoting/protocol/session.h"
35#include "remoting/protocol/session_config.h"
sergeyu4d208002015-11-23 22:27:4336#include "remoting/protocol/video_frame_pump.h"
[email protected]4e719f42014-08-12 18:04:3737#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
[email protected]c78669c92011-06-13 22:42:3838
[email protected]739e2802013-03-18 01:03:4839namespace remoting {
[email protected]48a8ca32013-02-13 04:31:0140
sergeyu7bc87602015-02-13 20:33:2841namespace {
42
wez6e95a372015-07-08 22:33:3143// Name of command-line flag to disable use of I444 by default.
44const char kDisableI444SwitchName[] = "disable-i444";
wez43ac2662015-06-10 18:22:2945
dcheng0765c492016-04-06 22:41:5346std::unique_ptr<AudioEncoder> CreateAudioEncoder(
sergeyu7bc87602015-02-13 20:33:2847 const protocol::SessionConfig& config) {
48 const protocol::ChannelConfig& audio_config = config.audio_config();
49
50 if (audio_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) {
dcheng0765c492016-04-06 22:41:5351 return base::WrapUnique(new AudioEncoderVerbatim());
sergeyu7bc87602015-02-13 20:33:2852 } else if (audio_config.codec == protocol::ChannelConfig::CODEC_OPUS) {
dcheng0765c492016-04-06 22:41:5353 return base::WrapUnique(new AudioEncoderOpus());
sergeyu7bc87602015-02-13 20:33:2854 }
55
56 NOTREACHED();
57 return nullptr;
58}
59
60} // namespace
61
[email protected]44f60762011-03-23 12:13:3562ClientSession::ClientSession(
63 EventHandler* event_handler,
[email protected]032d9dd2012-11-01 17:55:0464 scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner,
dcheng0765c492016-04-06 22:41:5365 std::unique_ptr<protocol::ConnectionToClient> connection,
[email protected]81904792012-10-18 04:16:2866 DesktopEnvironmentFactory* desktop_environment_factory,
[email protected]88356922013-06-04 06:26:0167 const base::TimeDelta& max_duration,
[email protected]1b478ba2014-07-31 12:51:4368 scoped_refptr<protocol::PairingRegistry> pairing_registry,
69 const std::vector<HostExtension*>& extensions)
[email protected]44f60762011-03-23 12:13:3570 : event_handler_(event_handler),
sergeyu1417e0132015-12-23 19:01:2271 connection_(std::move(connection)),
[email protected]3361e1f2012-03-20 20:31:4472 client_jid_(connection_->session()->jid()),
[email protected]233bb942013-03-15 07:18:1773 desktop_environment_factory_(desktop_environment_factory),
[email protected]eccc2d42013-01-10 19:35:1474 input_tracker_(&host_input_filter_),
[email protected]86cbe6b2012-04-03 00:56:1875 remote_input_filter_(&input_tracker_),
[email protected]58f1ad42013-01-10 23:49:5176 mouse_clamping_filter_(&remote_input_filter_),
sergeyua609b7a2015-11-30 06:25:3977 disable_input_filter_(&mouse_clamping_filter_),
[email protected]750ae6b2012-08-20 22:52:4078 disable_clipboard_filter_(clipboard_echo_filter_.host_filter()),
[email protected]7f44ba42012-05-31 20:26:2979 client_clipboard_factory_(clipboard_echo_filter_.client_filter()),
[email protected]170cba42012-09-12 22:28:3980 max_duration_(max_duration),
[email protected]032d9dd2012-11-01 17:55:0481 audio_task_runner_(audio_task_runner),
[email protected]1b478ba2014-07-31 12:51:4382 pairing_registry_(pairing_registry),
sergeyu1f8cd502015-02-13 21:45:5383 is_authenticated_(false),
[email protected]1b478ba2014-07-31 12:51:4384 pause_video_(false),
85 lossless_video_encode_(false),
wez6e95a372015-07-08 22:33:3186 // Note that |lossless_video_color_| defaults to true, but actually only
87 // controls VP9 video stream color quality.
88 lossless_video_color_(!base::CommandLine::ForCurrentProcess()->HasSwitch(
89 kDisableI444SwitchName)),
kulkarni.a933aeaf2014-09-20 13:19:1790 weak_factory_(this) {
[email protected]ee910fd2011-11-10 18:23:3191 connection_->SetEventHandler(this);
92
[email protected]1b478ba2014-07-31 12:51:4393 // Create a manager for the configured extensions, if any.
94 extension_manager_.reset(new HostExtensionSessionManager(extensions, this));
95
[email protected]2f4084892013-02-25 20:30:2096#if defined(OS_WIN)
97 // LocalInputMonitorWin filters out an echo of the injected input before it
98 // reaches |remote_input_filter_|.
99 remote_input_filter_.SetExpectLocalEcho(false);
100#endif // defined(OS_WIN)
[email protected]44f60762011-03-23 12:13:35101}
102
[email protected]f19f09ca2013-03-13 11:10:29103ClientSession::~ClientSession() {
104 DCHECK(CalledOnValidThread());
sergeyu7bc87602015-02-13 20:33:28105 DCHECK(!audio_pump_);
[email protected]231316a2013-03-25 06:01:12106 DCHECK(!desktop_environment_);
[email protected]b0b72f112013-03-24 03:42:42107 DCHECK(!input_injector_);
[email protected]231316a2013-03-25 06:01:12108 DCHECK(!screen_controls_);
sergeyua609b7a2015-11-30 06:25:39109 DCHECK(!video_stream_);
[email protected]f19f09ca2013-03-13 11:10:29110
111 connection_.reset();
112}
113
[email protected]48a8ca32013-02-13 04:31:01114void ClientSession::NotifyClientResolution(
115 const protocol::ClientResolution& resolution) {
[email protected]a5d181f2013-04-19 14:55:37116 DCHECK(CalledOnValidThread());
117
[email protected]b9ed58f2013-05-16 10:45:24118 // TODO(sergeyu): Move these checks to protocol layer.
119 if (!resolution.has_dips_width() || !resolution.has_dips_height() ||
120 resolution.dips_width() < 0 || resolution.dips_height() < 0 ||
121 resolution.width() <= 0 || resolution.height() <= 0) {
122 LOG(ERROR) << "Received invalid ClientResolution message.";
[email protected]739e2802013-03-18 01:03:48123 return;
[email protected]b9ed58f2013-05-16 10:45:24124 }
[email protected]739e2802013-03-18 01:03:48125
126 VLOG(1) << "Received ClientResolution (dips_width="
127 << resolution.dips_width() << ", dips_height="
128 << resolution.dips_height() << ")";
129
[email protected]231316a2013-03-25 06:01:12130 if (!screen_controls_)
[email protected]739e2802013-03-18 01:03:48131 return;
132
133 ScreenResolution client_resolution(
[email protected]b9ed58f2013-05-16 10:45:24134 webrtc::DesktopSize(resolution.dips_width(), resolution.dips_height()),
sergeyu00a67b12016-04-01 00:07:00135 webrtc::DesktopVector(kDefaultDpi, kDefaultDpi));
[email protected]739e2802013-03-18 01:03:48136
137 // Try to match the client's resolution.
[email protected]b9ed58f2013-05-16 10:45:24138 screen_controls_->SetScreenResolution(client_resolution);
[email protected]50d71c72012-05-03 01:28:55139}
140
141void ClientSession::ControlVideo(const protocol::VideoControl& video_control) {
[email protected]a5d181f2013-04-19 14:55:37142 DCHECK(CalledOnValidThread());
143
sergeyua609b7a2015-11-30 06:25:39144 // Note that |video_stream_| may be null, depending upon whether
sergeyu10ce97b2015-02-05 23:53:14145 // extensions choose to wrap or "steal" the video capturer or encoder.
[email protected]50d71c72012-05-03 01:28:55146 if (video_control.has_enable()) {
147 VLOG(1) << "Received VideoControl (enable="
148 << video_control.enable() << ")";
[email protected]1b478ba2014-07-31 12:51:43149 pause_video_ = !video_control.enable();
sergeyua609b7a2015-11-30 06:25:39150 if (video_stream_)
151 video_stream_->Pause(pause_video_);
[email protected]50d71c72012-05-03 01:28:55152 }
[email protected]a516f1e2014-05-30 07:21:20153 if (video_control.has_lossless_encode()) {
154 VLOG(1) << "Received VideoControl (lossless_encode="
155 << video_control.lossless_encode() << ")";
[email protected]1b478ba2014-07-31 12:51:43156 lossless_video_encode_ = video_control.lossless_encode();
sergeyua609b7a2015-11-30 06:25:39157 if (video_stream_)
158 video_stream_->SetLosslessEncode(lossless_video_encode_);
[email protected]a516f1e2014-05-30 07:21:20159 }
160 if (video_control.has_lossless_color()) {
161 VLOG(1) << "Received VideoControl (lossless_color="
162 << video_control.lossless_color() << ")";
[email protected]1b478ba2014-07-31 12:51:43163 lossless_video_color_ = video_control.lossless_color();
sergeyua609b7a2015-11-30 06:25:39164 if (video_stream_)
165 video_stream_->SetLosslessColor(lossless_video_color_);
[email protected]a516f1e2014-05-30 07:21:20166 }
[email protected]f2b9cf32012-04-27 00:13:43167}
168
[email protected]f458bed2012-10-18 03:27:59169void ClientSession::ControlAudio(const protocol::AudioControl& audio_control) {
[email protected]a5d181f2013-04-19 14:55:37170 DCHECK(CalledOnValidThread());
171
[email protected]f458bed2012-10-18 03:27:59172 if (audio_control.has_enable()) {
173 VLOG(1) << "Received AudioControl (enable="
174 << audio_control.enable() << ")";
sergeyu7bc87602015-02-13 20:33:28175 if (audio_pump_)
176 audio_pump_->Pause(!audio_control.enable());
[email protected]f458bed2012-10-18 03:27:59177 }
178}
179
[email protected]a5d181f2013-04-19 14:55:37180void ClientSession::SetCapabilities(
181 const protocol::Capabilities& capabilities) {
182 DCHECK(CalledOnValidThread());
183
[email protected]a5d181f2013-04-19 14:55:37184 // Ignore all the messages but the 1st one.
185 if (client_capabilities_) {
186 LOG(WARNING) << "protocol::Capabilities has been received already.";
187 return;
188 }
189
[email protected]1b478ba2014-07-31 12:51:43190 // Compute the set of capabilities supported by both client and host.
dcheng0765c492016-04-06 22:41:53191 client_capabilities_ = base::WrapUnique(new std::string());
[email protected]a5d181f2013-04-19 14:55:37192 if (capabilities.has_capabilities())
193 *client_capabilities_ = capabilities.capabilities();
[email protected]1b478ba2014-07-31 12:51:43194 capabilities_ = IntersectCapabilities(*client_capabilities_,
195 host_capabilities_);
196 extension_manager_->OnNegotiatedCapabilities(
197 connection_->client_stub(), capabilities_);
[email protected]a5d181f2013-04-19 14:55:37198
199 VLOG(1) << "Client capabilities: " << *client_capabilities_;
200
201 // Calculate the set of capabilities enabled by both client and host and
202 // pass it to the desktop environment if it is available.
[email protected]1b478ba2014-07-31 12:51:43203 desktop_environment_->SetCapabilities(capabilities_);
[email protected]a5d181f2013-04-19 14:55:37204}
205
[email protected]88356922013-06-04 06:26:01206void ClientSession::RequestPairing(
207 const protocol::PairingRequest& pairing_request) {
dchengac10e4a82014-08-26 03:53:44208 if (pairing_registry_.get() && pairing_request.has_client_name()) {
[email protected]88356922013-06-04 06:26:01209 protocol::PairingRegistry::Pairing pairing =
210 pairing_registry_->CreatePairing(pairing_request.client_name());
211 protocol::PairingResponse pairing_response;
[email protected]df5189f2013-06-18 12:12:05212 pairing_response.set_client_id(pairing.client_id());
213 pairing_response.set_shared_secret(pairing.shared_secret());
[email protected]88356922013-06-04 06:26:01214 connection_->client_stub()->SetPairingResponse(pairing_response);
215 }
216}
217
[email protected]09eabd65c2013-08-13 00:13:48218void ClientSession::DeliverClientMessage(
219 const protocol::ExtensionMessage& message) {
[email protected]af278c42013-09-02 05:27:00220 if (message.has_type()) {
221 if (message.type() == "test-echo") {
222 protocol::ExtensionMessage reply;
223 reply.set_type("test-echo-reply");
224 if (message.has_data())
225 reply.set_data(message.data().substr(0, 16));
226 connection_->client_stub()->DeliverHostMessage(reply);
227 return;
[email protected]399b4f62014-05-30 20:13:15228 } else {
wez73f19de2014-10-29 19:06:33229 if (extension_manager_->OnExtensionMessage(message))
wez87036992014-09-05 00:53:43230 return;
231
232 DLOG(INFO) << "Unexpected message received: "
233 << message.type() << ": " << message.data();
[email protected]af278c42013-09-02 05:27:00234 }
235 }
[email protected]09eabd65c2013-08-13 00:13:48236}
237
[email protected]064128c2014-04-07 22:33:28238void ClientSession::OnConnectionAuthenticating(
239 protocol::ConnectionToClient* connection) {
240 event_handler_->OnSessionAuthenticating(this);
241}
242
[email protected]cba6f812012-03-27 01:01:50243void ClientSession::OnConnectionAuthenticated(
[email protected]ee910fd2011-11-10 18:23:31244 protocol::ConnectionToClient* connection) {
[email protected]86cbe6b2012-04-03 00:56:18245 DCHECK(CalledOnValidThread());
246 DCHECK_EQ(connection_.get(), connection);
sergeyu7bc87602015-02-13 20:33:28247 DCHECK(!audio_pump_);
[email protected]a5d181f2013-04-19 14:55:37248 DCHECK(!desktop_environment_);
[email protected]324b1962013-05-01 19:30:22249 DCHECK(!input_injector_);
250 DCHECK(!screen_controls_);
sergeyua609b7a2015-11-30 06:25:39251 DCHECK(!video_stream_);
[email protected]34df2ab2012-08-19 06:54:23252
sergeyu1f8cd502015-02-13 21:45:53253 is_authenticated_ = true;
[email protected]34df2ab2012-08-19 06:54:23254
[email protected]5dc5b12a2012-06-23 01:05:14255 if (max_duration_ > base::TimeDelta()) {
sergeyuec77d8542015-11-03 22:31:00256 max_duration_timer_.Start(
257 FROM_HERE, max_duration_,
258 base::Bind(&ClientSession::DisconnectSession, base::Unretained(this),
259 protocol::MAX_SESSION_LENGTH));
[email protected]5dc5b12a2012-06-23 01:05:14260 }
[email protected]34df2ab2012-08-19 06:54:23261
sergeyu21c899e2015-11-24 16:39:55262 // Notify EventHandler.
263 event_handler_->OnSessionAuthenticated(this);
[email protected]ce404ca2013-01-16 17:23:53264
[email protected]96361d02013-05-08 18:26:18265 // Create the desktop environment. Drop the connection if it could not be
266 // created for any reason (for instance the curtain could not initialize).
[email protected]231316a2013-03-25 06:01:12267 desktop_environment_ =
kulkarni.a933aeaf2014-09-20 13:19:17268 desktop_environment_factory_->Create(weak_factory_.GetWeakPtr());
[email protected]96361d02013-05-08 18:26:18269 if (!desktop_environment_) {
sergeyuec77d8542015-11-03 22:31:00270 DisconnectSession(protocol::HOST_CONFIGURATION_ERROR);
[email protected]96361d02013-05-08 18:26:18271 return;
272 }
273
sergeyu1f8cd502015-02-13 21:45:53274 // Connect host stub.
275 connection_->set_host_stub(this);
276
[email protected]1b478ba2014-07-31 12:51:43277 // Collate the set of capabilities to offer the client, if it supports them.
sergeyuf69b019f2014-09-13 20:41:02278 host_capabilities_ = desktop_environment_->GetCapabilities();
279 if (!host_capabilities_.empty())
280 host_capabilities_.append(" ");
281 host_capabilities_.append(extension_manager_->GetCapabilities());
[email protected]233bb942013-03-15 07:18:17282
[email protected]231316a2013-03-25 06:01:12283 // Create the object that controls the screen resolution.
284 screen_controls_ = desktop_environment_->CreateScreenControls();
[email protected]61cfdc52013-03-09 03:04:56285
[email protected]324b1962013-05-01 19:30:22286 // Create the event executor.
[email protected]231316a2013-03-25 06:01:12287 input_injector_ = desktop_environment_->CreateInputInjector();
[email protected]eccc2d42013-01-10 19:35:14288
sergeyu1f8cd502015-02-13 21:45:53289 // Connect the host input stubs.
290 connection_->set_input_stub(&disable_input_filter_);
[email protected]b0b72f112013-03-24 03:42:42291 host_input_filter_.set_input_stub(input_injector_.get());
sergeyu1f8cd502015-02-13 21:45:53292
293 // Connect the clipboard stubs.
294 connection_->set_clipboard_stub(&disable_clipboard_filter_);
[email protected]b0b72f112013-03-24 03:42:42295 clipboard_echo_filter_.set_host_stub(input_injector_.get());
sergeyu1f8cd502015-02-13 21:45:53296 clipboard_echo_filter_.set_client_stub(connection_->client_stub());
[email protected]324b1962013-05-01 19:30:22297}
298
299void ClientSession::OnConnectionChannelsConnected(
300 protocol::ConnectionToClient* connection) {
301 DCHECK(CalledOnValidThread());
302 DCHECK_EQ(connection_.get(), connection);
303
304 // Negotiate capabilities with the client.
sergeyuf69b019f2014-09-13 20:41:02305 VLOG(1) << "Host capabilities: " << host_capabilities_;
sergeyuf69b019f2014-09-13 20:41:02306 protocol::Capabilities capabilities;
307 capabilities.set_capabilities(host_capabilities_);
308 connection_->client_stub()->SetCapabilities(capabilities);
[email protected]324b1962013-05-01 19:30:22309
310 // Start the event executor.
311 input_injector_->Start(CreateClipboardProxy());
312 SetDisableInputs(false);
313
sergeyu6ad12dc2016-04-02 00:01:32314 // Create MouseShapePump to send mouse cursor shape.
315 mouse_shape_pump_.reset(
316 new MouseShapePump(desktop_environment_->CreateMouseCursorMonitor(),
317 connection_->client_stub()));
318
319 // Create a VideoStream to pump frames from the capturer to the client.
320 video_stream_ = connection_->StartVideoStream(
321 desktop_environment_->CreateVideoCapturer());
322
323 video_stream_->SetSizeCallback(
324 base::Bind(&ClientSession::OnScreenSizeChanged, base::Unretained(this)));
325
326 // Apply video-control parameters to the new stream.
327 video_stream_->SetLosslessEncode(lossless_video_encode_);
328 video_stream_->SetLosslessColor(lossless_video_color_);
329
330 // Pause capturing if necessary.
331 video_stream_->Pause(pause_video_);
[email protected]324b1962013-05-01 19:30:22332
sergeyu7bc87602015-02-13 20:33:28333 // Create an AudioPump if audio is enabled, to pump audio samples.
334 if (connection_->session()->config().is_audio_enabled()) {
dcheng0765c492016-04-06 22:41:53335 std::unique_ptr<AudioEncoder> audio_encoder =
sergeyu7bc87602015-02-13 20:33:28336 CreateAudioEncoder(connection_->session()->config());
337 audio_pump_.reset(new AudioPump(
338 audio_task_runner_, desktop_environment_->CreateAudioCapturer(),
sergeyu1417e0132015-12-23 19:01:22339 std::move(audio_encoder), connection_->audio_stub()));
sergeyu7bc87602015-02-13 20:33:28340 }
[email protected]170cba42012-09-12 22:28:39341
[email protected]cdd1c9e2012-10-26 21:14:04342 // Notify the event handler that all our channels are now connected.
[email protected]cba6f812012-03-27 01:01:50343 event_handler_->OnSessionChannelsConnected(this);
[email protected]ee910fd2011-11-10 18:23:31344}
345
[email protected]cba6f812012-03-27 01:01:50346void ClientSession::OnConnectionClosed(
[email protected]1f249e22011-11-29 20:19:59347 protocol::ConnectionToClient* connection,
[email protected]204a9e32012-03-02 05:42:58348 protocol::ErrorCode error) {
[email protected]ec6411872011-11-11 03:28:55349 DCHECK(CalledOnValidThread());
[email protected]ee910fd2011-11-10 18:23:31350 DCHECK_EQ(connection_.get(), connection);
[email protected]750ae6b2012-08-20 22:52:40351
lukaszaf34d8412015-04-30 23:09:59352 HOST_LOG << "Client disconnected: " << client_jid_ << "; error = " << error;
353
[email protected]231316a2013-03-25 06:01:12354 // Ignore any further callbacks.
kulkarni.a933aeaf2014-09-20 13:19:17355 weak_factory_.InvalidateWeakPtrs();
[email protected]a031c972012-12-27 20:10:40356
[email protected]24a2a9d22012-12-07 09:06:47357 // If the client never authenticated then the session failed.
sergeyu1f8cd502015-02-13 21:45:53358 if (!is_authenticated_)
[email protected]1f249e22011-11-29 20:19:59359 event_handler_->OnSessionAuthenticationFailed(this);
[email protected]750ae6b2012-08-20 22:52:40360
[email protected]86cbe6b2012-04-03 00:56:18361 // Ensure that any pressed keys or buttons are released.
362 input_tracker_.ReleaseAll();
363
[email protected]24a2a9d22012-12-07 09:06:47364 // Stop components access the client, audio or video stubs, which are no
365 // longer valid once ConnectionToClient calls OnConnectionClosed().
sergeyu7bc87602015-02-13 20:33:28366 audio_pump_.reset();
sergeyua609b7a2015-11-30 06:25:39367 video_stream_.reset();
sergeyu1afb35a12015-02-13 18:45:30368 mouse_shape_pump_.reset();
[email protected]24a2a9d22012-12-07 09:06:47369 client_clipboard_factory_.InvalidateWeakPtrs();
[email protected]b0b72f112013-03-24 03:42:42370 input_injector_.reset();
[email protected]231316a2013-03-25 06:01:12371 screen_controls_.reset();
372 desktop_environment_.reset();
[email protected]24a2a9d22012-12-07 09:06:47373
374 // Notify the ChromotingHost that this client is disconnected.
[email protected]ee910fd2011-11-10 18:23:31375 event_handler_->OnSessionClosed(this);
[email protected]ee910fd2011-11-10 18:23:31376}
377
sergeyu752c6e62015-09-30 06:40:27378void ClientSession::OnInputEventReceived(
379 protocol::ConnectionToClient* connection,
380 int64_t event_timestamp) {
[email protected]ec6411872011-11-11 03:28:55381 DCHECK(CalledOnValidThread());
[email protected]ee910fd2011-11-10 18:23:31382 DCHECK_EQ(connection_.get(), connection);
[email protected]170cba42012-09-12 22:28:39383
sergeyua609b7a2015-11-30 06:25:39384 if (video_stream_.get())
385 video_stream_->OnInputEventReceived(event_timestamp);
[email protected]ee910fd2011-11-10 18:23:31386}
387
[email protected]17af2ab2012-02-02 04:07:52388void ClientSession::OnRouteChange(
389 protocol::ConnectionToClient* connection,
390 const std::string& channel_name,
[email protected]be451c82012-03-20 22:24:47391 const protocol::TransportRoute& route) {
[email protected]91e4b7f62012-01-25 23:23:02392 DCHECK(CalledOnValidThread());
393 DCHECK_EQ(connection_.get(), connection);
[email protected]be451c82012-03-20 22:24:47394 event_handler_->OnSessionRouteChange(this, channel_name, route);
[email protected]91e4b7f62012-01-25 23:23:02395}
396
[email protected]231316a2013-03-25 06:01:12397const std::string& ClientSession::client_jid() const {
398 return client_jid_;
399}
400
sergeyuec77d8542015-11-03 22:31:00401void ClientSession::DisconnectSession(protocol::ErrorCode error) {
[email protected]ec6411872011-11-11 03:28:55402 DCHECK(CalledOnValidThread());
403 DCHECK(connection_.get());
[email protected]a46bcef2011-11-11 01:27:23404
[email protected]5dc5b12a2012-06-23 01:05:14405 max_duration_timer_.Stop();
[email protected]24a2a9d22012-12-07 09:06:47406
[email protected]86cbe6b2012-04-03 00:56:18407 // This triggers OnConnectionClosed(), and the session may be destroyed
[email protected]a46bcef2011-11-11 01:27:23408 // as the result, so this call must be the last in this method.
sergeyuec77d8542015-11-03 22:31:00409 connection_->Disconnect(error);
[email protected]44f60762011-03-23 12:13:35410}
411
[email protected]8c83a71c2013-12-16 18:02:58412void ClientSession::OnLocalMouseMoved(const webrtc::DesktopVector& position) {
[email protected]ec6411872011-11-11 03:28:55413 DCHECK(CalledOnValidThread());
[email protected]231316a2013-03-25 06:01:12414 remote_input_filter_.LocalMouseMoved(position);
[email protected]86cbe6b2012-04-03 00:56:18415}
[email protected]ec6411872011-11-11 03:28:55416
[email protected]86cbe6b2012-04-03 00:56:18417void ClientSession::SetDisableInputs(bool disable_inputs) {
418 DCHECK(CalledOnValidThread());
419
[email protected]750ae6b2012-08-20 22:52:40420 if (disable_inputs)
[email protected]86cbe6b2012-04-03 00:56:18421 input_tracker_.ReleaseAll();
[email protected]750ae6b2012-08-20 22:52:40422
423 disable_input_filter_.set_enabled(!disable_inputs);
424 disable_clipboard_filter_.set_enabled(!disable_inputs);
[email protected]c78669c92011-06-13 22:42:38425}
426
dcheng0765c492016-04-06 22:41:53427std::unique_ptr<protocol::ClipboardStub> ClientSession::CreateClipboardProxy() {
[email protected]7f44ba42012-05-31 20:26:29428 DCHECK(CalledOnValidThread());
429
dcheng0765c492016-04-06 22:41:53430 return base::WrapUnique(
sergeyu2d690882014-10-01 02:36:43431 new protocol::ClipboardThreadProxy(client_clipboard_factory_.GetWeakPtr(),
anujk.sharmabb802932015-05-05 21:57:29432 base::ThreadTaskRunnerHandle::Get()));
[email protected]7f44ba42012-05-31 20:26:29433}
434
sergeyu00a67b12016-04-01 00:07:00435void ClientSession::OnScreenSizeChanged(const webrtc::DesktopSize& size,
436 const webrtc::DesktopVector& dpi) {
sergeyua609b7a2015-11-30 06:25:39437 DCHECK(CalledOnValidThread());
sergeyu00a67b12016-04-01 00:07:00438
sergeyua609b7a2015-11-30 06:25:39439 mouse_clamping_filter_.set_input_size(size);
440 mouse_clamping_filter_.set_output_size(size);
sergeyu00a67b12016-04-01 00:07:00441
442 if (connection_->session()->config().protocol() ==
443 protocol::SessionConfig::Protocol::WEBRTC) {
444 protocol::VideoLayout layout;
445 protocol::VideoTrackLayout* video_track = layout.add_video_track();
446 video_track->set_position_x(0);
447 video_track->set_position_y(0);
448 video_track->set_width(size.width() * kDefaultDpi / dpi.x());
449 video_track->set_height(size.height() * kDefaultDpi / dpi.y());
450 video_track->set_x_dpi(dpi.x());
451 video_track->set_y_dpi(dpi.y());
452 connection_->client_stub()->SetVideoLayout(layout);
453 }
sergeyua609b7a2015-11-30 06:25:39454}
455
[email protected]44f60762011-03-23 12:13:35456} // namespace remoting