blob: ec09c8692142956e7b7686a578478d6ba0e5ad46 [file] [log] [blame]
Avi Drissmand6cdf9b2022-09-15 19:52:531// Copyright 2013 The Chromium Authors
[email protected]5de788d82013-02-07 05:54:232// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
dcheng0765c492016-04-06 22:41:535#include "remoting/host/ipc_desktop_environment.h"
6
avic5960f32015-12-22 22:49:487#include <stdint.h>
8
dcheng0765c492016-04-06 22:41:539#include <memory>
sergeyu1417e0132015-12-23 19:01:2210#include <utility>
11
[email protected]5de788d82013-02-07 05:54:2312#include "base/bind.h"
[email protected]5de788d82013-02-07 05:54:2313#include "base/callback.h"
danakjdb9ae7942020-11-11 16:01:3514#include "base/callback_helpers.h"
Keishi Hattori0e45c022021-11-27 09:25:5215#include "base/memory/raw_ptr.h"
[email protected]5de788d82013-02-07 05:54:2316#include "base/memory/ref_counted.h"
Yuwei Huang3628aa52021-12-08 23:00:5517#include "base/memory/weak_ptr.h"
Carlos Caballerodd8bf7b042019-07-30 14:14:1518#include "base/message_loop/message_pump_type.h"
[email protected]f090f5812013-07-23 14:49:4619#include "base/process/process.h"
20#include "base/process/process_handle.h"
[email protected]5de788d82013-02-07 05:54:2321#include "base/run_loop.h"
Patrick Monette643cdf62021-10-15 19:13:4222#include "base/task/single_thread_task_runner.h"
Yuwei Huang219fc032021-09-08 23:15:3923#include "base/test/gmock_callback_support.h"
24#include "base/test/mock_callback.h"
Gabriel Charettec7108742019-08-23 03:31:4025#include "base/test/task_environment.h"
Yuwei Huang219fc032021-09-08 23:15:3926#include "base/threading/sequenced_task_runner_handle.h"
avic5960f32015-12-22 22:49:4827#include "build/build_config.h"
[email protected]5de788d82013-02-07 05:54:2328#include "ipc/ipc_channel.h"
29#include "ipc/ipc_channel_proxy.h"
30#include "ipc/ipc_listener.h"
31#include "ipc/ipc_message.h"
32#include "ipc/ipc_platform_file.h"
Joe Downing185945a2022-02-15 18:57:1933#include "mojo/public/cpp/system/message_pipe.h"
[email protected]5de788d82013-02-07 05:54:2334#include "remoting/base/auto_thread.h"
35#include "remoting/base/auto_thread_task_runner.h"
[email protected]73fc5572013-02-20 11:59:3736#include "remoting/base/constants.h"
[email protected]5de788d82013-02-07 05:54:2337#include "remoting/host/desktop_process.h"
[email protected]e36460f2013-03-08 09:29:3238#include "remoting/host/desktop_session.h"
[email protected]5de788d82013-02-07 05:54:2339#include "remoting/host/desktop_session_connector.h"
40#include "remoting/host/desktop_session_proxy.h"
Erik Jensenc08ecf112019-12-19 00:29:4941#include "remoting/host/fake_keyboard_layout_monitor.h"
[email protected]20013202014-08-08 06:33:5042#include "remoting/host/fake_mouse_cursor_monitor.h"
[email protected]5de788d82013-02-07 05:54:2343#include "remoting/host/host_mock_objects.h"
Joe Downingd4d6f342021-09-23 22:12:0944#include "remoting/host/mojom/desktop_session.mojom.h"
sergeyu4d208002015-11-23 22:27:4345#include "remoting/protocol/fake_desktop_capturer.h"
[email protected]5de788d82013-02-07 05:54:2346#include "remoting/protocol/protocol_mock_objects.h"
rkuroiwad11ebf02015-03-06 01:31:4547#include "remoting/protocol/test_event_matchers.h"
[email protected]5de788d82013-02-07 05:54:2348#include "testing/gmock/include/gmock/gmock.h"
49#include "testing/gtest/include/gtest/gtest.h"
zijiehea69c7842016-11-11 01:28:2050#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
[email protected]b9ed58f2013-05-16 10:45:2451#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
52#include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
[email protected]5de788d82013-02-07 05:54:2353
Yuwei Huang219fc032021-09-08 23:15:3954using base::test::RunCallback;
55using base::test::RunOnceCallback;
56using base::test::RunOnceClosure;
[email protected]5de788d82013-02-07 05:54:2357using testing::_;
58using testing::AnyNumber;
[email protected]73fc5572013-02-20 11:59:3759using testing::AtLeast;
[email protected]a5d181f2013-04-19 14:55:3760using testing::AtMost;
Yuwei Huang219fc032021-09-08 23:15:3961using testing::ByMove;
[email protected]c4d9d292013-05-16 18:31:1062using testing::DeleteArg;
63using testing::DoAll;
rkuroiwad11ebf02015-03-06 01:31:4564using testing::InSequence;
[email protected]5de788d82013-02-07 05:54:2365using testing::Return;
[email protected]231316a2013-03-25 06:01:1266using testing::ReturnRef;
[email protected]5de788d82013-02-07 05:54:2367
68namespace remoting {
69
rkuroiwa29333662015-03-13 17:21:1170using protocol::test::EqualsTouchEvent;
71using protocol::test::EqualsTouchEventTypeAndId;
72
Yuwei Huang219fc032021-09-08 23:15:3973using SetUpUrlForwarderResponse =
74 protocol::UrlForwarderControl::SetUpUrlForwarderResponse;
75
[email protected]5de788d82013-02-07 05:54:2376namespace {
77
zijiehea69c7842016-11-11 01:28:2078class MockScreenCapturerCallback : public webrtc::DesktopCapturer::Callback {
sergeyu1e5d35af2016-06-07 21:43:0179 public:
Chris Watkins6fe52aa2017-11-28 03:24:0580 MockScreenCapturerCallback() = default;
Peter Boströme9178e42021-09-22 18:11:4981
82 MockScreenCapturerCallback(const MockScreenCapturerCallback&) = delete;
83 MockScreenCapturerCallback& operator=(const MockScreenCapturerCallback&) =
84 delete;
85
Daniel Cheng8b41cd282018-04-26 20:41:1586 ~MockScreenCapturerCallback() override = default;
sergeyu1e5d35af2016-06-07 21:43:0187
Joe Downingd198b512022-02-25 14:46:4888 MOCK_METHOD(void,
89 OnCaptureResultPtr,
90 (webrtc::DesktopCapturer::Result,
91 std::unique_ptr<webrtc::DesktopFrame>*));
sergeyu546cbaa2016-06-17 20:39:3292 void OnCaptureResult(webrtc::DesktopCapturer::Result result,
93 std::unique_ptr<webrtc::DesktopFrame> frame) override {
94 OnCaptureResultPtr(result, &frame);
95 }
sergeyu1e5d35af2016-06-07 21:43:0196};
97
[email protected]73fc5572013-02-20 11:59:3798// Receives messages sent from the desktop process to the daemon.
Joe Downingd4d6f342021-09-23 22:12:0999class MockDaemonListener : public IPC::Listener,
100 public mojom::DesktopSessionRequestHandler {
[email protected]5de788d82013-02-07 05:54:23101 public:
Chris Watkins6fe52aa2017-11-28 03:24:05102 MockDaemonListener() = default;
Peter Boströme9178e42021-09-22 18:11:49103
104 MockDaemonListener(const MockDaemonListener&) = delete;
105 MockDaemonListener& operator=(const MockDaemonListener&) = delete;
106
Chris Watkins6fe52aa2017-11-28 03:24:05107 ~MockDaemonListener() override = default;
[email protected]5de788d82013-02-07 05:54:23108
nick697f4292015-04-23 18:22:31109 bool OnMessageReceived(const IPC::Message& message) override;
Joe Downingd4d6f342021-09-23 22:12:09110 void OnAssociatedInterfaceRequest(
111 const std::string& interface_name,
112 mojo::ScopedInterfaceEndpointHandle handle) override;
[email protected]5de788d82013-02-07 05:54:23113
Joe Downingd4d6f342021-09-23 22:12:09114 MOCK_METHOD(void,
115 ConnectDesktopChannel,
116 (mojo::ScopedMessagePipeHandle handle),
117 (override));
118 MOCK_METHOD(void, InjectSecureAttentionSequence, (), (override));
119 MOCK_METHOD(void, CrashNetworkProcess, (), (override));
120 MOCK_METHOD(void, OnChannelConnected, (int32_t), (override));
121 MOCK_METHOD(void, OnChannelError, (), (override));
122
123 void Disconnect();
124
125 private:
126 mojo::AssociatedReceiver<mojom::DesktopSessionRequestHandler>
127 desktop_session_request_handler_{this};
[email protected]5de788d82013-02-07 05:54:23128};
129
[email protected]5de788d82013-02-07 05:54:23130bool MockDaemonListener::OnMessageReceived(const IPC::Message& message) {
Joe Downingd4d6f342021-09-23 22:12:09131 ADD_FAILURE() << "Unexpected call to OnMessageReceived()";
132 return false;
133}
[email protected]5de788d82013-02-07 05:54:23134
Joe Downingd4d6f342021-09-23 22:12:09135void MockDaemonListener::OnAssociatedInterfaceRequest(
136 const std::string& interface_name,
137 mojo::ScopedInterfaceEndpointHandle handle) {
138 EXPECT_EQ(mojom::DesktopSessionRequestHandler::Name_, interface_name);
139 mojo::PendingAssociatedReceiver<mojom::DesktopSessionRequestHandler>
140 pending_receiver(std::move(handle));
141 desktop_session_request_handler_.Bind(std::move(pending_receiver));
142}
143
144void MockDaemonListener::Disconnect() {
145 desktop_session_request_handler_.reset();
[email protected]5de788d82013-02-07 05:54:23146}
147
Joe Downing1437fb72022-02-16 15:25:26148class MockDesktopSessionManager : public mojom::DesktopSessionManager {
149 public:
150 MockDesktopSessionManager() = default;
151 ~MockDesktopSessionManager() override = default;
152
153 void BindNewReceiver(
154 mojo::PendingAssociatedReceiver<mojom::DesktopSessionManager> receiver);
155
156 // mojom::DesktopSessionManager implementation.
157 MOCK_METHOD(void,
158 CreateDesktopSession,
159 (int, const ScreenResolution&, bool),
160 (override));
161 MOCK_METHOD(void, CloseDesktopSession, (int), (override));
162 MOCK_METHOD(void,
163 SetScreenResolution,
164 (int, const ScreenResolution&),
165 (override));
166
167 private:
168 mojo::AssociatedReceiver<mojom::DesktopSessionManager>
169 desktop_session_manager_{this};
170};
171
172void MockDesktopSessionManager::BindNewReceiver(
173 mojo::PendingAssociatedReceiver<mojom::DesktopSessionManager> receiver) {
174 desktop_session_manager_.reset();
175
176 // EnableUnassociatedUsage() sets up a private message pipe for the remote /
177 // receiver pair used in this test which simplifies our test setup and
178 // doesn't change any behaviors being tested.
179 receiver.EnableUnassociatedUsage();
180 desktop_session_manager_.Bind(std::move(receiver));
181}
182
[email protected]5de788d82013-02-07 05:54:23183} // namespace
184
[email protected]73fc5572013-02-20 11:59:37185class IpcDesktopEnvironmentTest : public testing::Test {
[email protected]5de788d82013-02-07 05:54:23186 public:
187 IpcDesktopEnvironmentTest();
dcheng440d8e1c2014-10-28 01:23:15188 ~IpcDesktopEnvironmentTest() override;
[email protected]5de788d82013-02-07 05:54:23189
dcheng440d8e1c2014-10-28 01:23:15190 void SetUp() override;
rkuroiwaa7815e72015-06-05 21:39:04191 void TearDown() override;
[email protected]5de788d82013-02-07 05:54:23192
Joe Downing1437fb72022-02-16 15:25:26193 void CreateDesktopSession(int terminal_id,
194 const ScreenResolution& resolution,
195 bool virtual_terminal);
196 void CloseDesktopSession(int terminal_id);
[email protected]5de788d82013-02-07 05:54:23197
[email protected]4e719f42014-08-12 18:04:37198 // Creates a DesktopEnvironment with a fake webrtc::DesktopCapturer, to mock
[email protected]5de788d82013-02-07 05:54:23199 // DesktopEnvironmentFactory::Create().
Lambros Lambroua4a259e2022-02-11 05:07:58200 std::unique_ptr<DesktopEnvironment> CreateDesktopEnvironment();
[email protected]5de788d82013-02-07 05:54:23201
Lambros Lambroua4a259e2022-02-11 05:07:58202 // Creates a fake InputInjector, to mock
[email protected]b0b72f112013-03-24 03:42:42203 // DesktopEnvironment::CreateInputInjector().
Lambros Lambroua4a259e2022-02-11 05:07:58204 std::unique_ptr<InputInjector> CreateInputInjector();
Erik Jensenc08ecf112019-12-19 00:29:49205
[email protected]5de788d82013-02-07 05:54:23206 void DeleteDesktopEnvironment();
207
[email protected]73fc5572013-02-20 11:59:37208 // Forwards |event| to |clipboard_stub_|.
209 void ReflectClipboardEvent(const protocol::ClipboardEvent& event);
210
[email protected]5de788d82013-02-07 05:54:23211 protected:
[email protected]73fc5572013-02-20 11:59:37212 // Creates and starts an instance of desktop process object.
213 void CreateDesktopProcess();
214
215 // Destroys the desktop process object created by CreateDesktopProcess().
Joe Downing28a8fd02022-01-26 21:08:19216 void DestroyDesktopProcess();
[email protected]73fc5572013-02-20 11:59:37217
Yuwei Huang219fc032021-09-08 23:15:39218 // Creates a new remote URL forwarder configurator for the desktop process.
219 void ResetRemoteUrlForwarderConfigurator();
220
[email protected]5de788d82013-02-07 05:54:23221 void OnDisconnectCallback();
222
Joe Downingd4d6f342021-09-23 22:12:09223 // Invoked when ConnectDesktopChannel() is called over IPC.
224 void ConnectDesktopChannel(mojo::ScopedMessagePipeHandle desktop_pipe);
[email protected]5de788d82013-02-07 05:54:23225
Yuwei Huang219fc032021-09-08 23:15:39226 // Runs until there are no references to |task_runner_|. Calls after the main
227 // loop has been run are no-op.
rkuroiwaa7815e72015-06-05 21:39:04228 void RunMainLoopUntilDone();
229
Joe Downing28a8fd02022-01-26 21:08:19230 // Some tests require |setup_run_loop_| to be reset so we need a method which
231 // can be bound that will quit the current run loop.
232 void QuitSetupRunLoop();
233
Yuwei Huang219fc032021-09-08 23:15:39234 base::test::TaskEnvironment task_environment_{
235 base::test::TaskEnvironment::MainThreadType::UI};
[email protected]5de788d82013-02-07 05:54:23236
237 // Runs until |desktop_session_proxy_| is connected to the desktop.
dcheng0765c492016-04-06 22:41:53238 std::unique_ptr<base::RunLoop> setup_run_loop_;
[email protected]5de788d82013-02-07 05:54:23239
[email protected]5de788d82013-02-07 05:54:23240 scoped_refptr<AutoThreadTaskRunner> task_runner_;
[email protected]73fc5572013-02-20 11:59:37241 scoped_refptr<AutoThreadTaskRunner> io_task_runner_;
[email protected]5de788d82013-02-07 05:54:23242
[email protected]231316a2013-03-25 06:01:12243 std::string client_jid_;
244
[email protected]73fc5572013-02-20 11:59:37245 // Clipboard stub that receives clipboard events from the desktop process.
Keishi Hattori0e45c022021-11-27 09:25:52246 raw_ptr<protocol::ClipboardStub> clipboard_stub_;
[email protected]5de788d82013-02-07 05:54:23247
248 // The daemons's end of the daemon-to-desktop channel.
dcheng0765c492016-04-06 22:41:53249 std::unique_ptr<IPC::ChannelProxy> desktop_channel_;
[email protected]5de788d82013-02-07 05:54:23250
Joe Downing1437fb72022-02-16 15:25:26251 MockDesktopSessionManager mock_desktop_session_manager_;
252
[email protected]73fc5572013-02-20 11:59:37253 // Delegate that is passed to |desktop_channel_|.
254 MockDaemonListener desktop_listener_;
[email protected]5de788d82013-02-07 05:54:23255
dcheng0765c492016-04-06 22:41:53256 std::unique_ptr<IpcDesktopEnvironmentFactory> desktop_environment_factory_;
257 std::unique_ptr<DesktopEnvironment> desktop_environment_;
[email protected]73fc5572013-02-20 11:59:37258
[email protected]b0b72f112013-03-24 03:42:42259 // The IPC input injector.
dcheng0765c492016-04-06 22:41:53260 std::unique_ptr<InputInjector> input_injector_;
[email protected]5de788d82013-02-07 05:54:23261
[email protected]e3cab672013-05-31 02:20:29262 // The IPC screen controls.
dcheng0765c492016-04-06 22:41:53263 std::unique_ptr<ScreenControls> screen_controls_;
[email protected]e3cab672013-05-31 02:20:29264
[email protected]73fc5572013-02-20 11:59:37265 // The IPC screen capturer.
dcheng0765c492016-04-06 22:41:53266 std::unique_ptr<webrtc::DesktopCapturer> video_capturer_;
[email protected]5de788d82013-02-07 05:54:23267
268 // Represents the desktop process running in a user session.
dcheng0765c492016-04-06 22:41:53269 std::unique_ptr<DesktopProcess> desktop_process_;
[email protected]5de788d82013-02-07 05:54:23270
[email protected]b0b72f112013-03-24 03:42:42271 // Input injector owned by |desktop_process_|.
Keishi Hattori0e45c022021-11-27 09:25:52272 raw_ptr<MockInputInjector> remote_input_injector_;
[email protected]73fc5572013-02-20 11:59:37273
Yuwei Huang219fc032021-09-08 23:15:39274 // Will be transferred to the caller of
275 // MockDesktopEnvironment::CreateUrlForwarderConfigurator().
276 // We create the configurator in advance to allow setting expectations before
277 // the desktop process is being created, during which the configurator will be
278 // used.
279 std::unique_ptr<MockUrlForwarderConfigurator>
280 owned_remote_url_forwarder_configurator_;
Keishi Hattori0e45c022021-11-27 09:25:52281 raw_ptr<MockUrlForwarderConfigurator> remote_url_forwarder_configurator_;
Yuwei Huang219fc032021-09-08 23:15:39282 std::unique_ptr<UrlForwarderConfigurator> url_forwarder_configurator_;
283
[email protected]73fc5572013-02-20 11:59:37284 // The last |terminal_id| passed to ConnectTermina();
285 int terminal_id_;
[email protected]5de788d82013-02-07 05:54:23286
sergeyu1e5d35af2016-06-07 21:43:01287 MockScreenCapturerCallback desktop_capturer_callback_;
[email protected]231316a2013-03-25 06:01:12288
289 MockClientSessionControl client_session_control_;
290 base::WeakPtrFactory<ClientSessionControl> client_session_control_factory_;
rkuroiwaa7815e72015-06-05 21:39:04291
Yuwei Huang3628aa52021-12-08 23:00:55292 MockClientSessionEvents client_session_events_;
293 base::WeakPtrFactory<MockClientSessionEvents> client_session_events_factory_{
294 &client_session_events_};
295
rkuroiwaa7815e72015-06-05 21:39:04296 private:
Yuwei Huang219fc032021-09-08 23:15:39297 // Runs until there are no references to |task_runner_|.
rkuroiwaa7815e72015-06-05 21:39:04298 base::RunLoop main_run_loop_;
[email protected]5de788d82013-02-07 05:54:23299};
300
301IpcDesktopEnvironmentTest::IpcDesktopEnvironmentTest()
[email protected]166f2ed2013-12-19 19:34:00302 : client_jid_("user@domain/rest-of-jid"),
sergeyuc5f104b2015-01-09 19:33:24303 clipboard_stub_(nullptr),
304 remote_input_injector_(nullptr),
[email protected]231316a2013-03-25 06:01:12305 terminal_id_(-1),
306 client_session_control_factory_(&client_session_control_) {
[email protected]5de788d82013-02-07 05:54:23307}
308
Chris Watkins6fe52aa2017-11-28 03:24:05309IpcDesktopEnvironmentTest::~IpcDesktopEnvironmentTest() = default;
[email protected]5de788d82013-02-07 05:54:23310
311void IpcDesktopEnvironmentTest::SetUp() {
312 // Arrange to run |message_loop_| until no components depend on it.
Gabriel Charettedfa36042019-08-19 17:30:11313 task_runner_ =
314 new AutoThreadTaskRunner(task_environment_.GetMainThreadTaskRunner(),
315 main_run_loop_.QuitClosure());
[email protected]5de788d82013-02-07 05:54:23316
Carlos Caballerodd8bf7b042019-07-30 14:14:15317 io_task_runner_ = AutoThread::CreateWithType("IPC thread", task_runner_,
318 base::MessagePumpType::IO);
[email protected]73fc5572013-02-20 11:59:37319
Peter Boström42afa23f2021-04-02 22:10:46320 setup_run_loop_ = std::make_unique<base::RunLoop>();
[email protected]5de788d82013-02-07 05:54:23321
322 // Set expectation that the DaemonProcess will send DesktopAttached message
323 // once it is ready.
[email protected]73fc5572013-02-20 11:59:37324 EXPECT_CALL(desktop_listener_, OnChannelConnected(_))
325 .Times(AnyNumber());
Joe Downingd4d6f342021-09-23 22:12:09326 EXPECT_CALL(desktop_listener_, ConnectDesktopChannel(_))
[email protected]73fc5572013-02-20 11:59:37327 .Times(AnyNumber())
Joe Downingd4d6f342021-09-23 22:12:09328 .WillRepeatedly([&](mojo::ScopedMessagePipeHandle desktop_pipe) {
329 ConnectDesktopChannel(std::move(desktop_pipe));
330 });
[email protected]73fc5572013-02-20 11:59:37331 EXPECT_CALL(desktop_listener_, OnChannelError())
[email protected]5de788d82013-02-07 05:54:23332 .Times(AnyNumber())
Joe Downing28a8fd02022-01-26 21:08:19333 .WillOnce(
334 Invoke(this, &IpcDesktopEnvironmentTest::DestroyDesktopProcess));
[email protected]5de788d82013-02-07 05:54:23335
[email protected]73fc5572013-02-20 11:59:37336 // Intercept requests to connect and disconnect a terminal.
Joe Downing1437fb72022-02-16 15:25:26337 EXPECT_CALL(mock_desktop_session_manager_, CreateDesktopSession(_, _, _))
[email protected]73fc5572013-02-20 11:59:37338 .Times(AnyNumber())
Joe Downing1437fb72022-02-16 15:25:26339 .WillRepeatedly(
340 Invoke(this, &IpcDesktopEnvironmentTest::CreateDesktopSession));
341 EXPECT_CALL(mock_desktop_session_manager_, CloseDesktopSession(_))
[email protected]73fc5572013-02-20 11:59:37342 .Times(AnyNumber())
Joe Downing1437fb72022-02-16 15:25:26343 .WillRepeatedly(
344 Invoke(this, &IpcDesktopEnvironmentTest::CloseDesktopSession));
[email protected]691e4b62013-02-16 20:31:08345
[email protected]231316a2013-03-25 06:01:12346 EXPECT_CALL(client_session_control_, client_jid())
347 .Times(AnyNumber())
348 .WillRepeatedly(ReturnRef(client_jid_));
sergeyuec77d8542015-11-03 22:31:00349 EXPECT_CALL(client_session_control_, DisconnectSession(_))
[email protected]231316a2013-03-25 06:01:12350 .Times(AnyNumber())
sergeyuec77d8542015-11-03 22:31:00351 .WillRepeatedly(InvokeWithoutArgs(
[email protected]231316a2013-03-25 06:01:12352 this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
Jamie Walch6e3a42292019-05-03 02:19:21353 EXPECT_CALL(client_session_control_, OnLocalPointerMoved(_, _)).Times(0);
[email protected]231316a2013-03-25 06:01:12354 EXPECT_CALL(client_session_control_, SetDisableInputs(_))
355 .Times(0);
356
Joe Downing28a8fd02022-01-26 21:08:19357 // Most tests will only call this once but reattach will call multiple times.
358 EXPECT_CALL(client_session_events_, OnDesktopAttached(_))
359 .Times(AnyNumber())
360 .WillRepeatedly(InvokeWithoutArgs(
361 this, &IpcDesktopEnvironmentTest::QuitSetupRunLoop));
Joe Downing975f2112022-01-28 20:07:42362 EXPECT_CALL(client_session_events_, OnDesktopDetached()).Times(AnyNumber());
Joe Downing28a8fd02022-01-26 21:08:19363
[email protected]73fc5572013-02-20 11:59:37364 // Create a desktop environment instance.
Joe Downing1437fb72022-02-16 15:25:26365 mojo::AssociatedRemote<mojom::DesktopSessionManager> remote;
366 mock_desktop_session_manager_.BindNewReceiver(
367 remote.BindNewEndpointAndPassReceiver());
Peter Boström42afa23f2021-04-02 22:10:46368 desktop_environment_factory_ = std::make_unique<IpcDesktopEnvironmentFactory>(
Joe Downing1437fb72022-02-16 15:25:26369 task_runner_, task_runner_, io_task_runner_, std::move(remote));
[email protected]73fc5572013-02-20 11:59:37370 desktop_environment_ = desktop_environment_factory_->Create(
zijiehe4aa6ea42016-11-12 01:28:16371 client_session_control_factory_.GetWeakPtr(),
Yuwei Huang3628aa52021-12-08 23:00:55372 client_session_events_factory_.GetWeakPtr(), DesktopEnvironmentOptions());
[email protected]5de788d82013-02-07 05:54:23373
[email protected]e3cab672013-05-31 02:20:29374 screen_controls_ = desktop_environment_->CreateScreenControls();
375
[email protected]b0b72f112013-03-24 03:42:42376 // Create the input injector.
[email protected]231316a2013-03-25 06:01:12377 input_injector_ = desktop_environment_->CreateInputInjector();
[email protected]5de788d82013-02-07 05:54:23378
379 // Create the screen capturer.
Joe Downinge910cf92022-09-14 22:20:44380 video_capturer_ = desktop_environment_->CreateVideoCapturer();
[email protected]a5d181f2013-04-19 14:55:37381
382 desktop_environment_->SetCapabilities(std::string());
Yuwei Huang219fc032021-09-08 23:15:39383
384 url_forwarder_configurator_ =
385 desktop_environment_->CreateUrlForwarderConfigurator();
386 ResetRemoteUrlForwarderConfigurator();
[email protected]5de788d82013-02-07 05:54:23387}
388
rkuroiwaa7815e72015-06-05 21:39:04389void IpcDesktopEnvironmentTest::TearDown() {
390 RunMainLoopUntilDone();
391}
392
Joe Downing1437fb72022-02-16 15:25:26393void IpcDesktopEnvironmentTest::CreateDesktopSession(
[email protected]e36460f2013-03-08 09:29:32394 int terminal_id,
[email protected]739e2802013-03-18 01:03:48395 const ScreenResolution& resolution,
[email protected]e36460f2013-03-08 09:29:32396 bool virtual_terminal) {
[email protected]73fc5572013-02-20 11:59:37397 EXPECT_NE(terminal_id_, terminal_id);
[email protected]5de788d82013-02-07 05:54:23398
[email protected]73fc5572013-02-20 11:59:37399 terminal_id_ = terminal_id;
400 CreateDesktopProcess();
401}
402
Joe Downing1437fb72022-02-16 15:25:26403void IpcDesktopEnvironmentTest::CloseDesktopSession(int terminal_id) {
[email protected]73fc5572013-02-20 11:59:37404 EXPECT_EQ(terminal_id_, terminal_id);
405
406 // The IPC desktop environment is fully destroyed now. Release the remaining
407 // task runners.
408 desktop_environment_factory_.reset();
409}
410
Lambros Lambroua4a259e2022-02-11 05:07:58411std::unique_ptr<DesktopEnvironment>
412IpcDesktopEnvironmentTest::CreateDesktopEnvironment() {
413 auto desktop_environment = std::make_unique<MockDesktopEnvironment>();
414 EXPECT_CALL(*desktop_environment, CreateAudioCapturer()).Times(0);
415 EXPECT_CALL(*desktop_environment, CreateInputInjector())
[email protected]a5d181f2013-04-19 14:55:37416 .Times(AtMost(1))
Lambros Lambroua4a259e2022-02-11 05:07:58417 .WillOnce(Invoke(this, &IpcDesktopEnvironmentTest::CreateInputInjector));
418 EXPECT_CALL(*desktop_environment, CreateScreenControls()).Times(AtMost(1));
Joe Downinge910cf92022-09-14 22:20:44419 EXPECT_CALL(*desktop_environment, CreateVideoCapturer())
[email protected]a5d181f2013-04-19 14:55:37420 .Times(AtMost(1))
Lambros Lambroua4a259e2022-02-11 05:07:58421 .WillOnce(
422 Return(ByMove(std::make_unique<protocol::FakeDesktopCapturer>())));
423 EXPECT_CALL(*desktop_environment, CreateActionExecutor()).Times(AtMost(1));
424 EXPECT_CALL(*desktop_environment, CreateFileOperations()).Times(AtMost(1));
Joe Downinge910cf92022-09-14 22:20:44425 EXPECT_CALL(*desktop_environment, CreateMouseCursorMonitor())
[email protected]20013202014-08-08 06:33:50426 .Times(AtMost(1))
Lambros Lambroua4a259e2022-02-11 05:07:58427 .WillOnce(Return(ByMove(std::make_unique<FakeMouseCursorMonitor>())));
428 EXPECT_CALL(*desktop_environment, CreateKeyboardLayoutMonitor(_))
Erik Jensenc08ecf112019-12-19 00:29:49429 .Times(AtMost(1))
Lambros Lambroua4a259e2022-02-11 05:07:58430 .WillOnce(Return(ByMove(std::make_unique<FakeKeyboardLayoutMonitor>())));
[email protected]a5d181f2013-04-19 14:55:37431 EXPECT_CALL(*desktop_environment, GetCapabilities())
432 .Times(AtMost(1));
433 EXPECT_CALL(*desktop_environment, SetCapabilities(_))
434 .Times(AtMost(1));
Yuwei Huang219fc032021-09-08 23:15:39435 DCHECK(owned_remote_url_forwarder_configurator_);
436 EXPECT_CALL(*desktop_environment, CreateUrlForwarderConfigurator())
437 .Times(AtMost(1))
438 .WillOnce(
439 Return(ByMove(std::move(owned_remote_url_forwarder_configurator_))));
[email protected]73fc5572013-02-20 11:59:37440
[email protected]73fc5572013-02-20 11:59:37441 return desktop_environment;
442}
443
Lambros Lambroua4a259e2022-02-11 05:07:58444std::unique_ptr<InputInjector>
445IpcDesktopEnvironmentTest::CreateInputInjector() {
446 auto remote_input_injector =
447 std::make_unique<testing::StrictMock<MockInputInjector>>();
sergeyuc5f104b2015-01-09 19:33:24448 EXPECT_TRUE(remote_input_injector_ == nullptr);
Lambros Lambroua4a259e2022-02-11 05:07:58449 remote_input_injector_ = remote_input_injector.get();
[email protected]73fc5572013-02-20 11:59:37450
Lambros Lambroua4a259e2022-02-11 05:07:58451 EXPECT_CALL(*remote_input_injector_, Start(_));
452 return remote_input_injector;
Erik Jensenc08ecf112019-12-19 00:29:49453}
454
[email protected]73fc5572013-02-20 11:59:37455void IpcDesktopEnvironmentTest::DeleteDesktopEnvironment() {
[email protected]b0b72f112013-03-24 03:42:42456 input_injector_.reset();
[email protected]e3cab672013-05-31 02:20:29457 screen_controls_.reset();
[email protected]73fc5572013-02-20 11:59:37458 video_capturer_.reset();
Yuwei Huang219fc032021-09-08 23:15:39459 url_forwarder_configurator_.reset();
[email protected]73fc5572013-02-20 11:59:37460
Joe Downing1437fb72022-02-16 15:25:26461 // Trigger CloseDesktopSession().
[email protected]73fc5572013-02-20 11:59:37462 desktop_environment_.reset();
463}
464
465void IpcDesktopEnvironmentTest::ReflectClipboardEvent(
466 const protocol::ClipboardEvent& event) {
467 clipboard_stub_->InjectClipboardEvent(event);
468}
469
470void IpcDesktopEnvironmentTest::CreateDesktopProcess() {
[email protected]f9d8a772013-06-01 04:33:17471 EXPECT_TRUE(task_runner_.get());
472 EXPECT_TRUE(io_task_runner_.get());
[email protected]73fc5572013-02-20 11:59:37473
474 // Create the daemon end of the daemon-to-desktop channel.
sammc34c69a12016-10-27 22:43:37475 mojo::MessagePipe pipe;
erikchen30dc2812015-09-24 03:26:38476 desktop_channel_ = IPC::ChannelProxy::Create(
sammc34c69a12016-10-27 22:43:37477 pipe.handle0.release(), IPC::Channel::MODE_SERVER, &desktop_listener_,
Hajime Hoshiff15e972017-11-09 06:37:09478 io_task_runner_.get(), base::ThreadTaskRunnerHandle::Get());
[email protected]5de788d82013-02-07 05:54:23479
[email protected]691e4b62013-02-16 20:31:08480 // Create and start the desktop process.
Peter Boström42afa23f2021-04-02 22:10:46481 desktop_process_ = std::make_unique<DesktopProcess>(
482 task_runner_, io_task_runner_, io_task_runner_, std::move(pipe.handle1));
[email protected]691e4b62013-02-16 20:31:08483
dcheng0765c492016-04-06 22:41:53484 std::unique_ptr<MockDesktopEnvironmentFactory> desktop_environment_factory(
[email protected]691e4b62013-02-16 20:31:08485 new MockDesktopEnvironmentFactory());
Lambros Lambroua4a259e2022-02-11 05:07:58486 EXPECT_CALL(*desktop_environment_factory, Create(_, _, _))
[email protected]691e4b62013-02-16 20:31:08487 .Times(AnyNumber())
Lambros Lambroua4a259e2022-02-11 05:07:58488 .WillRepeatedly(
489 Invoke(this, &IpcDesktopEnvironmentTest::CreateDesktopEnvironment));
[email protected]691e4b62013-02-16 20:31:08490 EXPECT_CALL(*desktop_environment_factory, SupportsAudioCapture())
491 .Times(AnyNumber())
492 .WillRepeatedly(Return(false));
493
sergeyu1417e0132015-12-23 19:01:22494 EXPECT_TRUE(desktop_process_->Start(std::move(desktop_environment_factory)));
[email protected]5de788d82013-02-07 05:54:23495}
496
Joe Downing28a8fd02022-01-26 21:08:19497void IpcDesktopEnvironmentTest::DestroyDesktopProcess() {
[email protected]73fc5572013-02-20 11:59:37498 desktop_channel_.reset();
499 if (desktop_process_) {
500 desktop_process_->OnChannelError();
501 desktop_process_.reset();
502 }
Joe Downingd4d6f342021-09-23 22:12:09503 desktop_listener_.Disconnect();
sergeyuc5f104b2015-01-09 19:33:24504 remote_input_injector_ = nullptr;
[email protected]5de788d82013-02-07 05:54:23505}
506
Yuwei Huang219fc032021-09-08 23:15:39507void IpcDesktopEnvironmentTest::ResetRemoteUrlForwarderConfigurator() {
508 owned_remote_url_forwarder_configurator_ =
509 std::make_unique<MockUrlForwarderConfigurator>();
510 remote_url_forwarder_configurator_ =
511 owned_remote_url_forwarder_configurator_.get();
512 ON_CALL(*remote_url_forwarder_configurator_, IsUrlForwarderSetUp(_))
513 .WillByDefault(RunOnceCallback<0>(false));
514}
515
[email protected]5de788d82013-02-07 05:54:23516void IpcDesktopEnvironmentTest::OnDisconnectCallback() {
[email protected]73fc5572013-02-20 11:59:37517 DeleteDesktopEnvironment();
[email protected]5de788d82013-02-07 05:54:23518}
519
Joe Downingd4d6f342021-09-23 22:12:09520void IpcDesktopEnvironmentTest::ConnectDesktopChannel(
521 mojo::ScopedMessagePipeHandle desktop_pipe) {
[email protected]5de788d82013-02-07 05:54:23522 // Instruct DesktopSessionProxy to connect to the network-to-desktop pipe.
[email protected]73fc5572013-02-20 11:59:37523 desktop_environment_factory_->OnDesktopSessionAgentAttached(
Joe Downing185945a2022-02-15 18:57:19524 terminal_id_, /*session_id=*/0, std::move(desktop_pipe));
[email protected]5de788d82013-02-07 05:54:23525}
526
rkuroiwaa7815e72015-06-05 21:39:04527void IpcDesktopEnvironmentTest::RunMainLoopUntilDone() {
Yuwei Huang219fc032021-09-08 23:15:39528 bool should_run_loop = task_runner_ != nullptr;
rkuroiwaa7815e72015-06-05 21:39:04529 task_runner_ = nullptr;
530 io_task_runner_ = nullptr;
Yuwei Huang219fc032021-09-08 23:15:39531 if (should_run_loop) {
532 main_run_loop_.Run();
533 }
rkuroiwaa7815e72015-06-05 21:39:04534}
535
Joe Downing28a8fd02022-01-26 21:08:19536void IpcDesktopEnvironmentTest::QuitSetupRunLoop() {
537 setup_run_loop_->Quit();
538}
539
[email protected]73fc5572013-02-20 11:59:37540// Runs until the desktop is attached and exits immediately after that.
[email protected]5de788d82013-02-07 05:54:23541TEST_F(IpcDesktopEnvironmentTest, Basic) {
dcheng0765c492016-04-06 22:41:53542 std::unique_ptr<protocol::MockClipboardStub> clipboard_stub(
[email protected]5de788d82013-02-07 05:54:23543 new protocol::MockClipboardStub());
544 EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
545 .Times(0);
546
[email protected]b0b72f112013-03-24 03:42:42547 // Start the input injector and screen capturer.
sergeyu1417e0132015-12-23 19:01:22548 input_injector_->Start(std::move(clipboard_stub));
[email protected]5de788d82013-02-07 05:54:23549
550 // Run the message loop until the desktop is attached.
[email protected]73fc5572013-02-20 11:59:37551 setup_run_loop_->Run();
552
[email protected]5de788d82013-02-07 05:54:23553 // Stop the test.
554 DeleteDesktopEnvironment();
rkuroiwaa7815e72015-06-05 21:39:04555}
[email protected]5de788d82013-02-07 05:54:23556
rkuroiwaa7815e72015-06-05 21:39:04557// Check touchEvents capability is set when the desktop environment can
558// inject touch events.
559TEST_F(IpcDesktopEnvironmentTest, TouchEventsCapabilities) {
560 // Create an environment with multi touch enabled.
rkuroiwaa7815e72015-06-05 21:39:04561 desktop_environment_ = desktop_environment_factory_->Create(
zijiehe4aa6ea42016-11-12 01:28:16562 client_session_control_factory_.GetWeakPtr(),
Yuwei Huang3628aa52021-12-08 23:00:55563 client_session_events_factory_.GetWeakPtr(), DesktopEnvironmentOptions());
rkuroiwaa7815e72015-06-05 21:39:04564
dcheng0765c492016-04-06 22:41:53565 std::unique_ptr<protocol::MockClipboardStub> clipboard_stub(
rkuroiwaa7815e72015-06-05 21:39:04566 new protocol::MockClipboardStub());
567 EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
568 .Times(0);
569
sergeyub3e637e2016-10-27 23:31:21570 std::string expected_capabilities = "rateLimitResizeRequests";
571 if (InputInjector::SupportsTouchEvents())
572 expected_capabilities += " touchEvents";
573
574 EXPECT_EQ(expected_capabilities, desktop_environment_->GetCapabilities());
rkuroiwaa7815e72015-06-05 21:39:04575
576 // Start the input injector and screen capturer.
sergeyu1417e0132015-12-23 19:01:22577 input_injector_->Start(std::move(clipboard_stub));
rkuroiwaa7815e72015-06-05 21:39:04578
579 // Run the message loop until the desktop is attached.
580 setup_run_loop_->Run();
581
582 // Stop the test.
583 DeleteDesktopEnvironment();
[email protected]5de788d82013-02-07 05:54:23584}
585
[email protected]73fc5572013-02-20 11:59:37586// Tests that the video capturer receives a frame over IPC.
[email protected]5de788d82013-02-07 05:54:23587TEST_F(IpcDesktopEnvironmentTest, CaptureFrame) {
dcheng0765c492016-04-06 22:41:53588 std::unique_ptr<protocol::MockClipboardStub> clipboard_stub(
[email protected]5de788d82013-02-07 05:54:23589 new protocol::MockClipboardStub());
590 EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
591 .Times(0);
592
[email protected]b0b72f112013-03-24 03:42:42593 // Start the input injector and screen capturer.
sergeyu1417e0132015-12-23 19:01:22594 input_injector_->Start(std::move(clipboard_stub));
[email protected]4e719f42014-08-12 18:04:37595 video_capturer_->Start(&desktop_capturer_callback_);
[email protected]5de788d82013-02-07 05:54:23596
597 // Run the message loop until the desktop is attached.
[email protected]73fc5572013-02-20 11:59:37598 setup_run_loop_->Run();
599
[email protected]5de788d82013-02-07 05:54:23600 // Stop the test when the first frame is captured.
sergeyu546cbaa2016-06-17 20:39:32601 EXPECT_CALL(desktop_capturer_callback_, OnCaptureResultPtr(_, _))
602 .WillOnce(InvokeWithoutArgs(
603 this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
[email protected]5de788d82013-02-07 05:54:23604
605 // Capture a single frame.
zijiehe27bcc912016-10-18 05:57:56606 video_capturer_->CaptureFrame();
[email protected]73fc5572013-02-20 11:59:37607}
608
609// Tests that attaching to a new desktop works.
610TEST_F(IpcDesktopEnvironmentTest, Reattach) {
dcheng0765c492016-04-06 22:41:53611 std::unique_ptr<protocol::MockClipboardStub> clipboard_stub(
[email protected]73fc5572013-02-20 11:59:37612 new protocol::MockClipboardStub());
613 EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
614 .Times(0);
615
[email protected]b0b72f112013-03-24 03:42:42616 // Start the input injector and screen capturer.
sergeyu1417e0132015-12-23 19:01:22617 input_injector_->Start(std::move(clipboard_stub));
[email protected]4e719f42014-08-12 18:04:37618 video_capturer_->Start(&desktop_capturer_callback_);
[email protected]73fc5572013-02-20 11:59:37619
620 // Run the message loop until the desktop is attached.
621 setup_run_loop_->Run();
622
623 // Create and start a new desktop process object.
Peter Boström42afa23f2021-04-02 22:10:46624 setup_run_loop_ = std::make_unique<base::RunLoop>();
Joe Downing28a8fd02022-01-26 21:08:19625 DestroyDesktopProcess();
Yuwei Huang219fc032021-09-08 23:15:39626 ResetRemoteUrlForwarderConfigurator();
[email protected]73fc5572013-02-20 11:59:37627 CreateDesktopProcess();
628 setup_run_loop_->Run();
629
[email protected]73fc5572013-02-20 11:59:37630 // Stop the test.
631 DeleteDesktopEnvironment();
[email protected]73fc5572013-02-20 11:59:37632}
633
[email protected]73fc5572013-02-20 11:59:37634// Tests injection of clipboard events.
635TEST_F(IpcDesktopEnvironmentTest, InjectClipboardEvent) {
dcheng0765c492016-04-06 22:41:53636 std::unique_ptr<protocol::MockClipboardStub> clipboard_stub(
[email protected]73fc5572013-02-20 11:59:37637 new protocol::MockClipboardStub());
638 clipboard_stub_ = clipboard_stub.get();
639
640 // Stop the test when a clipboard event is received from the desktop process.
641 EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
642 .Times(1)
643 .WillOnce(InvokeWithoutArgs(
644 this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
645
[email protected]b0b72f112013-03-24 03:42:42646 // Start the input injector and screen capturer.
sergeyu1417e0132015-12-23 19:01:22647 input_injector_->Start(std::move(clipboard_stub));
[email protected]4e719f42014-08-12 18:04:37648 video_capturer_->Start(&desktop_capturer_callback_);
[email protected]73fc5572013-02-20 11:59:37649
650 // Run the message loop until the desktop is attached.
651 setup_run_loop_->Run();
652
653 // Expect a single clipboard event.
[email protected]b0b72f112013-03-24 03:42:42654 EXPECT_CALL(*remote_input_injector_, InjectClipboardEvent(_))
[email protected]73fc5572013-02-20 11:59:37655 .Times(1)
656 .WillOnce(Invoke(this,
657 &IpcDesktopEnvironmentTest::ReflectClipboardEvent));
[email protected]73fc5572013-02-20 11:59:37658
659 // Send a clipboard event.
660 protocol::ClipboardEvent event;
661 event.set_mime_type(kMimeTypeTextUtf8);
662 event.set_data("a");
[email protected]b0b72f112013-03-24 03:42:42663 input_injector_->InjectClipboardEvent(event);
[email protected]73fc5572013-02-20 11:59:37664}
665
666// Tests injection of key events.
667TEST_F(IpcDesktopEnvironmentTest, InjectKeyEvent) {
dcheng0765c492016-04-06 22:41:53668 std::unique_ptr<protocol::MockClipboardStub> clipboard_stub(
[email protected]73fc5572013-02-20 11:59:37669 new protocol::MockClipboardStub());
670 EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
671 .Times(0);
672
[email protected]b0b72f112013-03-24 03:42:42673 // Start the input injector and screen capturer.
sergeyu1417e0132015-12-23 19:01:22674 input_injector_->Start(std::move(clipboard_stub));
[email protected]4e719f42014-08-12 18:04:37675 video_capturer_->Start(&desktop_capturer_callback_);
[email protected]73fc5572013-02-20 11:59:37676
677 // Run the message loop until the desktop is attached.
678 setup_run_loop_->Run();
679
680 // Expect a single key event.
[email protected]b0b72f112013-03-24 03:42:42681 EXPECT_CALL(*remote_input_injector_, InjectKeyEvent(_))
[email protected]73fc5572013-02-20 11:59:37682 .Times(AtLeast(1))
683 .WillRepeatedly(InvokeWithoutArgs(
684 this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
[email protected]73fc5572013-02-20 11:59:37685
686 // Send a key event.
687 protocol::KeyEvent event;
688 event.set_usb_keycode(0x070004);
689 event.set_pressed(true);
[email protected]b0b72f112013-03-24 03:42:42690 input_injector_->InjectKeyEvent(event);
[email protected]73fc5572013-02-20 11:59:37691}
692
[email protected]529bbd12014-03-27 20:25:39693// Tests injection of text events.
694TEST_F(IpcDesktopEnvironmentTest, InjectTextEvent) {
dcheng0765c492016-04-06 22:41:53695 std::unique_ptr<protocol::MockClipboardStub> clipboard_stub(
[email protected]529bbd12014-03-27 20:25:39696 new protocol::MockClipboardStub());
697 EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
698 .Times(0);
699
700 // Start the input injector and screen capturer.
sergeyu1417e0132015-12-23 19:01:22701 input_injector_->Start(std::move(clipboard_stub));
[email protected]4e719f42014-08-12 18:04:37702 video_capturer_->Start(&desktop_capturer_callback_);
[email protected]529bbd12014-03-27 20:25:39703
704 // Run the message loop until the desktop is attached.
705 setup_run_loop_->Run();
706
707 // Expect a single text event.
708 EXPECT_CALL(*remote_input_injector_, InjectTextEvent(_))
709 .Times(AtLeast(1))
710 .WillRepeatedly(InvokeWithoutArgs(
711 this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
712
713 // Send a text event.
714 protocol::TextEvent event;
715 event.set_text("hello");
716 input_injector_->InjectTextEvent(event);
[email protected]529bbd12014-03-27 20:25:39717}
718
[email protected]73fc5572013-02-20 11:59:37719// Tests injection of mouse events.
720TEST_F(IpcDesktopEnvironmentTest, InjectMouseEvent) {
dcheng0765c492016-04-06 22:41:53721 std::unique_ptr<protocol::MockClipboardStub> clipboard_stub(
[email protected]73fc5572013-02-20 11:59:37722 new protocol::MockClipboardStub());
723 EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
724 .Times(0);
725
[email protected]b0b72f112013-03-24 03:42:42726 // Start the input injector and screen capturer.
sergeyu1417e0132015-12-23 19:01:22727 input_injector_->Start(std::move(clipboard_stub));
[email protected]4e719f42014-08-12 18:04:37728 video_capturer_->Start(&desktop_capturer_callback_);
[email protected]73fc5572013-02-20 11:59:37729
730 // Run the message loop until the desktop is attached.
731 setup_run_loop_->Run();
732
733 // Expect a single mouse event.
[email protected]b0b72f112013-03-24 03:42:42734 EXPECT_CALL(*remote_input_injector_, InjectMouseEvent(_))
[email protected]73fc5572013-02-20 11:59:37735 .Times(1)
736 .WillOnce(InvokeWithoutArgs(
737 this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
738
739 // Send a mouse event.
740 protocol::MouseEvent event;
741 event.set_x(0);
742 event.set_y(0);
[email protected]b0b72f112013-03-24 03:42:42743 input_injector_->InjectMouseEvent(event);
[email protected]5de788d82013-02-07 05:54:23744}
745
rkuroiwad11ebf02015-03-06 01:31:45746// Tests injection of touch events.
747TEST_F(IpcDesktopEnvironmentTest, InjectTouchEvent) {
dcheng0765c492016-04-06 22:41:53748 std::unique_ptr<protocol::MockClipboardStub> clipboard_stub(
rkuroiwad11ebf02015-03-06 01:31:45749 new protocol::MockClipboardStub());
750 EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
751 .Times(0);
752
753 // Start the input injector and screen capturer.
sergeyu1417e0132015-12-23 19:01:22754 input_injector_->Start(std::move(clipboard_stub));
rkuroiwad11ebf02015-03-06 01:31:45755 video_capturer_->Start(&desktop_capturer_callback_);
756
757 // Run the message loop until the desktop is attached.
758 setup_run_loop_->Run();
759
760 protocol::TouchEvent event;
761 event.set_event_type(protocol::TouchEvent::TOUCH_POINT_START);
762 protocol::TouchEventPoint* point = event.add_touch_points();
763 point->set_id(0u);
764 point->set_x(0.0f);
765 point->set_y(0.0f);
766 point->set_radius_x(0.0f);
767 point->set_radius_y(0.0f);
768 point->set_angle(0.0f);
769 point->set_pressure(0.0f);
770
771 ON_CALL(*remote_input_injector_, InjectTouchEvent(_))
772 .WillByDefault(InvokeWithoutArgs(
773 this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
774
775 InSequence s;
776 // Expect that the event gets propagated to remote_input_injector_.
777 // And one more call for ReleaseAll().
778 EXPECT_CALL(*remote_input_injector_,
rkuroiwa29333662015-03-13 17:21:11779 InjectTouchEvent(EqualsTouchEvent(event)));
rkuroiwad11ebf02015-03-06 01:31:45780 EXPECT_CALL(*remote_input_injector_,
rkuroiwa29333662015-03-13 17:21:11781 InjectTouchEvent(EqualsTouchEventTypeAndId(
782 protocol::TouchEvent::TOUCH_POINT_CANCEL, 0u)));
rkuroiwad11ebf02015-03-06 01:31:45783
784 // Send the touch event.
785 input_injector_->InjectTouchEvent(event);
rkuroiwad11ebf02015-03-06 01:31:45786}
787
[email protected]e3cab672013-05-31 02:20:29788// Tests that setting the desktop resolution works.
789TEST_F(IpcDesktopEnvironmentTest, SetScreenResolution) {
dcheng0765c492016-04-06 22:41:53790 std::unique_ptr<protocol::MockClipboardStub> clipboard_stub(
[email protected]e3cab672013-05-31 02:20:29791 new protocol::MockClipboardStub());
792 EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
793 .Times(0);
794
795 // Start the input injector and screen capturer.
sergeyu1417e0132015-12-23 19:01:22796 input_injector_->Start(std::move(clipboard_stub));
[email protected]4e719f42014-08-12 18:04:37797 video_capturer_->Start(&desktop_capturer_callback_);
[email protected]e3cab672013-05-31 02:20:29798
799 // Run the message loop until the desktop is attached.
800 setup_run_loop_->Run();
801
Joe Downing1437fb72022-02-16 15:25:26802 EXPECT_CALL(mock_desktop_session_manager_, SetScreenResolution(_, _))
[email protected]e3cab672013-05-31 02:20:29803 .Times(1)
804 .WillOnce(InvokeWithoutArgs(
805 this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
806
807 // Change the desktop resolution.
Lambros Lambrouec5f1b02022-05-20 00:45:53808 screen_controls_->SetScreenResolution(
809 ScreenResolution(webrtc::DesktopSize(100, 100),
810 webrtc::DesktopVector(96, 96)),
811 absl::nullopt);
[email protected]e3cab672013-05-31 02:20:29812}
813
Joe Downing975f2112022-01-28 20:07:42814TEST_F(IpcDesktopEnvironmentTest, CheckUrlForwarderState) {
Yuwei Huang219fc032021-09-08 23:15:39815 EXPECT_CALL(*remote_url_forwarder_configurator_, IsUrlForwarderSetUp(_))
816 .WillOnce(RunOnceCallback<0>(true));
817 base::MockCallback<UrlForwarderConfigurator::IsUrlForwarderSetUpCallback>
818 callback;
819 EXPECT_CALL(callback, Run(true))
820 .WillOnce([&]() {
821 // Do it again when the state is already known.
822 url_forwarder_configurator_->IsUrlForwarderSetUp(callback.Get());
823 })
824 .WillOnce(InvokeWithoutArgs(
825 this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
826
Yuwei Huang219fc032021-09-08 23:15:39827 // Run the message loop until the desktop is attached.
828 setup_run_loop_->Run();
829
Joe Downing975f2112022-01-28 20:07:42830 url_forwarder_configurator_->IsUrlForwarderSetUp(callback.Get());
831
Yuwei Huang219fc032021-09-08 23:15:39832 // Run now rather than in TearDown() so that we can verify |callback|.
833 RunMainLoopUntilDone();
834}
835
Joe Downing975f2112022-01-28 20:07:42836TEST_F(IpcDesktopEnvironmentTest, SetUpUrlForwarderHappyPath) {
Yuwei Huang219fc032021-09-08 23:15:39837 EXPECT_CALL(*remote_url_forwarder_configurator_, IsUrlForwarderSetUp(_))
838 .WillOnce(RunOnceCallback<0>(false));
839 EXPECT_CALL(*remote_url_forwarder_configurator_, SetUpUrlForwarder(_))
840 .WillOnce([](auto& callback) {
841 callback.Run(SetUpUrlForwarderResponse::USER_INTERVENTION_REQUIRED);
842 callback.Run(SetUpUrlForwarderResponse::COMPLETE);
843 });
844 base::MockCallback<UrlForwarderConfigurator::SetUpUrlForwarderCallback>
845 setup_state_callback;
846 base::MockCallback<UrlForwarderConfigurator::IsUrlForwarderSetUpCallback>
847 is_set_up_callback;
848
849 {
850 InSequence s;
851
852 EXPECT_CALL(is_set_up_callback, Run(false)).WillOnce([&]() {
853 // Post task to prevent reentrant issue.
854 base::SequencedTaskRunnerHandle::Get()->PostTask(
855 FROM_HERE,
856 base::BindOnce(&UrlForwarderConfigurator::SetUpUrlForwarder,
857 base::Unretained(url_forwarder_configurator_.get()),
858 setup_state_callback.Get()));
859 });
860 EXPECT_CALL(setup_state_callback,
861 Run(SetUpUrlForwarderResponse::USER_INTERVENTION_REQUIRED))
862 .Times(1);
863 EXPECT_CALL(setup_state_callback, Run(SetUpUrlForwarderResponse::COMPLETE))
864 .WillOnce([&]() {
865 url_forwarder_configurator_->IsUrlForwarderSetUp(
866 is_set_up_callback.Get());
867 });
868 EXPECT_CALL(is_set_up_callback, Run(true))
869 .WillOnce(InvokeWithoutArgs(
870 this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
871 }
872
Yuwei Huang219fc032021-09-08 23:15:39873 // Run the message loop until the desktop is attached.
874 setup_run_loop_->Run();
875
Joe Downing975f2112022-01-28 20:07:42876 url_forwarder_configurator_->IsUrlForwarderSetUp(is_set_up_callback.Get());
877
Yuwei Huang219fc032021-09-08 23:15:39878 // Run now rather than in TearDown() so that we can verify |callback|.
879 RunMainLoopUntilDone();
880}
881
Joe Downing975f2112022-01-28 20:07:42882TEST_F(IpcDesktopEnvironmentTest, SetUpUrlForwarderFailed) {
Yuwei Huang219fc032021-09-08 23:15:39883 EXPECT_CALL(*remote_url_forwarder_configurator_, IsUrlForwarderSetUp(_))
884 .WillOnce(RunOnceCallback<0>(false));
885 EXPECT_CALL(*remote_url_forwarder_configurator_, SetUpUrlForwarder(_))
886 .WillOnce(RunOnceCallback<0>(SetUpUrlForwarderResponse::FAILED));
887 base::MockCallback<UrlForwarderConfigurator::SetUpUrlForwarderCallback>
888 setup_state_callback;
889 base::MockCallback<UrlForwarderConfigurator::IsUrlForwarderSetUpCallback>
890 is_set_up_callback;
891
892 {
893 InSequence s;
894
895 EXPECT_CALL(is_set_up_callback, Run(false)).WillOnce([&]() {
896 // Post task to prevent reentrant issue.
897 base::SequencedTaskRunnerHandle::Get()->PostTask(
898 FROM_HERE,
899 base::BindOnce(&UrlForwarderConfigurator::SetUpUrlForwarder,
900 base::Unretained(url_forwarder_configurator_.get()),
901 setup_state_callback.Get()));
902 });
903 EXPECT_CALL(setup_state_callback, Run(SetUpUrlForwarderResponse::FAILED))
904 .WillOnce([&]() {
905 url_forwarder_configurator_->IsUrlForwarderSetUp(
906 is_set_up_callback.Get());
907 });
908 EXPECT_CALL(is_set_up_callback, Run(false))
909 .WillOnce(InvokeWithoutArgs(
910 this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
911 }
912
Yuwei Huang219fc032021-09-08 23:15:39913 // Run the message loop until the desktop is attached.
914 setup_run_loop_->Run();
915
Joe Downing975f2112022-01-28 20:07:42916 url_forwarder_configurator_->IsUrlForwarderSetUp(is_set_up_callback.Get());
917
Yuwei Huang219fc032021-09-08 23:15:39918 // Run now rather than in TearDown() so that we can verify |callback|.
919 RunMainLoopUntilDone();
920}
921
[email protected]5de788d82013-02-07 05:54:23922} // namespace remoting