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