// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "remoting/host/client_session.h" #include "remoting/host/host_mock_objects.h" #include "remoting/protocol/protocol_mock_objects.h" #include "testing/gtest/include/gtest/gtest.h" namespace remoting { namespace { // A task that does nothing. class DummyTask : public Task { public: void Run() {} }; } // namespace using protocol::MockConnectionToClient; using protocol::MockConnectionToClientEventHandler; using protocol::MockHostStub; using protocol::MockInputStub; using testing::_; using testing::DeleteArg; using testing::InSequence; using testing::Return; class ClientSessionTest : public testing::Test { public: ClientSessionTest() {} virtual void SetUp() { connection_ = new MockConnectionToClient(&message_loop_, &connection_event_handler_, &host_stub_, &input_stub_); user_authenticator_ = new MockUserAuthenticator(); client_session_ = new ClientSession( &session_event_handler_, user_authenticator_, connection_, &input_stub_); ON_CALL(input_stub_, InjectKeyEvent(_, _)).WillByDefault(DeleteArg<1>()); ON_CALL(input_stub_, InjectMouseEvent(_, _)).WillByDefault(DeleteArg<1>()); } protected: MessageLoop message_loop_; MockConnectionToClientEventHandler connection_event_handler_; MockHostStub host_stub_; MockInputStub input_stub_; MockClientSessionEventHandler session_event_handler_; MockUserAuthenticator* user_authenticator_; scoped_refptr connection_; scoped_refptr client_session_; }; TEST_F(ClientSessionTest, InputStubFilter) { protocol::KeyEvent key_event1; key_event1.set_pressed(true); key_event1.set_keycode(1); protocol::KeyEvent key_event2_down; key_event2_down.set_pressed(true); key_event2_down.set_keycode(2); protocol::KeyEvent key_event2_up; key_event2_up.set_pressed(false); key_event2_up.set_keycode(2); protocol::KeyEvent key_event3; key_event3.set_pressed(true); key_event3.set_keycode(3); protocol::MouseEvent mouse_event1; mouse_event1.set_x(100); mouse_event1.set_y(101); protocol::MouseEvent mouse_event2; mouse_event2.set_x(200); mouse_event2.set_y(201); protocol::MouseEvent mouse_event3; mouse_event3.set_x(300); mouse_event3.set_y(301); protocol::LocalLoginCredentials credentials; credentials.set_type(protocol::PASSWORD); credentials.set_username("user"); credentials.set_credential("password"); InSequence s; EXPECT_CALL(*user_authenticator_, Authenticate(_, _)) .WillOnce(Return(true)); EXPECT_CALL(session_event_handler_, LocalLoginSucceeded(_)); EXPECT_CALL(input_stub_, InjectKeyEvent(&key_event2_down, _)); EXPECT_CALL(input_stub_, InjectKeyEvent(&key_event2_up, _)); EXPECT_CALL(input_stub_, InjectMouseEvent(&mouse_event2, _)); EXPECT_CALL(*connection_.get(), Disconnect()); // These events should not get through to the input stub, // because the client isn't authenticated yet. client_session_->InjectKeyEvent(&key_event1, new DummyTask()); client_session_->InjectMouseEvent(&mouse_event1, new DummyTask()); client_session_->BeginSessionRequest(&credentials, new DummyTask()); // These events should get through to the input stub. client_session_->InjectKeyEvent(&key_event2_down, new DummyTask()); client_session_->InjectKeyEvent(&key_event2_up, new DummyTask()); client_session_->InjectMouseEvent(&mouse_event2, new DummyTask()); client_session_->Disconnect(); // These events should not get through to the input stub, // because the client has disconnected. client_session_->InjectKeyEvent(&key_event3, new DummyTask()); client_session_->InjectMouseEvent(&mouse_event3, new DummyTask()); } TEST_F(ClientSessionTest, LocalInputTest) { protocol::MouseEvent mouse_event1; mouse_event1.set_x(100); mouse_event1.set_y(101); protocol::MouseEvent mouse_event2; mouse_event2.set_x(200); mouse_event2.set_y(201); protocol::MouseEvent mouse_event3; mouse_event3.set_x(300); mouse_event3.set_y(301); protocol::LocalLoginCredentials credentials; credentials.set_type(protocol::PASSWORD); credentials.set_username("user"); credentials.set_credential("password"); InSequence s; EXPECT_CALL(*user_authenticator_, Authenticate(_, _)) .WillOnce(Return(true)); EXPECT_CALL(session_event_handler_, LocalLoginSucceeded(_)); EXPECT_CALL(input_stub_, InjectMouseEvent(&mouse_event1, _)); EXPECT_CALL(input_stub_, InjectMouseEvent(&mouse_event2, _)); EXPECT_CALL(*connection_.get(), Disconnect()); client_session_->BeginSessionRequest(&credentials, new DummyTask()); // This event should get through to the input stub. client_session_->InjectMouseEvent(&mouse_event1, new DummyTask()); // This one should too because the local event echoes the remote one. client_session_->LocalMouseMoved(gfx::Point(mouse_event1.x(), mouse_event1.y())); client_session_->InjectMouseEvent(&mouse_event2, new DummyTask()); // This one should not. client_session_->LocalMouseMoved(gfx::Point(mouse_event1.x(), mouse_event1.y())); client_session_->InjectMouseEvent(&mouse_event3, new DummyTask()); // TODO(jamiewalch): Verify that remote inputs are re-enabled eventually // (via dependency injection, not sleep!) client_session_->Disconnect(); } MATCHER_P(IsMatchingKeyUp, k, "") { return !arg->pressed() && arg->keycode() == k->keycode(); } TEST_F(ClientSessionTest, UnpressKeys) { protocol::KeyEvent key1; key1.set_pressed(true); key1.set_keycode(1); protocol::KeyEvent key2; key2.set_pressed(true); key2.set_keycode(2); client_session_->RecordKeyEvent(&key1); client_session_->RecordKeyEvent(&key2); EXPECT_CALL(input_stub_, InjectKeyEvent(IsMatchingKeyUp(&key1), _)); EXPECT_CALL(input_stub_, InjectKeyEvent(IsMatchingKeyUp(&key2), _)); client_session_->UnpressKeys(); } } // namespace remoting