blob: 45c4bd32e6c5ec22f73e2062219d9eaa619cba77 [file] [log] [blame]
Avi Drissmand6cdf9b2022-09-15 19:52:531// Copyright 2012 The Chromium Authors
[email protected]da457fc2013-03-14 16:32:122// 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/me2me_desktop_environment.h"
6
Peter Boström42afa23f2021-04-02 22:10:467#include <memory>
sergeyu1417e0132015-12-23 19:01:228#include <utility>
9
[email protected]da457fc2013-03-14 16:32:1210#include "base/logging.h"
dcheng0765c492016-04-06 22:41:5311#include "base/memory/ptr_util.h"
Patrick Monette643cdf62021-10-15 19:13:4212#include "base/task/single_thread_task_runner.h"
avic5960f32015-12-22 22:49:4813#include "build/build_config.h"
[email protected]3a5b82c2014-02-20 13:28:1414#include "remoting/base/logging.h"
Joe Downing505ae0d02018-10-17 17:47:3015#include "remoting/host/action_executor.h"
Joe Downingb0fb5422021-12-07 21:26:2016#include "remoting/host/base/screen_controls.h"
[email protected]231316a2013-03-25 06:01:1217#include "remoting/host/client_session_control.h"
[email protected]96361d02013-05-08 18:26:1818#include "remoting/host/curtain_mode.h"
[email protected]da457fc2013-03-14 16:32:1219#include "remoting/host/desktop_resizer.h"
[email protected]c308f5122013-04-05 03:32:0620#include "remoting/host/host_window.h"
[email protected]ac115ce2013-04-24 20:44:3821#include "remoting/host/host_window_proxy.h"
sergeyub3e637e2016-10-27 23:31:2122#include "remoting/host/input_injector.h"
Joe Downing4dfb3892018-08-24 18:56:0623#include "remoting/host/input_monitor/local_input_monitor.h"
Yuwei Huang6df36ef2021-09-15 18:48:0624#include "remoting/host/remote_open_url/remote_open_url_util.h"
[email protected]da457fc2013-03-14 16:32:1225#include "remoting/host/resizing_host_observer.h"
rkuroiwaa7815e72015-06-05 21:39:0426#include "remoting/protocol/capability_names.h"
[email protected]cd8088052013-10-15 02:39:0227#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
zijiehea69c7842016-11-11 01:28:2028#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
[email protected]ac115ce2013-04-24 20:44:3829
Xiaohan Wang453b38672022-01-13 20:02:4430#if BUILDFLAG(IS_POSIX)
[email protected]ac115ce2013-04-24 20:44:3831#include <sys/types.h>
32#include <unistd.h>
Xiaohan Wang453b38672022-01-13 20:02:4433#endif // BUILDFLAG(IS_POSIX)
[email protected]da457fc2013-03-14 16:32:1234
Xiaohan Wang453b38672022-01-13 20:02:4435#if BUILDFLAG(IS_WIN)
Joe Downingb511e4a92018-11-16 21:10:1336#include "base/win/windows_version.h"
Xiaohan Wang453b38672022-01-13 20:02:4437#endif // BUILDFLAG(IS_WIN)
Joe Downingb511e4a92018-11-16 21:10:1338
[email protected]da457fc2013-03-14 16:32:1239namespace remoting {
40
41Me2MeDesktopEnvironment::~Me2MeDesktopEnvironment() {
[email protected]231316a2013-03-25 06:01:1242 DCHECK(caller_task_runner()->BelongsToCurrentThread());
[email protected]da457fc2013-03-14 16:32:1243}
44
Joe Downing505ae0d02018-10-17 17:47:3045std::unique_ptr<ActionExecutor>
46Me2MeDesktopEnvironment::CreateActionExecutor() {
47 DCHECK(caller_task_runner()->BelongsToCurrentThread());
48
49 return ActionExecutor::Create();
50}
51
dcheng0765c492016-04-06 22:41:5352std::unique_ptr<ScreenControls>
53Me2MeDesktopEnvironment::CreateScreenControls() {
[email protected]231316a2013-03-25 06:01:1254 DCHECK(caller_task_runner()->BelongsToCurrentThread());
[email protected]da457fc2013-03-14 16:32:1255
rkjnsn5d5d89b92016-06-07 21:34:2156 // We only want to restore the host resolution on disconnect if we are not
57 // curtained so we don't mess up the user's window layout unnecessarily if
58 // they disconnect and reconnect. Both OS X and Windows will restore the
59 // resolution automatically when the user logs back in on the console, and on
60 // Linux the curtain-mode uses a separate session.
Lambros Lambroud27736d2022-06-16 00:52:2761 auto resizer = std::make_unique<ResizingHostObserver>(
62 DesktopResizer::Create(), curtain_ == nullptr);
63 resizer->RegisterForDisplayChanges(*GetDisplayInfoMonitor());
64 return resizer;
[email protected]da457fc2013-03-14 16:32:1265}
66
[email protected]4a444c42013-06-09 01:43:1467std::string Me2MeDesktopEnvironment::GetCapabilities() const {
Lambros Lambrouf9a02aaf2022-03-29 00:39:4268 std::string capabilities = BasicDesktopEnvironment::GetCapabilities();
69 if (!capabilities.empty()) {
70 capabilities += " ";
71 }
sergeyub3e637e2016-10-27 23:31:2172 capabilities += protocol::kRateLimitResizeRequests;
Lambros Lambrou4c46dcb02020-07-22 18:14:5473
sergeyub3e637e2016-10-27 23:31:2174 if (InputInjector::SupportsTouchEvents()) {
75 capabilities += " ";
76 capabilities += protocol::kTouchEventsCapability;
77 }
Joseph Arhare76c3042017-08-03 02:01:1378
Joseph Arhar111ddceb2017-09-01 04:57:3079 if (desktop_environment_options().enable_file_transfer()) {
80 capabilities += " ";
81 capabilities += protocol::kFileTransferCapability;
82 }
Joseph Arhare76c3042017-08-03 02:01:1383
Xiaohan Wang453b38672022-01-13 20:02:4484#if BUILDFLAG(IS_WIN)
Joe Downingb511e4a92018-11-16 21:10:1385 capabilities += " ";
86 capabilities += protocol::kSendAttentionSequenceAction;
87
88 if (base::win::OSInfo::GetInstance()->version_type() !=
89 base::win::VersionType::SUITE_HOME) {
90 capabilities += " ";
91 capabilities += protocol::kLockWorkstationAction;
92 }
Xiaohan Wang453b38672022-01-13 20:02:4493#endif // BUILDFLAG(IS_WIN)
Joe Downingb511e4a92018-11-16 21:10:1394
Yuwei Huangc31b4d72021-09-13 23:04:4995 if (desktop_environment_options().enable_remote_open_url() &&
96 IsRemoteOpenUrlSupported()) {
Yuwei Huangc49279792021-07-22 23:31:4897 capabilities += " ";
98 capabilities += protocol::kRemoteOpenUrlCapability;
99 }
Yuwei Huang9d0cb6dc2021-05-10 21:04:51100
Yuwei Huang78b3fc52021-10-20 21:03:24101 if (desktop_environment_options().enable_remote_webauthn()) {
102 capabilities += " ";
103 capabilities += protocol::kRemoteWebAuthnCapability;
104 }
105
Lambros Lambroufc279d82022-09-21 18:37:39106#if BUILDFLAG(IS_LINUX)
107 capabilities += " ";
108 capabilities += protocol::kMultiStreamCapability;
109#if defined(REMOTING_USE_X11)
110 capabilities += " ";
111 capabilities += protocol::kClientControlledLayoutCapability;
112#endif // defined(REMOTING_USE_X11)
113#endif // BUILDFLAG(IS_LINUX)
114
rkuroiwaa7815e72015-06-05 21:39:04115 return capabilities;
[email protected]4a444c42013-06-09 01:43:14116}
117
[email protected]231316a2013-03-25 06:01:12118Me2MeDesktopEnvironment::Me2MeDesktopEnvironment(
119 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
sergeyu85df3c482016-02-15 05:59:08120 scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner,
[email protected]231316a2013-03-25 06:01:12121 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
zijiehe4aa6ea42016-11-12 01:28:16122 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
Gary Kacmarcika7e33e42019-02-22 19:23:28123 base::WeakPtr<ClientSessionControl> client_session_control,
zijiehe4aa6ea42016-11-12 01:28:16124 const DesktopEnvironmentOptions& options)
[email protected]231316a2013-03-25 06:01:12125 : BasicDesktopEnvironment(caller_task_runner,
sergeyu85df3c482016-02-15 05:59:08126 video_capture_task_runner,
[email protected]231316a2013-03-25 06:01:12127 input_task_runner,
zijiehe4aa6ea42016-11-12 01:28:16128 ui_task_runner,
Gary Kacmarcika7e33e42019-02-22 19:23:28129 client_session_control,
zijiehe4aa6ea42016-11-12 01:28:16130 options) {
[email protected]231316a2013-03-25 06:01:12131 DCHECK(caller_task_runner->BelongsToCurrentThread());
sergeyu85df3c482016-02-15 05:59:08132
zijiehe4aa6ea42016-11-12 01:28:16133 // TODO(zijiehe): This logic should belong to RemotingMe2MeHost, instead of
134 // Me2MeDesktopEnvironment, which does not take response to create a new
135 // session.
sergeyu85df3c482016-02-15 05:59:08136 // X DAMAGE is not enabled by default, since it is broken on many systems -
137 // see http://crbug.com/73423. It's safe to enable it here because it works
138 // properly under Xvfb.
zijiehe4aa6ea42016-11-12 01:28:16139 mutable_desktop_capture_options()->set_use_update_notifications(true);
[email protected]96361d02013-05-08 18:26:18140}
141
142bool Me2MeDesktopEnvironment::InitializeSecurity(
zijiehe4aa6ea42016-11-12 01:28:16143 base::WeakPtr<ClientSessionControl> client_session_control) {
[email protected]96361d02013-05-08 18:26:18144 DCHECK(caller_task_runner()->BelongsToCurrentThread());
145
146 // Detach the session from the local console if the caller requested.
zijiehe4aa6ea42016-11-12 01:28:16147 if (desktop_environment_options().enable_curtaining()) {
148 curtain_ = CurtainMode::Create(
149 caller_task_runner(), ui_task_runner(), client_session_control);
rkjnsn5d5d89b92016-06-07 21:34:21150 if (!curtain_->Activate()) {
[email protected]04eca612013-05-15 04:02:25151 LOG(ERROR) << "Failed to activate the curtain mode.";
rkjnsn5d5d89b92016-06-07 21:34:21152 curtain_ = nullptr;
153 return false;
154 }
155 return true;
[email protected]96361d02013-05-08 18:26:18156 }
157
158 // Otherwise, if the session is shared with the local user start monitoring
159 // the local input and create the in-session UI.
Xiaohan Wang453b38672022-01-13 20:02:44160#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
[email protected]04eca612013-05-15 04:02:25161 bool want_user_interface = false;
Xiaohan Wang453b38672022-01-13 20:02:44162#elif BUILDFLAG(IS_APPLE)
[email protected]ac115ce2013-04-24 20:44:38163 // Don't try to display any UI on top of the system's login screen as this
164 // is rejected by the Window Server on OS X 10.7.4, and prevents the
165 // capturer from working (http://crbug.com/140984).
166
167 // TODO(lambroslambrou): Use a better technique of detecting whether we're
168 // running in the LoginWindow context, and refactor this into a separate
169 // function to be used here and in CurtainMode::ActivateCurtain().
[email protected]04eca612013-05-15 04:02:25170 bool want_user_interface = getuid() != 0;
lambroslambrou51e19b92016-04-13 21:30:41171#else
zijiehe4aa6ea42016-11-12 01:28:16172 bool want_user_interface =
173 desktop_environment_options().enable_user_interface();
lambroslambrou51e19b92016-04-13 21:30:41174#endif
[email protected]ac115ce2013-04-24 20:44:38175
[email protected]ac115ce2013-04-24 20:44:38176 if (want_user_interface) {
[email protected]04eca612013-05-15 04:02:25177 // Create the local input monitor.
zijiehe4aa6ea42016-11-12 01:28:16178 local_input_monitor_ = LocalInputMonitor::Create(
Joe Downingf86c8a012018-08-29 16:49:04179 caller_task_runner(), input_task_runner(), ui_task_runner());
180 local_input_monitor_->StartMonitoringForClientSession(
zijiehe4aa6ea42016-11-12 01:28:16181 client_session_control);
[email protected]04eca612013-05-15 04:02:25182
Joe Downingf86c8a012018-08-29 16:49:04183 // Create the disconnect window.
Xiaohan Wang453b38672022-01-13 20:02:44184#if BUILDFLAG(IS_WIN)
Joe Downing8e95ed182018-08-30 22:57:19185 disconnect_window_ =
186 HostWindow::CreateAutoHidingDisconnectWindow(LocalInputMonitor::Create(
187 caller_task_runner(), input_task_runner(), ui_task_runner()));
188#else
[email protected]fc877cf2013-07-31 23:08:39189 disconnect_window_ = HostWindow::CreateDisconnectWindow();
Joe Downing8e95ed182018-08-30 22:57:19190#endif
Peter Boström42afa23f2021-04-02 22:10:46191 disconnect_window_ = std::make_unique<HostWindowProxy>(
192 caller_task_runner(), ui_task_runner(), std::move(disconnect_window_));
[email protected]ac115ce2013-04-24 20:44:38193 disconnect_window_->Start(client_session_control);
194 }
[email protected]96361d02013-05-08 18:26:18195
196 return true;
[email protected]da457fc2013-03-14 16:32:12197}
198
[email protected]231316a2013-03-25 06:01:12199Me2MeDesktopEnvironmentFactory::Me2MeDesktopEnvironmentFactory(
200 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
sergeyu85df3c482016-02-15 05:59:08201 scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner,
[email protected]231316a2013-03-25 06:01:12202 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
Scott Violet9778dcd2019-06-20 21:59:37203 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner)
[email protected]231316a2013-03-25 06:01:12204 : BasicDesktopEnvironmentFactory(caller_task_runner,
sergeyu85df3c482016-02-15 05:59:08205 video_capture_task_runner,
[email protected]231316a2013-03-25 06:01:12206 input_task_runner,
Scott Violet9778dcd2019-06-20 21:59:37207 ui_task_runner) {}
[email protected]da457fc2013-03-14 16:32:12208
209Me2MeDesktopEnvironmentFactory::~Me2MeDesktopEnvironmentFactory() {
210}
211
dcheng0765c492016-04-06 22:41:53212std::unique_ptr<DesktopEnvironment> Me2MeDesktopEnvironmentFactory::Create(
zijiehe4aa6ea42016-11-12 01:28:16213 base::WeakPtr<ClientSessionControl> client_session_control,
Yuwei Huang3628aa52021-12-08 23:00:55214 base::WeakPtr<ClientSessionEvents> client_session_events,
zijiehe4aa6ea42016-11-12 01:28:16215 const DesktopEnvironmentOptions& options) {
[email protected]231316a2013-03-25 06:01:12216 DCHECK(caller_task_runner()->BelongsToCurrentThread());
217
dcheng0765c492016-04-06 22:41:53218 std::unique_ptr<Me2MeDesktopEnvironment> desktop_environment(
Scott Violet9778dcd2019-06-20 21:59:37219 new Me2MeDesktopEnvironment(caller_task_runner(),
220 video_capture_task_runner(),
221 input_task_runner(), ui_task_runner(),
222 client_session_control, options));
zijiehe4aa6ea42016-11-12 01:28:16223 if (!desktop_environment->InitializeSecurity(client_session_control)) {
sergeyuafce9782014-09-29 19:38:30224 return nullptr;
[email protected]96361d02013-05-08 18:26:18225 }
226
Jeroen Dhollandera3ce38f2022-08-25 07:18:02227 return desktop_environment;
[email protected]96361d02013-05-08 18:26:18228}
229
[email protected]da457fc2013-03-14 16:32:12230} // namespace remoting