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 38using testing::_; 39using testing::AnyNumber; 40using testing::AtLeast; 41using testing::AtMost; 42using testing::DeleteArg; 43using testing::DoAll; 44using testing::Return; 45using testing::ReturnRef; 46 47namespace remoting { 48 49namespace { 50 51// Receives messages sent from the network process to the daemon. 52class 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. 71class 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 86bool FakeDaemonSender::Send(IPC::Message* message) { 87 OnMessageReceived(*message); 88 delete message; 89 return true; 90} 91 92void 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 107bool 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 121class 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 222IpcDesktopEnvironmentTest::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 230IpcDesktopEnvironmentTest::~IpcDesktopEnvironmentTest() { 231} 232 233void 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 300void 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 310void 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 318DesktopEnvironment* 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 347InputInjector* 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 355webrtc::DesktopCapturer* IpcDesktopEnvironmentTest::CreateVideoCapturer() { 356 return new FakeDesktopCapturer(); 357} 358 359webrtc::MouseCursorMonitor* 360IpcDesktopEnvironmentTest::CreateMouseCursorMonitor() { 361 return new FakeMouseCursorMonitor(); 362} 363 364void IpcDesktopEnvironmentTest::DeleteDesktopEnvironment() { 365 input_injector_.reset(); 366 screen_controls_.reset(); 367 video_capturer_.reset(); 368 369 // Trigger DisconnectTerminal(). 370 desktop_environment_.reset(); 371} 372 373void IpcDesktopEnvironmentTest::ReflectClipboardEvent( 374 const protocol::ClipboardEvent& event) { 375 clipboard_stub_->InjectClipboardEvent(event); 376} 377 378void 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 409void 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 418void IpcDesktopEnvironmentTest::OnDisconnectCallback() { 419 DeleteDesktopEnvironment(); 420} 421 422void 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. 431TEST_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. 452TEST_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. 481TEST_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. 509TEST_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. 545TEST_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. 576TEST_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. 606TEST_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. 637TEST_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 666