Avi Drissman | d6cdf9b | 2022-09-15 19:52:53 | [diff] [blame] | 1 | // Copyright 2012 The Chromium Authors |
[email protected] | da457fc | 2013-03-14 16:32:12 | [diff] [blame] | 2 | // 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öm | 42afa23f | 2021-04-02 22:10:46 | [diff] [blame] | 7 | #include <memory> |
sergeyu | 1417e013 | 2015-12-23 19:01:22 | [diff] [blame] | 8 | #include <utility> |
| 9 | |
[email protected] | da457fc | 2013-03-14 16:32:12 | [diff] [blame] | 10 | #include "base/logging.h" |
dcheng | 0765c49 | 2016-04-06 22:41:53 | [diff] [blame] | 11 | #include "base/memory/ptr_util.h" |
Patrick Monette | 643cdf6 | 2021-10-15 19:13:42 | [diff] [blame] | 12 | #include "base/task/single_thread_task_runner.h" |
avi | c5960f3 | 2015-12-22 22:49:48 | [diff] [blame] | 13 | #include "build/build_config.h" |
[email protected] | 3a5b82c | 2014-02-20 13:28:14 | [diff] [blame] | 14 | #include "remoting/base/logging.h" |
Joe Downing | 505ae0d0 | 2018-10-17 17:47:30 | [diff] [blame] | 15 | #include "remoting/host/action_executor.h" |
Joe Downing | b0fb542 | 2021-12-07 21:26:20 | [diff] [blame] | 16 | #include "remoting/host/base/screen_controls.h" |
[email protected] | 231316a | 2013-03-25 06:01:12 | [diff] [blame] | 17 | #include "remoting/host/client_session_control.h" |
[email protected] | 96361d0 | 2013-05-08 18:26:18 | [diff] [blame] | 18 | #include "remoting/host/curtain_mode.h" |
[email protected] | da457fc | 2013-03-14 16:32:12 | [diff] [blame] | 19 | #include "remoting/host/desktop_resizer.h" |
[email protected] | c308f512 | 2013-04-05 03:32:06 | [diff] [blame] | 20 | #include "remoting/host/host_window.h" |
[email protected] | ac115ce | 2013-04-24 20:44:38 | [diff] [blame] | 21 | #include "remoting/host/host_window_proxy.h" |
sergeyu | b3e637e | 2016-10-27 23:31:21 | [diff] [blame] | 22 | #include "remoting/host/input_injector.h" |
Joe Downing | 4dfb389 | 2018-08-24 18:56:06 | [diff] [blame] | 23 | #include "remoting/host/input_monitor/local_input_monitor.h" |
Yuwei Huang | 6df36ef | 2021-09-15 18:48:06 | [diff] [blame] | 24 | #include "remoting/host/remote_open_url/remote_open_url_util.h" |
[email protected] | da457fc | 2013-03-14 16:32:12 | [diff] [blame] | 25 | #include "remoting/host/resizing_host_observer.h" |
rkuroiwa | a7815e7 | 2015-06-05 21:39:04 | [diff] [blame] | 26 | #include "remoting/protocol/capability_names.h" |
[email protected] | cd808805 | 2013-10-15 02:39:02 | [diff] [blame] | 27 | #include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h" |
zijiehe | a69c784 | 2016-11-11 01:28:20 | [diff] [blame] | 28 | #include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h" |
[email protected] | ac115ce | 2013-04-24 20:44:38 | [diff] [blame] | 29 | |
Xiaohan Wang | 453b3867 | 2022-01-13 20:02:44 | [diff] [blame] | 30 | #if BUILDFLAG(IS_POSIX) |
[email protected] | ac115ce | 2013-04-24 20:44:38 | [diff] [blame] | 31 | #include <sys/types.h> |
| 32 | #include <unistd.h> |
Xiaohan Wang | 453b3867 | 2022-01-13 20:02:44 | [diff] [blame] | 33 | #endif // BUILDFLAG(IS_POSIX) |
[email protected] | da457fc | 2013-03-14 16:32:12 | [diff] [blame] | 34 | |
Xiaohan Wang | 453b3867 | 2022-01-13 20:02:44 | [diff] [blame] | 35 | #if BUILDFLAG(IS_WIN) |
Joe Downing | b511e4a9 | 2018-11-16 21:10:13 | [diff] [blame] | 36 | #include "base/win/windows_version.h" |
Xiaohan Wang | 453b3867 | 2022-01-13 20:02:44 | [diff] [blame] | 37 | #endif // BUILDFLAG(IS_WIN) |
Joe Downing | b511e4a9 | 2018-11-16 21:10:13 | [diff] [blame] | 38 | |
[email protected] | da457fc | 2013-03-14 16:32:12 | [diff] [blame] | 39 | namespace remoting { |
| 40 | |
| 41 | Me2MeDesktopEnvironment::~Me2MeDesktopEnvironment() { |
[email protected] | 231316a | 2013-03-25 06:01:12 | [diff] [blame] | 42 | DCHECK(caller_task_runner()->BelongsToCurrentThread()); |
[email protected] | da457fc | 2013-03-14 16:32:12 | [diff] [blame] | 43 | } |
| 44 | |
Joe Downing | 505ae0d0 | 2018-10-17 17:47:30 | [diff] [blame] | 45 | std::unique_ptr<ActionExecutor> |
| 46 | Me2MeDesktopEnvironment::CreateActionExecutor() { |
| 47 | DCHECK(caller_task_runner()->BelongsToCurrentThread()); |
| 48 | |
| 49 | return ActionExecutor::Create(); |
| 50 | } |
| 51 | |
dcheng | 0765c49 | 2016-04-06 22:41:53 | [diff] [blame] | 52 | std::unique_ptr<ScreenControls> |
| 53 | Me2MeDesktopEnvironment::CreateScreenControls() { |
[email protected] | 231316a | 2013-03-25 06:01:12 | [diff] [blame] | 54 | DCHECK(caller_task_runner()->BelongsToCurrentThread()); |
[email protected] | da457fc | 2013-03-14 16:32:12 | [diff] [blame] | 55 | |
rkjnsn | 5d5d89b9 | 2016-06-07 21:34:21 | [diff] [blame] | 56 | // 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 Lambrou | d27736d | 2022-06-16 00:52:27 | [diff] [blame] | 61 | auto resizer = std::make_unique<ResizingHostObserver>( |
| 62 | DesktopResizer::Create(), curtain_ == nullptr); |
| 63 | resizer->RegisterForDisplayChanges(*GetDisplayInfoMonitor()); |
| 64 | return resizer; |
[email protected] | da457fc | 2013-03-14 16:32:12 | [diff] [blame] | 65 | } |
| 66 | |
[email protected] | 4a444c4 | 2013-06-09 01:43:14 | [diff] [blame] | 67 | std::string Me2MeDesktopEnvironment::GetCapabilities() const { |
Lambros Lambrou | f9a02aaf | 2022-03-29 00:39:42 | [diff] [blame] | 68 | std::string capabilities = BasicDesktopEnvironment::GetCapabilities(); |
| 69 | if (!capabilities.empty()) { |
| 70 | capabilities += " "; |
| 71 | } |
sergeyu | b3e637e | 2016-10-27 23:31:21 | [diff] [blame] | 72 | capabilities += protocol::kRateLimitResizeRequests; |
Lambros Lambrou | 4c46dcb0 | 2020-07-22 18:14:54 | [diff] [blame] | 73 | |
sergeyu | b3e637e | 2016-10-27 23:31:21 | [diff] [blame] | 74 | if (InputInjector::SupportsTouchEvents()) { |
| 75 | capabilities += " "; |
| 76 | capabilities += protocol::kTouchEventsCapability; |
| 77 | } |
Joseph Arhar | e76c304 | 2017-08-03 02:01:13 | [diff] [blame] | 78 | |
Joseph Arhar | 111ddceb | 2017-09-01 04:57:30 | [diff] [blame] | 79 | if (desktop_environment_options().enable_file_transfer()) { |
| 80 | capabilities += " "; |
| 81 | capabilities += protocol::kFileTransferCapability; |
| 82 | } |
Joseph Arhar | e76c304 | 2017-08-03 02:01:13 | [diff] [blame] | 83 | |
Xiaohan Wang | 453b3867 | 2022-01-13 20:02:44 | [diff] [blame] | 84 | #if BUILDFLAG(IS_WIN) |
Joe Downing | b511e4a9 | 2018-11-16 21:10:13 | [diff] [blame] | 85 | 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 Wang | 453b3867 | 2022-01-13 20:02:44 | [diff] [blame] | 93 | #endif // BUILDFLAG(IS_WIN) |
Joe Downing | b511e4a9 | 2018-11-16 21:10:13 | [diff] [blame] | 94 | |
Yuwei Huang | c31b4d7 | 2021-09-13 23:04:49 | [diff] [blame] | 95 | if (desktop_environment_options().enable_remote_open_url() && |
| 96 | IsRemoteOpenUrlSupported()) { |
Yuwei Huang | c4927979 | 2021-07-22 23:31:48 | [diff] [blame] | 97 | capabilities += " "; |
| 98 | capabilities += protocol::kRemoteOpenUrlCapability; |
| 99 | } |
Yuwei Huang | 9d0cb6dc | 2021-05-10 21:04:51 | [diff] [blame] | 100 | |
Yuwei Huang | 78b3fc5 | 2021-10-20 21:03:24 | [diff] [blame] | 101 | if (desktop_environment_options().enable_remote_webauthn()) { |
| 102 | capabilities += " "; |
| 103 | capabilities += protocol::kRemoteWebAuthnCapability; |
| 104 | } |
| 105 | |
Lambros Lambrou | fc279d8 | 2022-09-21 18:37:39 | [diff] [blame^] | 106 | #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 | |
rkuroiwa | a7815e7 | 2015-06-05 21:39:04 | [diff] [blame] | 115 | return capabilities; |
[email protected] | 4a444c4 | 2013-06-09 01:43:14 | [diff] [blame] | 116 | } |
| 117 | |
[email protected] | 231316a | 2013-03-25 06:01:12 | [diff] [blame] | 118 | Me2MeDesktopEnvironment::Me2MeDesktopEnvironment( |
| 119 | scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
sergeyu | 85df3c48 | 2016-02-15 05:59:08 | [diff] [blame] | 120 | scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, |
[email protected] | 231316a | 2013-03-25 06:01:12 | [diff] [blame] | 121 | scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, |
zijiehe | 4aa6ea4 | 2016-11-12 01:28:16 | [diff] [blame] | 122 | scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, |
Gary Kacmarcik | a7e33e4 | 2019-02-22 19:23:28 | [diff] [blame] | 123 | base::WeakPtr<ClientSessionControl> client_session_control, |
zijiehe | 4aa6ea4 | 2016-11-12 01:28:16 | [diff] [blame] | 124 | const DesktopEnvironmentOptions& options) |
[email protected] | 231316a | 2013-03-25 06:01:12 | [diff] [blame] | 125 | : BasicDesktopEnvironment(caller_task_runner, |
sergeyu | 85df3c48 | 2016-02-15 05:59:08 | [diff] [blame] | 126 | video_capture_task_runner, |
[email protected] | 231316a | 2013-03-25 06:01:12 | [diff] [blame] | 127 | input_task_runner, |
zijiehe | 4aa6ea4 | 2016-11-12 01:28:16 | [diff] [blame] | 128 | ui_task_runner, |
Gary Kacmarcik | a7e33e4 | 2019-02-22 19:23:28 | [diff] [blame] | 129 | client_session_control, |
zijiehe | 4aa6ea4 | 2016-11-12 01:28:16 | [diff] [blame] | 130 | options) { |
[email protected] | 231316a | 2013-03-25 06:01:12 | [diff] [blame] | 131 | DCHECK(caller_task_runner->BelongsToCurrentThread()); |
sergeyu | 85df3c48 | 2016-02-15 05:59:08 | [diff] [blame] | 132 | |
zijiehe | 4aa6ea4 | 2016-11-12 01:28:16 | [diff] [blame] | 133 | // TODO(zijiehe): This logic should belong to RemotingMe2MeHost, instead of |
| 134 | // Me2MeDesktopEnvironment, which does not take response to create a new |
| 135 | // session. |
sergeyu | 85df3c48 | 2016-02-15 05:59:08 | [diff] [blame] | 136 | // 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. |
zijiehe | 4aa6ea4 | 2016-11-12 01:28:16 | [diff] [blame] | 139 | mutable_desktop_capture_options()->set_use_update_notifications(true); |
[email protected] | 96361d0 | 2013-05-08 18:26:18 | [diff] [blame] | 140 | } |
| 141 | |
| 142 | bool Me2MeDesktopEnvironment::InitializeSecurity( |
zijiehe | 4aa6ea4 | 2016-11-12 01:28:16 | [diff] [blame] | 143 | base::WeakPtr<ClientSessionControl> client_session_control) { |
[email protected] | 96361d0 | 2013-05-08 18:26:18 | [diff] [blame] | 144 | DCHECK(caller_task_runner()->BelongsToCurrentThread()); |
| 145 | |
| 146 | // Detach the session from the local console if the caller requested. |
zijiehe | 4aa6ea4 | 2016-11-12 01:28:16 | [diff] [blame] | 147 | if (desktop_environment_options().enable_curtaining()) { |
| 148 | curtain_ = CurtainMode::Create( |
| 149 | caller_task_runner(), ui_task_runner(), client_session_control); |
rkjnsn | 5d5d89b9 | 2016-06-07 21:34:21 | [diff] [blame] | 150 | if (!curtain_->Activate()) { |
[email protected] | 04eca61 | 2013-05-15 04:02:25 | [diff] [blame] | 151 | LOG(ERROR) << "Failed to activate the curtain mode."; |
rkjnsn | 5d5d89b9 | 2016-06-07 21:34:21 | [diff] [blame] | 152 | curtain_ = nullptr; |
| 153 | return false; |
| 154 | } |
| 155 | return true; |
[email protected] | 96361d0 | 2013-05-08 18:26:18 | [diff] [blame] | 156 | } |
| 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 Wang | 453b3867 | 2022-01-13 20:02:44 | [diff] [blame] | 160 | #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) |
[email protected] | 04eca61 | 2013-05-15 04:02:25 | [diff] [blame] | 161 | bool want_user_interface = false; |
Xiaohan Wang | 453b3867 | 2022-01-13 20:02:44 | [diff] [blame] | 162 | #elif BUILDFLAG(IS_APPLE) |
[email protected] | ac115ce | 2013-04-24 20:44:38 | [diff] [blame] | 163 | // 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] | 04eca61 | 2013-05-15 04:02:25 | [diff] [blame] | 170 | bool want_user_interface = getuid() != 0; |
lambroslambrou | 51e19b9 | 2016-04-13 21:30:41 | [diff] [blame] | 171 | #else |
zijiehe | 4aa6ea4 | 2016-11-12 01:28:16 | [diff] [blame] | 172 | bool want_user_interface = |
| 173 | desktop_environment_options().enable_user_interface(); |
lambroslambrou | 51e19b9 | 2016-04-13 21:30:41 | [diff] [blame] | 174 | #endif |
[email protected] | ac115ce | 2013-04-24 20:44:38 | [diff] [blame] | 175 | |
[email protected] | ac115ce | 2013-04-24 20:44:38 | [diff] [blame] | 176 | if (want_user_interface) { |
[email protected] | 04eca61 | 2013-05-15 04:02:25 | [diff] [blame] | 177 | // Create the local input monitor. |
zijiehe | 4aa6ea4 | 2016-11-12 01:28:16 | [diff] [blame] | 178 | local_input_monitor_ = LocalInputMonitor::Create( |
Joe Downing | f86c8a01 | 2018-08-29 16:49:04 | [diff] [blame] | 179 | caller_task_runner(), input_task_runner(), ui_task_runner()); |
| 180 | local_input_monitor_->StartMonitoringForClientSession( |
zijiehe | 4aa6ea4 | 2016-11-12 01:28:16 | [diff] [blame] | 181 | client_session_control); |
[email protected] | 04eca61 | 2013-05-15 04:02:25 | [diff] [blame] | 182 | |
Joe Downing | f86c8a01 | 2018-08-29 16:49:04 | [diff] [blame] | 183 | // Create the disconnect window. |
Xiaohan Wang | 453b3867 | 2022-01-13 20:02:44 | [diff] [blame] | 184 | #if BUILDFLAG(IS_WIN) |
Joe Downing | 8e95ed18 | 2018-08-30 22:57:19 | [diff] [blame] | 185 | disconnect_window_ = |
| 186 | HostWindow::CreateAutoHidingDisconnectWindow(LocalInputMonitor::Create( |
| 187 | caller_task_runner(), input_task_runner(), ui_task_runner())); |
| 188 | #else |
[email protected] | fc877cf | 2013-07-31 23:08:39 | [diff] [blame] | 189 | disconnect_window_ = HostWindow::CreateDisconnectWindow(); |
Joe Downing | 8e95ed18 | 2018-08-30 22:57:19 | [diff] [blame] | 190 | #endif |
Peter Boström | 42afa23f | 2021-04-02 22:10:46 | [diff] [blame] | 191 | disconnect_window_ = std::make_unique<HostWindowProxy>( |
| 192 | caller_task_runner(), ui_task_runner(), std::move(disconnect_window_)); |
[email protected] | ac115ce | 2013-04-24 20:44:38 | [diff] [blame] | 193 | disconnect_window_->Start(client_session_control); |
| 194 | } |
[email protected] | 96361d0 | 2013-05-08 18:26:18 | [diff] [blame] | 195 | |
| 196 | return true; |
[email protected] | da457fc | 2013-03-14 16:32:12 | [diff] [blame] | 197 | } |
| 198 | |
[email protected] | 231316a | 2013-03-25 06:01:12 | [diff] [blame] | 199 | Me2MeDesktopEnvironmentFactory::Me2MeDesktopEnvironmentFactory( |
| 200 | scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
sergeyu | 85df3c48 | 2016-02-15 05:59:08 | [diff] [blame] | 201 | scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, |
[email protected] | 231316a | 2013-03-25 06:01:12 | [diff] [blame] | 202 | scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, |
Scott Violet | 9778dcd | 2019-06-20 21:59:37 | [diff] [blame] | 203 | scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) |
[email protected] | 231316a | 2013-03-25 06:01:12 | [diff] [blame] | 204 | : BasicDesktopEnvironmentFactory(caller_task_runner, |
sergeyu | 85df3c48 | 2016-02-15 05:59:08 | [diff] [blame] | 205 | video_capture_task_runner, |
[email protected] | 231316a | 2013-03-25 06:01:12 | [diff] [blame] | 206 | input_task_runner, |
Scott Violet | 9778dcd | 2019-06-20 21:59:37 | [diff] [blame] | 207 | ui_task_runner) {} |
[email protected] | da457fc | 2013-03-14 16:32:12 | [diff] [blame] | 208 | |
| 209 | Me2MeDesktopEnvironmentFactory::~Me2MeDesktopEnvironmentFactory() { |
| 210 | } |
| 211 | |
dcheng | 0765c49 | 2016-04-06 22:41:53 | [diff] [blame] | 212 | std::unique_ptr<DesktopEnvironment> Me2MeDesktopEnvironmentFactory::Create( |
zijiehe | 4aa6ea4 | 2016-11-12 01:28:16 | [diff] [blame] | 213 | base::WeakPtr<ClientSessionControl> client_session_control, |
Yuwei Huang | 3628aa5 | 2021-12-08 23:00:55 | [diff] [blame] | 214 | base::WeakPtr<ClientSessionEvents> client_session_events, |
zijiehe | 4aa6ea4 | 2016-11-12 01:28:16 | [diff] [blame] | 215 | const DesktopEnvironmentOptions& options) { |
[email protected] | 231316a | 2013-03-25 06:01:12 | [diff] [blame] | 216 | DCHECK(caller_task_runner()->BelongsToCurrentThread()); |
| 217 | |
dcheng | 0765c49 | 2016-04-06 22:41:53 | [diff] [blame] | 218 | std::unique_ptr<Me2MeDesktopEnvironment> desktop_environment( |
Scott Violet | 9778dcd | 2019-06-20 21:59:37 | [diff] [blame] | 219 | new Me2MeDesktopEnvironment(caller_task_runner(), |
| 220 | video_capture_task_runner(), |
| 221 | input_task_runner(), ui_task_runner(), |
| 222 | client_session_control, options)); |
zijiehe | 4aa6ea4 | 2016-11-12 01:28:16 | [diff] [blame] | 223 | if (!desktop_environment->InitializeSecurity(client_session_control)) { |
sergeyu | afce978 | 2014-09-29 19:38:30 | [diff] [blame] | 224 | return nullptr; |
[email protected] | 96361d0 | 2013-05-08 18:26:18 | [diff] [blame] | 225 | } |
| 226 | |
Jeroen Dhollander | a3ce38f | 2022-08-25 07:18:02 | [diff] [blame] | 227 | return desktop_environment; |
[email protected] | 96361d0 | 2013-05-08 18:26:18 | [diff] [blame] | 228 | } |
| 229 | |
[email protected] | da457fc | 2013-03-14 16:32:12 | [diff] [blame] | 230 | } // namespace remoting |