This source file includes following definitions.
- ACTION_P2
- ACTION_P2
- ACTION_P2
- ACTION_P2
- ACTION_P2
- ACTION_P2
- SetUp
- TearDown
- DisconnectClientSession
- StopClientSession
- CreateDesktopEnvironment
- CreateInputInjector
- CreateVideoCapturer
- ConnectClientSession
- QuitMainMessageLoop
- MATCHER_P2
- TEST_F
- MATCHER_P2
- MATCHER_P2
- MATCHER_P2
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "base/message_loop/message_loop.h"
#include "base/test/test_simple_task_runner.h"
#include "remoting/base/auto_thread_task_runner.h"
#include "remoting/base/constants.h"
#include "remoting/host/audio_capturer.h"
#include "remoting/host/client_session.h"
#include "remoting/host/desktop_environment.h"
#include "remoting/host/host_mock_objects.h"
#include "remoting/host/screen_capturer_fake.h"
#include "remoting/protocol/protocol_mock_objects.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
#include "third_party/webrtc/modules/desktop_capture/screen_capturer_mock_objects.h"
namespace remoting {
using protocol::MockConnectionToClient;
using protocol::MockClientStub;
using protocol::MockHostStub;
using protocol::MockInputStub;
using protocol::MockSession;
using protocol::MockVideoStub;
using protocol::SessionConfig;
using testing::_;
using testing::AnyNumber;
using testing::AtMost;
using testing::DeleteArg;
using testing::DoAll;
using testing::Expectation;
using testing::Return;
using testing::ReturnRef;
using testing::Sequence;
using testing::StrEq;
using testing::StrictMock;
namespace {
ACTION_P2(InjectClipboardEvent, connection, event) {
connection->clipboard_stub()->InjectClipboardEvent(event);
}
ACTION_P2(InjectKeyEvent, connection, event) {
connection->input_stub()->InjectKeyEvent(event);
}
ACTION_P2(InjectMouseEvent, connection, event) {
connection->input_stub()->InjectMouseEvent(event);
}
ACTION_P2(LocalMouseMoved, client_session, event) {
client_session->OnLocalMouseMoved(
webrtc::DesktopVector(event.x(), event.y()));
}
ACTION_P2(SetGnubbyAuthHandlerForTesting, client_session, gnubby_auth_handler) {
client_session->SetGnubbyAuthHandlerForTesting(gnubby_auth_handler);
}
ACTION_P2(DeliverClientMessage, client_session, message) {
client_session->DeliverClientMessage(message);
}
}
class ClientSessionTest : public testing::Test {
public:
ClientSessionTest() : client_jid_("user@domain/rest-of-jid") {}
virtual void SetUp() OVERRIDE;
virtual void TearDown() OVERRIDE;
void DisconnectClientSession();
void StopClientSession();
protected:
DesktopEnvironment* CreateDesktopEnvironment();
InputInjector* CreateInputInjector();
webrtc::ScreenCapturer* CreateVideoCapturer();
void ConnectClientSession();
void QuitMainMessageLoop();
base::MessageLoop message_loop_;
scoped_ptr<ClientSession> client_session_;
MockClientSessionEventHandler session_event_handler_;
SessionConfig session_config_;
const std::string client_jid_;
MockClientStub client_stub_;
MockVideoStub video_stub_;
scoped_ptr<MockInputInjector> input_injector_;
MockConnectionToClient* connection_;
scoped_ptr<MockDesktopEnvironmentFactory> desktop_environment_factory_;
};
void ClientSessionTest::SetUp() {
scoped_refptr<AutoThreadTaskRunner> ui_task_runner = new AutoThreadTaskRunner(
message_loop_.message_loop_proxy(),
base::Bind(&ClientSessionTest::QuitMainMessageLoop,
base::Unretained(this)));
desktop_environment_factory_.reset(new MockDesktopEnvironmentFactory());
EXPECT_CALL(*desktop_environment_factory_, CreatePtr())
.Times(AnyNumber())
.WillRepeatedly(Invoke(this,
&ClientSessionTest::CreateDesktopEnvironment));
EXPECT_CALL(*desktop_environment_factory_, SupportsAudioCapture())
.Times(AnyNumber())
.WillRepeatedly(Return(false));
input_injector_.reset(new MockInputInjector());
session_config_ = SessionConfig::ForTest();
protocol::MockSession* session = new MockSession();
EXPECT_CALL(*session, config()).WillRepeatedly(ReturnRef(session_config_));
EXPECT_CALL(*session, jid()).WillRepeatedly(ReturnRef(client_jid_));
EXPECT_CALL(*session, SetEventHandler(_));
scoped_ptr<MockConnectionToClient> connection(
new MockConnectionToClient(session, NULL));
EXPECT_CALL(*connection, session()).WillRepeatedly(Return(session));
EXPECT_CALL(*connection, client_stub())
.WillRepeatedly(Return(&client_stub_));
EXPECT_CALL(*connection, video_stub()).WillRepeatedly(Return(&video_stub_));
EXPECT_CALL(*connection, Disconnect());
connection_ = connection.get();
client_session_.reset(new ClientSession(
&session_event_handler_,
ui_task_runner,
ui_task_runner,
ui_task_runner,
ui_task_runner,
ui_task_runner,
ui_task_runner,
connection.PassAs<protocol::ConnectionToClient>(),
desktop_environment_factory_.get(),
base::TimeDelta(),
NULL));
}
void ClientSessionTest::TearDown() {
EXPECT_TRUE(!client_session_);
}
void ClientSessionTest::DisconnectClientSession() {
client_session_->DisconnectSession();
client_session_->OnConnectionClosed(client_session_->connection(),
protocol::OK);
}
void ClientSessionTest::StopClientSession() {
client_session_.reset();
desktop_environment_factory_.reset();
}
DesktopEnvironment* ClientSessionTest::CreateDesktopEnvironment() {
MockDesktopEnvironment* desktop_environment = new MockDesktopEnvironment();
EXPECT_CALL(*desktop_environment, CreateAudioCapturerPtr())
.Times(0);
EXPECT_CALL(*desktop_environment, CreateInputInjectorPtr())
.WillOnce(Invoke(this, &ClientSessionTest::CreateInputInjector));
EXPECT_CALL(*desktop_environment, CreateScreenControlsPtr())
.Times(AtMost(1));
EXPECT_CALL(*desktop_environment, CreateVideoCapturerPtr())
.WillOnce(Invoke(this, &ClientSessionTest::CreateVideoCapturer));
EXPECT_CALL(*desktop_environment, GetCapabilities())
.Times(AtMost(1));
EXPECT_CALL(*desktop_environment, SetCapabilities(_))
.Times(AtMost(1));
return desktop_environment;
}
InputInjector* ClientSessionTest::CreateInputInjector() {
EXPECT_TRUE(input_injector_);
return input_injector_.release();
}
webrtc::ScreenCapturer* ClientSessionTest::CreateVideoCapturer() {
return new ScreenCapturerFake();
}
void ClientSessionTest::ConnectClientSession() {
client_session_->OnConnectionAuthenticated(client_session_->connection());
client_session_->OnConnectionChannelsConnected(client_session_->connection());
}
void ClientSessionTest::QuitMainMessageLoop() {
message_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
}
MATCHER_P2(EqualsClipboardEvent, m, d, "") {
return (strcmp(arg.mime_type().c_str(), m) == 0 &&
memcmp(arg.data().data(), d, arg.data().size()) == 0);
}
TEST_F(ClientSessionTest, ClipboardStubFilter) {
protocol::ClipboardEvent clipboard_event1;
clipboard_event1.set_mime_type(kMimeTypeTextUtf8);
clipboard_event1.set_data("a");
protocol::ClipboardEvent clipboard_event2;
clipboard_event2.set_mime_type(kMimeTypeTextUtf8);
clipboard_event2.set_data("b");
protocol::ClipboardEvent clipboard_event3;
clipboard_event3.set_mime_type(kMimeTypeTextUtf8);
clipboard_event3.set_data("c");
Expectation authenticated =
EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_))
.WillOnce(Return(true));
EXPECT_CALL(*input_injector_, StartPtr(_))
.After(authenticated);
EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_))
.After(authenticated);
Sequence s;
EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _))
.InSequence(s)
.After(authenticated)
.WillOnce(DoAll(
InjectClipboardEvent(connection_, clipboard_event2),
InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession),
InjectClipboardEvent(connection_, clipboard_event3),
InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession)));
EXPECT_CALL(*input_injector_, InjectClipboardEvent(EqualsClipboardEvent(
kMimeTypeTextUtf8, "b")))
.InSequence(s);
EXPECT_CALL(session_event_handler_, OnSessionClosed(_))
.InSequence(s);
connection_->clipboard_stub()->InjectClipboardEvent(clipboard_event1);
ConnectClientSession();
message_loop_.Run();
}
namespace {
MATCHER_P2(EqualsUsbEvent, usb_keycode, pressed, "") {
return arg.usb_keycode() == (unsigned int)usb_keycode &&
arg.pressed() == pressed;
}
MATCHER_P2(EqualsMouseEvent, x, y, "") {
return arg.x() == x && arg.y() == y;
}
MATCHER_P2(EqualsMouseButtonEvent, button, down, "") {
return arg.button() == button && arg.button_down() == down;
}
}
TEST_F(ClientSessionTest, InputStubFilter) {
protocol::KeyEvent key_event1;
key_event1.set_pressed(true);
key_event1.set_usb_keycode(1);
protocol::KeyEvent key_event2_down;
key_event2_down.set_pressed(true);
key_event2_down.set_usb_keycode(2);
protocol::KeyEvent key_event2_up;
key_event2_up.set_pressed(false);
key_event2_up.set_usb_keycode(2);
protocol::KeyEvent key_event3;
key_event3.set_pressed(true);
key_event3.set_usb_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);
Expectation authenticated =
EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_))
.WillOnce(Return(true));
EXPECT_CALL(*input_injector_, StartPtr(_))
.After(authenticated);
EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_))
.After(authenticated);
Sequence s;
EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _))
.InSequence(s)
.After(authenticated)
.WillOnce(DoAll(
InjectKeyEvent(connection_, key_event2_down),
InjectKeyEvent(connection_, key_event2_up),
InjectMouseEvent(connection_, mouse_event2),
InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession),
InjectKeyEvent(connection_, key_event3),
InjectMouseEvent(connection_, mouse_event3),
InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession)));
EXPECT_CALL(*input_injector_, InjectKeyEvent(EqualsUsbEvent(2, true)))
.InSequence(s);
EXPECT_CALL(*input_injector_, InjectKeyEvent(EqualsUsbEvent(2, false)))
.InSequence(s);
EXPECT_CALL(*input_injector_, InjectMouseEvent(EqualsMouseEvent(200, 201)))
.InSequence(s);
EXPECT_CALL(session_event_handler_, OnSessionClosed(_))
.InSequence(s);
connection_->input_stub()->InjectKeyEvent(key_event1);
connection_->input_stub()->InjectMouseEvent(mouse_event1);
ConnectClientSession();
message_loop_.Run();
}
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);
Expectation authenticated =
EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_))
.WillOnce(Return(true));
EXPECT_CALL(*input_injector_, StartPtr(_))
.After(authenticated);
EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_))
.After(authenticated);
Sequence s;
EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _))
.InSequence(s)
.After(authenticated)
.WillOnce(DoAll(
InjectMouseEvent(connection_, mouse_event1),
#if !defined(OS_WIN)
LocalMouseMoved(client_session_.get(), mouse_event1),
#endif
InjectMouseEvent(connection_, mouse_event2),
LocalMouseMoved(client_session_.get(), mouse_event1),
InjectMouseEvent(connection_, mouse_event3),
InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession),
InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession)));
EXPECT_CALL(*input_injector_, InjectMouseEvent(EqualsMouseEvent(100, 101)))
.InSequence(s);
EXPECT_CALL(*input_injector_, InjectMouseEvent(EqualsMouseEvent(200, 201)))
.InSequence(s);
EXPECT_CALL(session_event_handler_, OnSessionClosed(_))
.InSequence(s);
ConnectClientSession();
message_loop_.Run();
}
TEST_F(ClientSessionTest, RestoreEventState) {
protocol::KeyEvent key1;
key1.set_pressed(true);
key1.set_usb_keycode(1);
protocol::KeyEvent key2;
key2.set_pressed(true);
key2.set_usb_keycode(2);
protocol::MouseEvent mousedown;
mousedown.set_button(protocol::MouseEvent::BUTTON_LEFT);
mousedown.set_button_down(true);
Expectation authenticated =
EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_))
.WillOnce(Return(true));
EXPECT_CALL(*input_injector_, StartPtr(_))
.After(authenticated);
EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_))
.After(authenticated);
Sequence s;
EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _))
.InSequence(s)
.After(authenticated)
.WillOnce(DoAll(
InjectKeyEvent(connection_, key1),
InjectKeyEvent(connection_, key2),
InjectMouseEvent(connection_, mousedown),
InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession),
InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession)));
EXPECT_CALL(*input_injector_, InjectKeyEvent(EqualsUsbEvent(1, true)))
.InSequence(s);
EXPECT_CALL(*input_injector_, InjectKeyEvent(EqualsUsbEvent(2, true)))
.InSequence(s);
EXPECT_CALL(*input_injector_, InjectMouseEvent(EqualsMouseButtonEvent(
protocol::MouseEvent::BUTTON_LEFT, true)))
.InSequence(s);
EXPECT_CALL(*input_injector_, InjectKeyEvent(EqualsUsbEvent(1, false)))
.InSequence(s);
EXPECT_CALL(*input_injector_, InjectKeyEvent(EqualsUsbEvent(2, false)))
.InSequence(s);
EXPECT_CALL(*input_injector_, InjectMouseEvent(EqualsMouseButtonEvent(
protocol::MouseEvent::BUTTON_LEFT, false)))
.InSequence(s);
EXPECT_CALL(session_event_handler_, OnSessionClosed(_))
.InSequence(s);
ConnectClientSession();
message_loop_.Run();
}
TEST_F(ClientSessionTest, ClampMouseEvents) {
Expectation authenticated =
EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_))
.WillOnce(Return(true));
EXPECT_CALL(*input_injector_, StartPtr(_))
.After(authenticated);
EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_))
.After(authenticated);
EXPECT_CALL(session_event_handler_, OnSessionClosed(_))
.After(authenticated);
Expectation connected = authenticated;
int input_x[3] = { -999, 100, 999 };
int expected_x[3] = { 0, 100, ScreenCapturerFake::kWidth - 1 };
int input_y[3] = { -999, 50, 999 };
int expected_y[3] = { 0, 50, ScreenCapturerFake::kHeight - 1 };
protocol::MouseEvent expected_event;
for (int j = 0; j < 3; j++) {
for (int i = 0; i < 3; i++) {
protocol::MouseEvent injected_event;
injected_event.set_x(input_x[i]);
injected_event.set_y(input_y[j]);
if (i == 0 && j == 0) {
connected =
EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _))
.After(connected)
.WillOnce(InjectMouseEvent(connection_, injected_event));
} else {
connected =
EXPECT_CALL(*input_injector_,
InjectMouseEvent(EqualsMouseEvent(expected_event.x(),
expected_event.y())))
.After(connected)
.WillOnce(InjectMouseEvent(connection_, injected_event));
}
expected_event.set_x(expected_x[i]);
expected_event.set_y(expected_y[j]);
}
}
EXPECT_CALL(*input_injector_,
InjectMouseEvent(EqualsMouseEvent(expected_event.x(),
expected_event.y())))
.After(connected)
.WillOnce(DoAll(
InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession),
InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession)));
ConnectClientSession();
message_loop_.Run();
}
TEST_F(ClientSessionTest, NoGnubbyAuth) {
protocol::ExtensionMessage message;
message.set_type("gnubby-auth");
message.set_data("test");
Expectation authenticated =
EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_))
.WillOnce(Return(true));
EXPECT_CALL(*input_injector_, StartPtr(_)).After(authenticated);
EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_))
.After(authenticated)
.WillOnce(DoAll(
DeliverClientMessage(client_session_.get(), message),
InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession),
InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession)));
EXPECT_CALL(session_event_handler_, OnSessionClosed(_));
ConnectClientSession();
message_loop_.Run();
}
TEST_F(ClientSessionTest, EnableGnubbyAuth) {
MockGnubbyAuthHandler* gnubby_auth_handler = new MockGnubbyAuthHandler();
protocol::ExtensionMessage message;
message.set_type("gnubby-auth");
message.set_data("test");
Expectation authenticated =
EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_))
.WillOnce(Return(true));
EXPECT_CALL(*input_injector_, StartPtr(_)).After(authenticated);
EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_))
.After(authenticated)
.WillOnce(DoAll(
SetGnubbyAuthHandlerForTesting(client_session_.get(),
gnubby_auth_handler),
DeliverClientMessage(client_session_.get(), message),
InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession),
InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession)));
EXPECT_CALL(*gnubby_auth_handler, DeliverClientMessage(_));
EXPECT_CALL(session_event_handler_, OnSessionClosed(_));
ConnectClientSession();
message_loop_.Run();
}
}