This source file includes following definitions.
- OnMessageReceived
- OnMessageReceived
- client_session_control_factory_
- SetUp
- ConnectTerminal
- DisconnectTerminal
- CreateDesktopEnvironment
- CreateInputInjector
- CreateVideoCapturer
- DeleteDesktopEnvironment
- ReflectClipboardEvent
- CreateDesktopProcess
- DestoyDesktopProcess
- OnDisconnectCallback
- OnDesktopAttached
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/process/process.h"
#include "base/process/process_handle.h"
#include "base/run_loop.h"
#include "ipc/ipc_channel.h"
#include "ipc/ipc_channel_proxy.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_platform_file.h"
#include "remoting/base/auto_thread.h"
#include "remoting/base/auto_thread_task_runner.h"
#include "remoting/base/constants.h"
#include "remoting/host/chromoting_messages.h"
#include "remoting/host/desktop_process.h"
#include "remoting/host/desktop_session.h"
#include "remoting/host/desktop_session_connector.h"
#include "remoting/host/desktop_session_proxy.h"
#include "remoting/host/host_mock_objects.h"
#include "remoting/host/ipc_desktop_environment.h"
#include "remoting/host/screen_capturer_fake.h"
#include "remoting/protocol/protocol_mock_objects.h"
#include "testing/gmock/include/gmock/gmock.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"
using testing::_;
using testing::AnyNumber;
using testing::AtLeast;
using testing::AtMost;
using testing::DeleteArg;
using testing::DoAll;
using testing::Return;
using testing::ReturnRef;
namespace remoting {
namespace {
class FakeDaemonSender : public IPC::Sender {
public:
FakeDaemonSender() {}
virtual ~FakeDaemonSender() {}
virtual bool Send(IPC::Message* message) OVERRIDE;
MOCK_METHOD3(ConnectTerminal, void(int, const ScreenResolution&, bool));
MOCK_METHOD1(DisconnectTerminal, void(int));
MOCK_METHOD2(SetScreenResolution, void(int, const ScreenResolution&));
private:
void OnMessageReceived(const IPC::Message& message);
DISALLOW_COPY_AND_ASSIGN(FakeDaemonSender);
};
class MockDaemonListener : public IPC::Listener {
public:
MockDaemonListener() {}
virtual ~MockDaemonListener() {}
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
MOCK_METHOD1(OnDesktopAttached, void(IPC::PlatformFileForTransit));
MOCK_METHOD1(OnChannelConnected, void(int32));
MOCK_METHOD0(OnChannelError, void());
private:
DISALLOW_COPY_AND_ASSIGN(MockDaemonListener);
};
bool FakeDaemonSender::Send(IPC::Message* message) {
OnMessageReceived(*message);
delete message;
return true;
}
void FakeDaemonSender::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(FakeDaemonSender, message)
IPC_MESSAGE_HANDLER(ChromotingNetworkHostMsg_ConnectTerminal,
ConnectTerminal)
IPC_MESSAGE_HANDLER(ChromotingNetworkHostMsg_DisconnectTerminal,
DisconnectTerminal)
IPC_MESSAGE_HANDLER(ChromotingNetworkDaemonMsg_SetScreenResolution,
SetScreenResolution)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
EXPECT_TRUE(handled);
}
bool MockDaemonListener::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(MockDaemonListener, message)
IPC_MESSAGE_HANDLER(ChromotingDesktopDaemonMsg_DesktopAttached,
OnDesktopAttached)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
EXPECT_TRUE(handled);
return handled;
}
}
class IpcDesktopEnvironmentTest : public testing::Test {
public:
IpcDesktopEnvironmentTest();
virtual ~IpcDesktopEnvironmentTest();
virtual void SetUp() OVERRIDE;
void ConnectTerminal(int terminal_id,
const ScreenResolution& resolution,
bool virtual_terminal);
void DisconnectTerminal(int terminal_id);
DesktopEnvironment* CreateDesktopEnvironment();
InputInjector* CreateInputInjector();
webrtc::ScreenCapturer* CreateVideoCapturer();
void DeleteDesktopEnvironment();
void ReflectClipboardEvent(const protocol::ClipboardEvent& event);
protected:
void CreateDesktopProcess();
void DestoyDesktopProcess();
void OnDisconnectCallback();
void OnDesktopAttached(IPC::PlatformFileForTransit desktop_pipe);
base::MessageLoopForUI message_loop_;
scoped_ptr<base::RunLoop> setup_run_loop_;
base::RunLoop main_run_loop_;
scoped_refptr<AutoThreadTaskRunner> task_runner_;
scoped_refptr<AutoThreadTaskRunner> io_task_runner_;
std::string client_jid_;
protocol::ClipboardStub* clipboard_stub_;
scoped_ptr<IPC::ChannelProxy> desktop_channel_;
std::string desktop_channel_name_;
MockDaemonListener desktop_listener_;
FakeDaemonSender daemon_channel_;
scoped_ptr<IpcDesktopEnvironmentFactory> desktop_environment_factory_;
scoped_ptr<DesktopEnvironment> desktop_environment_;
scoped_ptr<InputInjector> input_injector_;
scoped_ptr<ScreenControls> screen_controls_;
scoped_ptr<webrtc::ScreenCapturer> video_capturer_;
scoped_ptr<DesktopProcess> desktop_process_;
MockInputInjector* remote_input_injector_;
int terminal_id_;
webrtc::MockScreenCapturerCallback screen_capturer_callback_;
MockClientSessionControl client_session_control_;
base::WeakPtrFactory<ClientSessionControl> client_session_control_factory_;
};
IpcDesktopEnvironmentTest::IpcDesktopEnvironmentTest()
: client_jid_("user@domain/rest-of-jid"),
clipboard_stub_(NULL),
remote_input_injector_(NULL),
terminal_id_(-1),
client_session_control_factory_(&client_session_control_) {
}
IpcDesktopEnvironmentTest::~IpcDesktopEnvironmentTest() {
}
void IpcDesktopEnvironmentTest::SetUp() {
task_runner_ = new AutoThreadTaskRunner(
message_loop_.message_loop_proxy(), main_run_loop_.QuitClosure());
io_task_runner_ = AutoThread::CreateWithType(
"IPC thread", task_runner_, base::MessageLoop::TYPE_IO);
setup_run_loop_.reset(new base::RunLoop());
EXPECT_CALL(desktop_listener_, OnChannelConnected(_))
.Times(AnyNumber());
EXPECT_CALL(desktop_listener_, OnDesktopAttached(_))
.Times(AnyNumber())
.WillRepeatedly(Invoke(this,
&IpcDesktopEnvironmentTest::OnDesktopAttached));
EXPECT_CALL(desktop_listener_, OnChannelError())
.Times(AnyNumber())
.WillOnce(Invoke(this,
&IpcDesktopEnvironmentTest::DestoyDesktopProcess));
EXPECT_CALL(daemon_channel_, ConnectTerminal(_, _, _))
.Times(AnyNumber())
.WillRepeatedly(Invoke(this,
&IpcDesktopEnvironmentTest::ConnectTerminal));
EXPECT_CALL(daemon_channel_, DisconnectTerminal(_))
.Times(AnyNumber())
.WillRepeatedly(Invoke(this,
&IpcDesktopEnvironmentTest::DisconnectTerminal));
EXPECT_CALL(client_session_control_, client_jid())
.Times(AnyNumber())
.WillRepeatedly(ReturnRef(client_jid_));
EXPECT_CALL(client_session_control_, DisconnectSession())
.Times(AnyNumber())
.WillRepeatedly(Invoke(
this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
EXPECT_CALL(client_session_control_, OnLocalMouseMoved(_))
.Times(0);
EXPECT_CALL(client_session_control_, SetDisableInputs(_))
.Times(0);
desktop_environment_factory_.reset(new IpcDesktopEnvironmentFactory(
task_runner_,
task_runner_,
task_runner_,
io_task_runner_,
&daemon_channel_));
desktop_environment_ = desktop_environment_factory_->Create(
client_session_control_factory_.GetWeakPtr());
screen_controls_ = desktop_environment_->CreateScreenControls();
input_injector_ = desktop_environment_->CreateInputInjector();
video_capturer_ =
desktop_environment_->CreateVideoCapturer();
desktop_environment_->SetCapabilities(std::string());
}
void IpcDesktopEnvironmentTest::ConnectTerminal(
int terminal_id,
const ScreenResolution& resolution,
bool virtual_terminal) {
EXPECT_NE(terminal_id_, terminal_id);
terminal_id_ = terminal_id;
CreateDesktopProcess();
}
void IpcDesktopEnvironmentTest::DisconnectTerminal(int terminal_id) {
EXPECT_EQ(terminal_id_, terminal_id);
desktop_environment_factory_.reset();
}
DesktopEnvironment* IpcDesktopEnvironmentTest::CreateDesktopEnvironment() {
MockDesktopEnvironment* desktop_environment = new MockDesktopEnvironment();
EXPECT_CALL(*desktop_environment, CreateAudioCapturerPtr())
.Times(0);
EXPECT_CALL(*desktop_environment, CreateInputInjectorPtr())
.Times(AtMost(1))
.WillOnce(Invoke(
this, &IpcDesktopEnvironmentTest::CreateInputInjector));
EXPECT_CALL(*desktop_environment, CreateScreenControlsPtr())
.Times(AtMost(1));
EXPECT_CALL(*desktop_environment, CreateVideoCapturerPtr())
.Times(AtMost(1))
.WillOnce(Invoke(
this, &IpcDesktopEnvironmentTest::CreateVideoCapturer));
EXPECT_CALL(*desktop_environment, GetCapabilities())
.Times(AtMost(1));
EXPECT_CALL(*desktop_environment, SetCapabilities(_))
.Times(AtMost(1));
message_loop_.PostTask(FROM_HERE, setup_run_loop_->QuitClosure());
return desktop_environment;
}
InputInjector* IpcDesktopEnvironmentTest::CreateInputInjector() {
EXPECT_TRUE(remote_input_injector_ == NULL);
remote_input_injector_ = new testing::StrictMock<MockInputInjector>();
EXPECT_CALL(*remote_input_injector_, StartPtr(_));
return remote_input_injector_;
}
webrtc::ScreenCapturer* IpcDesktopEnvironmentTest::CreateVideoCapturer() {
return new ScreenCapturerFake();
}
void IpcDesktopEnvironmentTest::DeleteDesktopEnvironment() {
input_injector_.reset();
screen_controls_.reset();
video_capturer_.reset();
desktop_environment_.reset();
}
void IpcDesktopEnvironmentTest::ReflectClipboardEvent(
const protocol::ClipboardEvent& event) {
clipboard_stub_->InjectClipboardEvent(event);
}
void IpcDesktopEnvironmentTest::CreateDesktopProcess() {
EXPECT_TRUE(task_runner_.get());
EXPECT_TRUE(io_task_runner_.get());
desktop_channel_name_ = IPC::Channel::GenerateUniqueRandomChannelID();
desktop_channel_.reset(
new IPC::ChannelProxy(IPC::ChannelHandle(desktop_channel_name_),
IPC::Channel::MODE_SERVER,
&desktop_listener_,
io_task_runner_.get()));
desktop_process_.reset(new DesktopProcess(task_runner_,
io_task_runner_,
desktop_channel_name_));
scoped_ptr<MockDesktopEnvironmentFactory> desktop_environment_factory(
new MockDesktopEnvironmentFactory());
EXPECT_CALL(*desktop_environment_factory, CreatePtr())
.Times(AnyNumber())
.WillRepeatedly(Invoke(
this, &IpcDesktopEnvironmentTest::CreateDesktopEnvironment));
EXPECT_CALL(*desktop_environment_factory, SupportsAudioCapture())
.Times(AnyNumber())
.WillRepeatedly(Return(false));
EXPECT_TRUE(desktop_process_->Start(
desktop_environment_factory.PassAs<DesktopEnvironmentFactory>()));
}
void IpcDesktopEnvironmentTest::DestoyDesktopProcess() {
desktop_channel_.reset();
if (desktop_process_) {
desktop_process_->OnChannelError();
desktop_process_.reset();
}
remote_input_injector_ = NULL;
}
void IpcDesktopEnvironmentTest::OnDisconnectCallback() {
DeleteDesktopEnvironment();
}
void IpcDesktopEnvironmentTest::OnDesktopAttached(
IPC::PlatformFileForTransit desktop_pipe) {
desktop_environment_factory_->OnDesktopSessionAgentAttached(
terminal_id_, base::GetCurrentProcessHandle(), desktop_pipe);
}
TEST_F(IpcDesktopEnvironmentTest, Basic) {
scoped_ptr<protocol::MockClipboardStub> clipboard_stub(
new protocol::MockClipboardStub());
EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
.Times(0);
input_injector_->Start(clipboard_stub.PassAs<protocol::ClipboardStub>());
setup_run_loop_->Run();
DeleteDesktopEnvironment();
task_runner_ = NULL;
io_task_runner_ = NULL;
main_run_loop_.Run();
}
TEST_F(IpcDesktopEnvironmentTest, CaptureFrame) {
scoped_ptr<protocol::MockClipboardStub> clipboard_stub(
new protocol::MockClipboardStub());
EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
.Times(0);
input_injector_->Start(clipboard_stub.PassAs<protocol::ClipboardStub>());
video_capturer_->Start(&screen_capturer_callback_);
setup_run_loop_->Run();
EXPECT_CALL(screen_capturer_callback_, OnCaptureCompleted(_))
.WillOnce(DoAll(
DeleteArg<0>(),
InvokeWithoutArgs(
this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment)));
video_capturer_->Capture(webrtc::DesktopRegion());
task_runner_ = NULL;
io_task_runner_ = NULL;
main_run_loop_.Run();
}
TEST_F(IpcDesktopEnvironmentTest, Reattach) {
scoped_ptr<protocol::MockClipboardStub> clipboard_stub(
new protocol::MockClipboardStub());
EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
.Times(0);
input_injector_->Start(clipboard_stub.PassAs<protocol::ClipboardStub>());
video_capturer_->Start(&screen_capturer_callback_);
setup_run_loop_->Run();
setup_run_loop_.reset(new base::RunLoop());
DestoyDesktopProcess();
CreateDesktopProcess();
setup_run_loop_->Run();
DeleteDesktopEnvironment();
task_runner_ = NULL;
io_task_runner_ = NULL;
main_run_loop_.Run();
}
TEST_F(IpcDesktopEnvironmentTest, InjectClipboardEvent) {
scoped_ptr<protocol::MockClipboardStub> clipboard_stub(
new protocol::MockClipboardStub());
clipboard_stub_ = clipboard_stub.get();
EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
.Times(1)
.WillOnce(InvokeWithoutArgs(
this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
input_injector_->Start(clipboard_stub.PassAs<protocol::ClipboardStub>());
video_capturer_->Start(&screen_capturer_callback_);
setup_run_loop_->Run();
EXPECT_CALL(*remote_input_injector_, InjectClipboardEvent(_))
.Times(1)
.WillOnce(Invoke(this,
&IpcDesktopEnvironmentTest::ReflectClipboardEvent));
protocol::ClipboardEvent event;
event.set_mime_type(kMimeTypeTextUtf8);
event.set_data("a");
input_injector_->InjectClipboardEvent(event);
task_runner_ = NULL;
io_task_runner_ = NULL;
main_run_loop_.Run();
}
TEST_F(IpcDesktopEnvironmentTest, InjectKeyEvent) {
scoped_ptr<protocol::MockClipboardStub> clipboard_stub(
new protocol::MockClipboardStub());
EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
.Times(0);
input_injector_->Start(clipboard_stub.PassAs<protocol::ClipboardStub>());
video_capturer_->Start(&screen_capturer_callback_);
setup_run_loop_->Run();
EXPECT_CALL(*remote_input_injector_, InjectKeyEvent(_))
.Times(AtLeast(1))
.WillRepeatedly(InvokeWithoutArgs(
this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
protocol::KeyEvent event;
event.set_usb_keycode(0x070004);
event.set_pressed(true);
input_injector_->InjectKeyEvent(event);
task_runner_ = NULL;
io_task_runner_ = NULL;
main_run_loop_.Run();
}
TEST_F(IpcDesktopEnvironmentTest, InjectTextEvent) {
scoped_ptr<protocol::MockClipboardStub> clipboard_stub(
new protocol::MockClipboardStub());
EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
.Times(0);
input_injector_->Start(clipboard_stub.PassAs<protocol::ClipboardStub>());
video_capturer_->Start(&screen_capturer_callback_);
setup_run_loop_->Run();
EXPECT_CALL(*remote_input_injector_, InjectTextEvent(_))
.Times(AtLeast(1))
.WillRepeatedly(InvokeWithoutArgs(
this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
protocol::TextEvent event;
event.set_text("hello");
input_injector_->InjectTextEvent(event);
task_runner_ = NULL;
io_task_runner_ = NULL;
main_run_loop_.Run();
}
TEST_F(IpcDesktopEnvironmentTest, InjectMouseEvent) {
scoped_ptr<protocol::MockClipboardStub> clipboard_stub(
new protocol::MockClipboardStub());
EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
.Times(0);
input_injector_->Start(clipboard_stub.PassAs<protocol::ClipboardStub>());
video_capturer_->Start(&screen_capturer_callback_);
setup_run_loop_->Run();
EXPECT_CALL(*remote_input_injector_, InjectMouseEvent(_))
.Times(1)
.WillOnce(InvokeWithoutArgs(
this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
protocol::MouseEvent event;
event.set_x(0);
event.set_y(0);
input_injector_->InjectMouseEvent(event);
task_runner_ = NULL;
io_task_runner_ = NULL;
main_run_loop_.Run();
}
TEST_F(IpcDesktopEnvironmentTest, SetScreenResolution) {
scoped_ptr<protocol::MockClipboardStub> clipboard_stub(
new protocol::MockClipboardStub());
EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
.Times(0);
input_injector_->Start(clipboard_stub.PassAs<protocol::ClipboardStub>());
video_capturer_->Start(&screen_capturer_callback_);
setup_run_loop_->Run();
EXPECT_CALL(daemon_channel_, SetScreenResolution(_, _))
.Times(1)
.WillOnce(InvokeWithoutArgs(
this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
screen_controls_->SetScreenResolution(ScreenResolution(
webrtc::DesktopSize(100, 100),
webrtc::DesktopVector(96, 96)));
task_runner_ = NULL;
io_task_runner_ = NULL;
main_run_loop_.Run();
}
}