1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
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 "base/bind.h"
6 #include "base/bind_helpers.h"
7 #include "base/callback.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/process/process.h"
12 #include "base/process/process_handle.h"
13 #include "base/run_loop.h"
14 #include "ipc/ipc_channel.h"
15 #include "ipc/ipc_channel_proxy.h"
16 #include "ipc/ipc_listener.h"
17 #include "ipc/ipc_message.h"
18 #include "ipc/ipc_platform_file.h"
19 #include "remoting/base/auto_thread.h"
20 #include "remoting/base/auto_thread_task_runner.h"
21 #include "remoting/base/constants.h"
22 #include "remoting/host/chromoting_messages.h"
23 #include "remoting/host/desktop_process.h"
24 #include "remoting/host/desktop_session.h"
25 #include "remoting/host/desktop_session_connector.h"
26 #include "remoting/host/desktop_session_proxy.h"
27 #include "remoting/host/host_mock_objects.h"
28 #include "remoting/host/ipc_desktop_environment.h"
29 #include "remoting/host/screen_capturer_fake.h"
30 #include "remoting/protocol/protocol_mock_objects.h"
31 #include "testing/gmock/include/gmock/gmock.h"
32 #include "testing/gtest/include/gtest/gtest.h"
33 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
34 #include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
35 #include "third_party/webrtc/modules/desktop_capture/screen_capturer_mock_objects.h"
36
37 using testing::_;
38 using testing::AnyNumber;
39 using testing::AtLeast;
40 using testing::AtMost;
41 using testing::DeleteArg;
42 using testing::DoAll;
43 using testing::Return;
44 using testing::ReturnRef;
45
46 namespace remoting {
47
48 namespace {
49
50 // Receives messages sent from the network process to the daemon.
51 class FakeDaemonSender : public IPC::Sender {
52 public:
FakeDaemonSender()53 FakeDaemonSender() {}
~FakeDaemonSender()54 virtual ~FakeDaemonSender() {}
55
56 // IPC::Sender implementation.
57 virtual bool Send(IPC::Message* message) OVERRIDE;
58
59 MOCK_METHOD3(ConnectTerminal, void(int, const ScreenResolution&, bool));
60 MOCK_METHOD1(DisconnectTerminal, void(int));
61 MOCK_METHOD2(SetScreenResolution, void(int, const ScreenResolution&));
62
63 private:
64 void OnMessageReceived(const IPC::Message& message);
65
66 DISALLOW_COPY_AND_ASSIGN(FakeDaemonSender);
67 };
68
69 // Receives messages sent from the desktop process to the daemon.
70 class MockDaemonListener : public IPC::Listener {
71 public:
MockDaemonListener()72 MockDaemonListener() {}
~MockDaemonListener()73 virtual ~MockDaemonListener() {}
74
75 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
76
77 MOCK_METHOD1(OnDesktopAttached, void(IPC::PlatformFileForTransit));
78 MOCK_METHOD1(OnChannelConnected, void(int32));
79 MOCK_METHOD0(OnChannelError, void());
80
81 private:
82 DISALLOW_COPY_AND_ASSIGN(MockDaemonListener);
83 };
84
Send(IPC::Message * message)85 bool FakeDaemonSender::Send(IPC::Message* message) {
86 OnMessageReceived(*message);
87 delete message;
88 return true;
89 }
90
OnMessageReceived(const IPC::Message & message)91 void FakeDaemonSender::OnMessageReceived(const IPC::Message& message) {
92 bool handled = true;
93 IPC_BEGIN_MESSAGE_MAP(FakeDaemonSender, message)
94 IPC_MESSAGE_HANDLER(ChromotingNetworkHostMsg_ConnectTerminal,
95 ConnectTerminal)
96 IPC_MESSAGE_HANDLER(ChromotingNetworkHostMsg_DisconnectTerminal,
97 DisconnectTerminal)
98 IPC_MESSAGE_HANDLER(ChromotingNetworkDaemonMsg_SetScreenResolution,
99 SetScreenResolution)
100 IPC_MESSAGE_UNHANDLED(handled = false)
101 IPC_END_MESSAGE_MAP()
102
103 EXPECT_TRUE(handled);
104 }
105
OnMessageReceived(const IPC::Message & message)106 bool MockDaemonListener::OnMessageReceived(const IPC::Message& message) {
107 bool handled = true;
108 IPC_BEGIN_MESSAGE_MAP(MockDaemonListener, message)
109 IPC_MESSAGE_HANDLER(ChromotingDesktopDaemonMsg_DesktopAttached,
110 OnDesktopAttached)
111 IPC_MESSAGE_UNHANDLED(handled = false)
112 IPC_END_MESSAGE_MAP()
113
114 EXPECT_TRUE(handled);
115 return handled;
116 }
117
118 } // namespace
119
120 class IpcDesktopEnvironmentTest : public testing::Test {
121 public:
122 IpcDesktopEnvironmentTest();
123 virtual ~IpcDesktopEnvironmentTest();
124
125 virtual void SetUp() OVERRIDE;
126
127 void ConnectTerminal(int terminal_id,
128 const ScreenResolution& resolution,
129 bool virtual_terminal);
130 void DisconnectTerminal(int terminal_id);
131
132 // Creates a DesktopEnvironment with a fake webrtc::ScreenCapturer, to mock
133 // DesktopEnvironmentFactory::Create().
134 DesktopEnvironment* CreateDesktopEnvironment();
135
136 // Creates a dummy InputInjector, to mock
137 // DesktopEnvironment::CreateInputInjector().
138 InputInjector* CreateInputInjector();
139
140 // Creates a fake webrtc::ScreenCapturer, to mock
141 // DesktopEnvironment::CreateVideoCapturer().
142 webrtc::ScreenCapturer* CreateVideoCapturer();
143
144 void DeleteDesktopEnvironment();
145
146 // Forwards |event| to |clipboard_stub_|.
147 void ReflectClipboardEvent(const protocol::ClipboardEvent& event);
148
149 protected:
150 // Creates and starts an instance of desktop process object.
151 void CreateDesktopProcess();
152
153 // Destroys the desktop process object created by CreateDesktopProcess().
154 void DestoyDesktopProcess();
155
156 void OnDisconnectCallback();
157
158 // Invoked when ChromotingDesktopDaemonMsg_DesktopAttached message is
159 // received.
160 void OnDesktopAttached(IPC::PlatformFileForTransit desktop_pipe);
161
162 // The main message loop.
163 base::MessageLoopForUI message_loop_;
164
165 // Runs until |desktop_session_proxy_| is connected to the desktop.
166 scoped_ptr<base::RunLoop> setup_run_loop_;
167
168 // Runs until there are references to |task_runner_|.
169 base::RunLoop main_run_loop_;
170
171 scoped_refptr<AutoThreadTaskRunner> task_runner_;
172 scoped_refptr<AutoThreadTaskRunner> io_task_runner_;
173
174 std::string client_jid_;
175
176 // Clipboard stub that receives clipboard events from the desktop process.
177 protocol::ClipboardStub* clipboard_stub_;
178
179 // The daemons's end of the daemon-to-desktop channel.
180 scoped_ptr<IPC::ChannelProxy> desktop_channel_;
181
182 // Name of the daemon-to-desktop channel.
183 std::string desktop_channel_name_;
184
185 // Delegate that is passed to |desktop_channel_|.
186 MockDaemonListener desktop_listener_;
187
188 FakeDaemonSender daemon_channel_;
189
190 scoped_ptr<IpcDesktopEnvironmentFactory> desktop_environment_factory_;
191 scoped_ptr<DesktopEnvironment> desktop_environment_;
192
193 // The IPC input injector.
194 scoped_ptr<InputInjector> input_injector_;
195
196 // The IPC screen controls.
197 scoped_ptr<ScreenControls> screen_controls_;
198
199 // The IPC screen capturer.
200 scoped_ptr<webrtc::ScreenCapturer> video_capturer_;
201
202 // Represents the desktop process running in a user session.
203 scoped_ptr<DesktopProcess> desktop_process_;
204
205 // Input injector owned by |desktop_process_|.
206 MockInputInjector* remote_input_injector_;
207
208 // The last |terminal_id| passed to ConnectTermina();
209 int terminal_id_;
210
211 webrtc::MockScreenCapturerCallback screen_capturer_callback_;
212
213 MockClientSessionControl client_session_control_;
214 base::WeakPtrFactory<ClientSessionControl> client_session_control_factory_;
215 };
216
IpcDesktopEnvironmentTest()217 IpcDesktopEnvironmentTest::IpcDesktopEnvironmentTest()
218 : client_jid_("user@domain/rest-of-jid"),
219 clipboard_stub_(NULL),
220 remote_input_injector_(NULL),
221 terminal_id_(-1),
222 client_session_control_factory_(&client_session_control_) {
223 }
224
~IpcDesktopEnvironmentTest()225 IpcDesktopEnvironmentTest::~IpcDesktopEnvironmentTest() {
226 }
227
SetUp()228 void IpcDesktopEnvironmentTest::SetUp() {
229 // Arrange to run |message_loop_| until no components depend on it.
230 task_runner_ = new AutoThreadTaskRunner(
231 message_loop_.message_loop_proxy(), main_run_loop_.QuitClosure());
232
233 io_task_runner_ = AutoThread::CreateWithType(
234 "IPC thread", task_runner_, base::MessageLoop::TYPE_IO);
235
236 setup_run_loop_.reset(new base::RunLoop());
237
238 // Set expectation that the DaemonProcess will send DesktopAttached message
239 // once it is ready.
240 EXPECT_CALL(desktop_listener_, OnChannelConnected(_))
241 .Times(AnyNumber());
242 EXPECT_CALL(desktop_listener_, OnDesktopAttached(_))
243 .Times(AnyNumber())
244 .WillRepeatedly(Invoke(this,
245 &IpcDesktopEnvironmentTest::OnDesktopAttached));
246 EXPECT_CALL(desktop_listener_, OnChannelError())
247 .Times(AnyNumber())
248 .WillOnce(Invoke(this,
249 &IpcDesktopEnvironmentTest::DestoyDesktopProcess));
250
251 // Intercept requests to connect and disconnect a terminal.
252 EXPECT_CALL(daemon_channel_, ConnectTerminal(_, _, _))
253 .Times(AnyNumber())
254 .WillRepeatedly(Invoke(this,
255 &IpcDesktopEnvironmentTest::ConnectTerminal));
256 EXPECT_CALL(daemon_channel_, DisconnectTerminal(_))
257 .Times(AnyNumber())
258 .WillRepeatedly(Invoke(this,
259 &IpcDesktopEnvironmentTest::DisconnectTerminal));
260
261 EXPECT_CALL(client_session_control_, client_jid())
262 .Times(AnyNumber())
263 .WillRepeatedly(ReturnRef(client_jid_));
264 EXPECT_CALL(client_session_control_, DisconnectSession())
265 .Times(AnyNumber())
266 .WillRepeatedly(Invoke(
267 this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
268 EXPECT_CALL(client_session_control_, OnLocalMouseMoved(_))
269 .Times(0);
270 EXPECT_CALL(client_session_control_, SetDisableInputs(_))
271 .Times(0);
272
273 // Create a desktop environment instance.
274 desktop_environment_factory_.reset(new IpcDesktopEnvironmentFactory(
275 task_runner_,
276 task_runner_,
277 task_runner_,
278 io_task_runner_,
279 &daemon_channel_));
280 desktop_environment_ = desktop_environment_factory_->Create(
281 client_session_control_factory_.GetWeakPtr());
282
283 screen_controls_ = desktop_environment_->CreateScreenControls();
284
285 // Create the input injector.
286 input_injector_ = desktop_environment_->CreateInputInjector();
287
288 // Create the screen capturer.
289 video_capturer_ =
290 desktop_environment_->CreateVideoCapturer();
291
292 desktop_environment_->SetCapabilities(std::string());
293 }
294
ConnectTerminal(int terminal_id,const ScreenResolution & resolution,bool virtual_terminal)295 void IpcDesktopEnvironmentTest::ConnectTerminal(
296 int terminal_id,
297 const ScreenResolution& resolution,
298 bool virtual_terminal) {
299 EXPECT_NE(terminal_id_, terminal_id);
300
301 terminal_id_ = terminal_id;
302 CreateDesktopProcess();
303 }
304
DisconnectTerminal(int terminal_id)305 void IpcDesktopEnvironmentTest::DisconnectTerminal(int terminal_id) {
306 EXPECT_EQ(terminal_id_, terminal_id);
307
308 // The IPC desktop environment is fully destroyed now. Release the remaining
309 // task runners.
310 desktop_environment_factory_.reset();
311 }
312
CreateDesktopEnvironment()313 DesktopEnvironment* IpcDesktopEnvironmentTest::CreateDesktopEnvironment() {
314 MockDesktopEnvironment* desktop_environment = new MockDesktopEnvironment();
315 EXPECT_CALL(*desktop_environment, CreateAudioCapturerPtr())
316 .Times(0);
317 EXPECT_CALL(*desktop_environment, CreateInputInjectorPtr())
318 .Times(AtMost(1))
319 .WillOnce(Invoke(
320 this, &IpcDesktopEnvironmentTest::CreateInputInjector));
321 EXPECT_CALL(*desktop_environment, CreateScreenControlsPtr())
322 .Times(AtMost(1));
323 EXPECT_CALL(*desktop_environment, CreateVideoCapturerPtr())
324 .Times(AtMost(1))
325 .WillOnce(Invoke(
326 this, &IpcDesktopEnvironmentTest::CreateVideoCapturer));
327 EXPECT_CALL(*desktop_environment, GetCapabilities())
328 .Times(AtMost(1));
329 EXPECT_CALL(*desktop_environment, SetCapabilities(_))
330 .Times(AtMost(1));
331
332 // Let tests know that the remote desktop environment is created.
333 message_loop_.PostTask(FROM_HERE, setup_run_loop_->QuitClosure());
334
335 return desktop_environment;
336 }
337
CreateInputInjector()338 InputInjector* IpcDesktopEnvironmentTest::CreateInputInjector() {
339 EXPECT_TRUE(remote_input_injector_ == NULL);
340 remote_input_injector_ = new testing::StrictMock<MockInputInjector>();
341
342 EXPECT_CALL(*remote_input_injector_, StartPtr(_));
343 return remote_input_injector_;
344 }
345
CreateVideoCapturer()346 webrtc::ScreenCapturer* IpcDesktopEnvironmentTest::CreateVideoCapturer() {
347 return new ScreenCapturerFake();
348 }
349
DeleteDesktopEnvironment()350 void IpcDesktopEnvironmentTest::DeleteDesktopEnvironment() {
351 input_injector_.reset();
352 screen_controls_.reset();
353 video_capturer_.reset();
354
355 // Trigger DisconnectTerminal().
356 desktop_environment_.reset();
357 }
358
ReflectClipboardEvent(const protocol::ClipboardEvent & event)359 void IpcDesktopEnvironmentTest::ReflectClipboardEvent(
360 const protocol::ClipboardEvent& event) {
361 clipboard_stub_->InjectClipboardEvent(event);
362 }
363
CreateDesktopProcess()364 void IpcDesktopEnvironmentTest::CreateDesktopProcess() {
365 EXPECT_TRUE(task_runner_.get());
366 EXPECT_TRUE(io_task_runner_.get());
367
368 // Create the daemon end of the daemon-to-desktop channel.
369 desktop_channel_name_ = IPC::Channel::GenerateUniqueRandomChannelID();
370 desktop_channel_ =
371 IPC::ChannelProxy::Create(IPC::ChannelHandle(desktop_channel_name_),
372 IPC::Channel::MODE_SERVER,
373 &desktop_listener_,
374 io_task_runner_.get());
375
376 // Create and start the desktop process.
377 desktop_process_.reset(new DesktopProcess(task_runner_,
378 io_task_runner_,
379 desktop_channel_name_));
380
381 scoped_ptr<MockDesktopEnvironmentFactory> desktop_environment_factory(
382 new MockDesktopEnvironmentFactory());
383 EXPECT_CALL(*desktop_environment_factory, CreatePtr())
384 .Times(AnyNumber())
385 .WillRepeatedly(Invoke(
386 this, &IpcDesktopEnvironmentTest::CreateDesktopEnvironment));
387 EXPECT_CALL(*desktop_environment_factory, SupportsAudioCapture())
388 .Times(AnyNumber())
389 .WillRepeatedly(Return(false));
390
391 EXPECT_TRUE(desktop_process_->Start(
392 desktop_environment_factory.PassAs<DesktopEnvironmentFactory>()));
393 }
394
DestoyDesktopProcess()395 void IpcDesktopEnvironmentTest::DestoyDesktopProcess() {
396 desktop_channel_.reset();
397 if (desktop_process_) {
398 desktop_process_->OnChannelError();
399 desktop_process_.reset();
400 }
401 remote_input_injector_ = NULL;
402 }
403
OnDisconnectCallback()404 void IpcDesktopEnvironmentTest::OnDisconnectCallback() {
405 DeleteDesktopEnvironment();
406 }
407
OnDesktopAttached(IPC::PlatformFileForTransit desktop_pipe)408 void IpcDesktopEnvironmentTest::OnDesktopAttached(
409 IPC::PlatformFileForTransit desktop_pipe) {
410
411 // Instruct DesktopSessionProxy to connect to the network-to-desktop pipe.
412 desktop_environment_factory_->OnDesktopSessionAgentAttached(
413 terminal_id_, base::GetCurrentProcessHandle(), desktop_pipe);
414 }
415
416 // Runs until the desktop is attached and exits immediately after that.
TEST_F(IpcDesktopEnvironmentTest,Basic)417 TEST_F(IpcDesktopEnvironmentTest, Basic) {
418 scoped_ptr<protocol::MockClipboardStub> clipboard_stub(
419 new protocol::MockClipboardStub());
420 EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
421 .Times(0);
422
423 // Start the input injector and screen capturer.
424 input_injector_->Start(clipboard_stub.PassAs<protocol::ClipboardStub>());
425
426 // Run the message loop until the desktop is attached.
427 setup_run_loop_->Run();
428
429 // Stop the test.
430 DeleteDesktopEnvironment();
431
432 task_runner_ = NULL;
433 io_task_runner_ = NULL;
434 main_run_loop_.Run();
435 }
436
437 // Tests that the video capturer receives a frame over IPC.
TEST_F(IpcDesktopEnvironmentTest,CaptureFrame)438 TEST_F(IpcDesktopEnvironmentTest, CaptureFrame) {
439 scoped_ptr<protocol::MockClipboardStub> clipboard_stub(
440 new protocol::MockClipboardStub());
441 EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
442 .Times(0);
443
444 // Start the input injector and screen capturer.
445 input_injector_->Start(clipboard_stub.PassAs<protocol::ClipboardStub>());
446 video_capturer_->Start(&screen_capturer_callback_);
447
448 // Run the message loop until the desktop is attached.
449 setup_run_loop_->Run();
450
451 // Stop the test when the first frame is captured.
452 EXPECT_CALL(screen_capturer_callback_, OnCaptureCompleted(_))
453 .WillOnce(DoAll(
454 DeleteArg<0>(),
455 InvokeWithoutArgs(
456 this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment)));
457
458 // Capture a single frame.
459 video_capturer_->Capture(webrtc::DesktopRegion());
460
461 task_runner_ = NULL;
462 io_task_runner_ = NULL;
463 main_run_loop_.Run();
464 }
465
466 // Tests that attaching to a new desktop works.
TEST_F(IpcDesktopEnvironmentTest,Reattach)467 TEST_F(IpcDesktopEnvironmentTest, Reattach) {
468 scoped_ptr<protocol::MockClipboardStub> clipboard_stub(
469 new protocol::MockClipboardStub());
470 EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
471 .Times(0);
472
473 // Start the input injector and screen capturer.
474 input_injector_->Start(clipboard_stub.PassAs<protocol::ClipboardStub>());
475 video_capturer_->Start(&screen_capturer_callback_);
476
477 // Run the message loop until the desktop is attached.
478 setup_run_loop_->Run();
479
480 // Create and start a new desktop process object.
481 setup_run_loop_.reset(new base::RunLoop());
482 DestoyDesktopProcess();
483 CreateDesktopProcess();
484 setup_run_loop_->Run();
485
486 // Stop the test.
487 DeleteDesktopEnvironment();
488
489 task_runner_ = NULL;
490 io_task_runner_ = NULL;
491 main_run_loop_.Run();
492 }
493
494 // Tests injection of clipboard events.
TEST_F(IpcDesktopEnvironmentTest,InjectClipboardEvent)495 TEST_F(IpcDesktopEnvironmentTest, InjectClipboardEvent) {
496 scoped_ptr<protocol::MockClipboardStub> clipboard_stub(
497 new protocol::MockClipboardStub());
498 clipboard_stub_ = clipboard_stub.get();
499
500 // Stop the test when a clipboard event is received from the desktop process.
501 EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
502 .Times(1)
503 .WillOnce(InvokeWithoutArgs(
504 this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
505
506 // Start the input injector and screen capturer.
507 input_injector_->Start(clipboard_stub.PassAs<protocol::ClipboardStub>());
508 video_capturer_->Start(&screen_capturer_callback_);
509
510 // Run the message loop until the desktop is attached.
511 setup_run_loop_->Run();
512
513 // Expect a single clipboard event.
514 EXPECT_CALL(*remote_input_injector_, InjectClipboardEvent(_))
515 .Times(1)
516 .WillOnce(Invoke(this,
517 &IpcDesktopEnvironmentTest::ReflectClipboardEvent));
518
519 // Send a clipboard event.
520 protocol::ClipboardEvent event;
521 event.set_mime_type(kMimeTypeTextUtf8);
522 event.set_data("a");
523 input_injector_->InjectClipboardEvent(event);
524
525 task_runner_ = NULL;
526 io_task_runner_ = NULL;
527 main_run_loop_.Run();
528 }
529
530 // Tests injection of key events.
TEST_F(IpcDesktopEnvironmentTest,InjectKeyEvent)531 TEST_F(IpcDesktopEnvironmentTest, InjectKeyEvent) {
532 scoped_ptr<protocol::MockClipboardStub> clipboard_stub(
533 new protocol::MockClipboardStub());
534 EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
535 .Times(0);
536
537 // Start the input injector and screen capturer.
538 input_injector_->Start(clipboard_stub.PassAs<protocol::ClipboardStub>());
539 video_capturer_->Start(&screen_capturer_callback_);
540
541 // Run the message loop until the desktop is attached.
542 setup_run_loop_->Run();
543
544 // Expect a single key event.
545 EXPECT_CALL(*remote_input_injector_, InjectKeyEvent(_))
546 .Times(AtLeast(1))
547 .WillRepeatedly(InvokeWithoutArgs(
548 this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
549
550 // Send a key event.
551 protocol::KeyEvent event;
552 event.set_usb_keycode(0x070004);
553 event.set_pressed(true);
554 input_injector_->InjectKeyEvent(event);
555
556 task_runner_ = NULL;
557 io_task_runner_ = NULL;
558 main_run_loop_.Run();
559 }
560
561 // Tests injection of text events.
TEST_F(IpcDesktopEnvironmentTest,InjectTextEvent)562 TEST_F(IpcDesktopEnvironmentTest, InjectTextEvent) {
563 scoped_ptr<protocol::MockClipboardStub> clipboard_stub(
564 new protocol::MockClipboardStub());
565 EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
566 .Times(0);
567
568 // Start the input injector and screen capturer.
569 input_injector_->Start(clipboard_stub.PassAs<protocol::ClipboardStub>());
570 video_capturer_->Start(&screen_capturer_callback_);
571
572 // Run the message loop until the desktop is attached.
573 setup_run_loop_->Run();
574
575 // Expect a single text event.
576 EXPECT_CALL(*remote_input_injector_, InjectTextEvent(_))
577 .Times(AtLeast(1))
578 .WillRepeatedly(InvokeWithoutArgs(
579 this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
580
581 // Send a text event.
582 protocol::TextEvent event;
583 event.set_text("hello");
584 input_injector_->InjectTextEvent(event);
585
586 task_runner_ = NULL;
587 io_task_runner_ = NULL;
588 main_run_loop_.Run();
589 }
590
591 // Tests injection of mouse events.
TEST_F(IpcDesktopEnvironmentTest,InjectMouseEvent)592 TEST_F(IpcDesktopEnvironmentTest, InjectMouseEvent) {
593 scoped_ptr<protocol::MockClipboardStub> clipboard_stub(
594 new protocol::MockClipboardStub());
595 EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
596 .Times(0);
597
598 // Start the input injector and screen capturer.
599 input_injector_->Start(clipboard_stub.PassAs<protocol::ClipboardStub>());
600 video_capturer_->Start(&screen_capturer_callback_);
601
602 // Run the message loop until the desktop is attached.
603 setup_run_loop_->Run();
604
605 // Expect a single mouse event.
606 EXPECT_CALL(*remote_input_injector_, InjectMouseEvent(_))
607 .Times(1)
608 .WillOnce(InvokeWithoutArgs(
609 this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
610
611 // Send a mouse event.
612 protocol::MouseEvent event;
613 event.set_x(0);
614 event.set_y(0);
615 input_injector_->InjectMouseEvent(event);
616
617 task_runner_ = NULL;
618 io_task_runner_ = NULL;
619 main_run_loop_.Run();
620 }
621
622 // Tests that setting the desktop resolution works.
TEST_F(IpcDesktopEnvironmentTest,SetScreenResolution)623 TEST_F(IpcDesktopEnvironmentTest, SetScreenResolution) {
624 scoped_ptr<protocol::MockClipboardStub> clipboard_stub(
625 new protocol::MockClipboardStub());
626 EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
627 .Times(0);
628
629 // Start the input injector and screen capturer.
630 input_injector_->Start(clipboard_stub.PassAs<protocol::ClipboardStub>());
631 video_capturer_->Start(&screen_capturer_callback_);
632
633 // Run the message loop until the desktop is attached.
634 setup_run_loop_->Run();
635
636 EXPECT_CALL(daemon_channel_, SetScreenResolution(_, _))
637 .Times(1)
638 .WillOnce(InvokeWithoutArgs(
639 this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
640
641 // Change the desktop resolution.
642 screen_controls_->SetScreenResolution(ScreenResolution(
643 webrtc::DesktopSize(100, 100),
644 webrtc::DesktopVector(96, 96)));
645
646 task_runner_ = NULL;
647 io_task_runner_ = NULL;
648 main_run_loop_.Run();
649 }
650
651 } // namespace remoting
652