summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-16 19:53:35 +0000
committerhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-16 19:53:35 +0000
commit6fd3d6a1648a754d8023924074612d55c187b4cf (patch)
tree102ac605e52b8cf1a4e423b5403a0302a5ee9f76
parent3e4155c723ab73c8f754a82d81f0eb247c83536f (diff)
downloadchromium_src-6fd3d6a1648a754d8023924074612d55c187b4cf.zip
chromium_src-6fd3d6a1648a754d8023924074612d55c187b4cf.tar.gz
chromium_src-6fd3d6a1648a754d8023924074612d55c187b4cf.tar.bz2
Implement input stub in the host side for chromoting
Implement InputStub for the host. BUG=None TEST=None Review URL: http://codereview.chromium.org/4726003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@66314 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/service/service_process.cc13
-rw-r--r--remoting/host/chromoting_host.cc18
-rw-r--r--remoting/host/chromoting_host.h13
-rw-r--r--remoting/host/chromoting_host_context.h2
-rw-r--r--remoting/host/event_executor.h42
-rw-r--r--remoting/host/event_executor_linux.cc95
-rw-r--r--remoting/host/event_executor_linux.h22
-rw-r--r--remoting/host/event_executor_mac.cc19
-rw-r--r--remoting/host/event_executor_mac.h18
-rw-r--r--remoting/host/event_executor_win.cc98
-rw-r--r--remoting/host/event_executor_win.h37
-rw-r--r--remoting/host/mock_objects.h12
-rw-r--r--remoting/host/session_manager_unittest.cc8
-rw-r--r--remoting/host/simple_host_process.cc23
-rw-r--r--remoting/proto/event.proto14
-rw-r--r--remoting/protocol/connection_to_client.cc27
-rw-r--r--remoting/protocol/connection_to_client.h33
-rw-r--r--remoting/protocol/connection_to_client_unittest.cc5
-rw-r--r--remoting/protocol/connection_to_host.h1
-rw-r--r--remoting/protocol/host_message_dispatcher.cc16
-rw-r--r--remoting/protocol/host_message_dispatcher.h4
-rw-r--r--remoting/protocol/host_stub.h2
-rw-r--r--remoting/protocol/input_stub.h4
-rw-r--r--remoting/protocol/mock_objects.h24
-rw-r--r--remoting/remoting.gyp1
25 files changed, 300 insertions, 251 deletions
diff --git a/chrome/service/service_process.cc b/chrome/service/service_process.cc
index 6660c29..f04e082 100644
--- a/chrome/service/service_process.cc
+++ b/chrome/service/service_process.cc
@@ -286,24 +286,27 @@ bool ServiceProcess::StartChromotingHost() {
// Create capturer and executor. The ownership will be transfered
// to the chromoting host.
scoped_ptr<remoting::Capturer> capturer;
- scoped_ptr<remoting::EventExecutor> executor;
+ scoped_ptr<remoting::protocol::InputStub> input_stub;
#if defined(OS_WIN)
capturer.reset(new remoting::CapturerGdi());
- executor.reset(new remoting::EventExecutorWin(capturer.get()));
+ input_stub.reset(new remoting::EventExecutorWin(
+ chromoting_context_->capture_message_loop(), capturer.get()));
#elif defined(OS_LINUX)
capturer.reset(new remoting::CapturerLinux());
- executor.reset(new remoting::EventExecutorLinux(capturer.get()));
+ input_stub.reset(new remoting::EventExecutorLinux(
+ chromoting_context_->capture_message_loop(), capturer.get()));
#elif defined(OS_MACOSX)
capturer.reset(new remoting::CapturerMac());
- executor.reset(new remoting::EventExecutorMac(capturer.get()));
+ input_stub.reset(new remoting::EventExecutorMac(
+ chromoting_context_->capture_message_loop(), capturer.get()));
#endif
// Create a chromoting host object.
chromoting_host_ = new remoting::ChromotingHost(chromoting_context_.get(),
chromoting_config_,
capturer.release(),
- executor.release());
+ input_stub.release());
// Then start the chromoting host.
// When ChromotingHost is shutdown because of failure or a request that
diff --git a/remoting/host/chromoting_host.cc b/remoting/host/chromoting_host.cc
index 8a62459..9fad9cbf 100644
--- a/remoting/host/chromoting_host.cc
+++ b/remoting/host/chromoting_host.cc
@@ -14,7 +14,6 @@
#include "remoting/base/encoder_zlib.h"
#include "remoting/host/chromoting_host_context.h"
#include "remoting/host/capturer.h"
-#include "remoting/host/event_executor.h"
#include "remoting/host/host_config.h"
#include "remoting/host/session_manager.h"
#include "remoting/protocol/session_config.h"
@@ -28,11 +27,11 @@ namespace remoting {
ChromotingHost::ChromotingHost(ChromotingHostContext* context,
MutableHostConfig* config,
Capturer* capturer,
- EventExecutor* executor)
+ protocol::InputStub* input_stub)
: context_(context),
config_(config),
capturer_(capturer),
- executor_(executor),
+ input_stub_(input_stub),
state_(kInitial) {
}
@@ -180,16 +179,6 @@ void ChromotingHost::OnClientDisconnected(ConnectionToClient* connection) {
////////////////////////////////////////////////////////////////////////////
// protocol::ConnectionToClient::EventHandler implementations
-void ChromotingHost::HandleMessage(ConnectionToClient* connection,
- ChromotingClientMessage* message) {
- DCHECK_EQ(context_->main_message_loop(), MessageLoop::current());
-
- // Delegate the messages to EventExecutor and delete the unhandled
- // messages.
- DCHECK(executor_.get());
- executor_->HandleInputEvent(message);
-}
-
void ChromotingHost::OnConnectionOpened(ConnectionToClient* connection) {
DCHECK_EQ(context_->main_message_loop(), MessageLoop::current());
@@ -283,7 +272,8 @@ void ChromotingHost::OnNewClientSession(
// If we accept the connected then create a client object and set the
// callback.
- connection_ = new ConnectionToClient(context_->main_message_loop(), this);
+ connection_ = new ConnectionToClient(context_->main_message_loop(),
+ this, NULL, input_stub_.get());
connection_->Init(session);
}
diff --git a/remoting/host/chromoting_host.h b/remoting/host/chromoting_host.h
index 6616c24..ab285ab 100644
--- a/remoting/host/chromoting_host.h
+++ b/remoting/host/chromoting_host.h
@@ -11,10 +11,10 @@
#include "remoting/base/encoder.h"
#include "remoting/host/access_verifier.h"
#include "remoting/host/capturer.h"
-#include "remoting/host/event_executor.h"
#include "remoting/host/heartbeat_sender.h"
#include "remoting/jingle_glue/jingle_client.h"
#include "remoting/jingle_glue/jingle_thread.h"
+#include "remoting/protocol/input_stub.h"
#include "remoting/protocol/session_manager.h"
#include "remoting/protocol/connection_to_client.h"
@@ -30,7 +30,6 @@ class SessionConfig;
class Capturer;
class ChromotingHostContext;
class Encoder;
-class EventExecutor;
class MutableHostConfig;
class SessionManager;
@@ -46,7 +45,7 @@ class SessionManager;
// a ConnectionToClient object that wraps around linjingle for transport.
// Also create a SessionManager with appropriate Encoder and Capturer and
// add the ConnectionToClient to this SessionManager for transporting the
-// screen captures. A EventExecutor is created and registered with the
+// screen captures. An InputStub is created and registered with the
// ConnectionToClient to receive mouse / keyboard events from the remote
// client.
// This is also the right time to create multiple threads to host
@@ -64,7 +63,7 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>,
public JingleClient::Callback {
public:
ChromotingHost(ChromotingHostContext* context, MutableHostConfig* config,
- Capturer* capturer, EventExecutor* executor);
+ Capturer* capturer, protocol::InputStub* input_stub);
virtual ~ChromotingHost();
// Asynchronously start the host process.
@@ -89,8 +88,6 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>,
////////////////////////////////////////////////////////////////////////////
// protocol::ConnectionToClient::EventHandler implementations
- virtual void HandleMessage(protocol::ConnectionToClient* client,
- ChromotingClientMessage* message);
virtual void OnConnectionOpened(protocol::ConnectionToClient* client);
virtual void OnConnectionClosed(protocol::ConnectionToClient* client);
virtual void OnConnectionFailed(protocol::ConnectionToClient* client);
@@ -133,8 +130,8 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>,
// constructed this is set to NULL.
scoped_ptr<Encoder> encoder_;
- // EventExecutor executes input events received from the client.
- scoped_ptr<EventExecutor> executor_;
+ // InputStub in the host executes input events received from the client.
+ scoped_ptr<protocol::InputStub> input_stub_;
// The libjingle client. This is used to connect to the talk network to
// receive connection requests from chromoting client.
diff --git a/remoting/host/chromoting_host_context.h b/remoting/host/chromoting_host_context.h
index 713afb8..f5b2783 100644
--- a/remoting/host/chromoting_host_context.h
+++ b/remoting/host/chromoting_host_context.h
@@ -28,6 +28,8 @@ class ChromotingHostContext {
virtual void Stop();
virtual JingleThread* jingle_thread();
+
+ // TODO(hclam): Change these all to MessageLoopProxy.
virtual MessageLoop* main_message_loop();
virtual MessageLoop* capture_message_loop();
virtual MessageLoop* encode_message_loop();
diff --git a/remoting/host/event_executor.h b/remoting/host/event_executor.h
deleted file mode 100644
index 3f87ea7..0000000
--- a/remoting/host/event_executor.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2010 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.
-
-#ifndef REMOTING_HOST_EVENT_EXECUTOR_H_
-#define REMOTING_HOST_EVENT_EXECUTOR_H_
-
-#include <vector>
-
-#include "base/basictypes.h"
-
-namespace remoting {
-
-class Capturer;
-class ChromotingClientMessage;
-
-// An interface that defines the behavior of an event executor object.
-// An event executor is to perform actions on the host machine. For example
-// moving the mouse cursor, generating keyboard events and manipulating
-// clipboards.
-class EventExecutor {
- public:
- explicit EventExecutor(Capturer* capturer)
- : capturer_(capturer) {
- }
- virtual ~EventExecutor() {}
-
- // Handles input events from ClientMessageList and removes them from the
- // list.
- virtual void HandleInputEvent(ChromotingClientMessage* message) = 0;
- // TODO(hclam): Define actions for clipboards.
-
- protected:
- Capturer* capturer_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(EventExecutor);
-};
-
-} // namespace remoting
-
-#endif // REMOTING_HOST_EVENT_EXECUTOR_H_
diff --git a/remoting/host/event_executor_linux.cc b/remoting/host/event_executor_linux.cc
index f8212f1..1421277 100644
--- a/remoting/host/event_executor_linux.cc
+++ b/remoting/host/event_executor_linux.cc
@@ -9,6 +9,8 @@
#include <X11/extensions/XTest.h>
#include "base/logging.h"
+#include "base/message_loop.h"
+#include "base/task.h"
#include "remoting/proto/internal.pb.h"
namespace remoting {
@@ -200,8 +202,8 @@ class EventExecutorLinuxPimpl {
~EventExecutorLinuxPimpl();
bool Init(); // TODO(ajwong): Do we really want this to be synchronous?
-
- void HandleInputEvent(ChromotingClientMessage* message);
+ void HandleMouse(const MouseEvent* message);
+ void HandleKey(const KeyEvent* key_event);
private:
void HandleMouseSetPosition(const MouseSetPositionEvent& position_event);
@@ -209,7 +211,6 @@ class EventExecutorLinuxPimpl {
void HandleMouseWheel(const MouseWheelEvent& wheel_event);
void HandleMouseButtonDown(const MouseDownEvent& mouse_down_event);
void HandleMouseButtonUp(const MouseUpEvent& mouse_up_event);
- void HandleKey(const KeyEvent& key_event);
void DeinitXlib();
// Reference to containing class so we can access friend functions.
@@ -227,19 +228,6 @@ class EventExecutorLinuxPimpl {
int test_error_base_;
};
-EventExecutorLinux::EventExecutorLinux(Capturer* capturer)
- : EventExecutor(capturer),
- pimpl_(new EventExecutorLinuxPimpl(this)) {
- CHECK(pimpl_->Init());
-}
-
-EventExecutorLinux::~EventExecutorLinux() {
-}
-
-void EventExecutorLinux::HandleInputEvent(ChromotingClientMessage* message) {
- pimpl_->HandleInputEvent(message);
-}
-
EventExecutorLinuxPimpl::EventExecutorLinuxPimpl(EventExecutorLinux* executor)
: executor_(executor),
display_(NULL),
@@ -302,22 +290,17 @@ bool EventExecutorLinuxPimpl::Init() {
return true;
}
-void EventExecutorLinuxPimpl::HandleInputEvent(
- ChromotingClientMessage* message) {
- if (message->has_mouse_set_position_event()) {
- HandleMouseSetPosition(message->mouse_set_position_event());
- } else if (message->has_mouse_move_event()) {
- HandleMouseMove(message->mouse_move_event());
- } else if (message->has_mouse_wheel_event()) {
- HandleMouseWheel(message->mouse_wheel_event());
- } else if (message->has_mouse_down_event()) {
- HandleMouseButtonDown(message->mouse_down_event());
- } else if (message->has_mouse_up_event()) {
- HandleMouseButtonUp(message->mouse_up_event());
- } else if (message->has_key_event()) {
- HandleKey(message->key_event());
+void EventExecutorLinuxPimpl::HandleMouse(
+ const MouseEvent* mouse_event) {
+ if (mouse_event->has_set_position()) {
+ HandleMouseSetPosition(mouse_event->set_position());
+ } else if (mouse_event->has_wheel()) {
+ HandleMouseWheel(mouse_event->wheel());
+ } else if (mouse_event->has_down()) {
+ HandleMouseButtonDown(mouse_event->down());
+ } else if (mouse_event->has_up()) {
+ HandleMouseButtonUp(mouse_event->up());
}
- delete message;
}
void EventExecutorLinuxPimpl::HandleMouseSetPosition(
@@ -376,12 +359,12 @@ void EventExecutorLinuxPimpl::HandleMouseButtonUp(
XTestFakeButtonEvent(display_, button_number, False, CurrentTime);
}
-void EventExecutorLinuxPimpl::HandleKey(const KeyEvent& key_event) {
+void EventExecutorLinuxPimpl::HandleKey(const KeyEvent* key_event) {
// TODO(ajwong): This will only work for QWERTY keyboards.
- int keysym = ChromotocolKeycodeToX11Keysym(key_event.key());
+ int keysym = ChromotocolKeycodeToX11Keysym(key_event->key());
if (keysym == -1) {
- LOG(WARNING) << "Ignoring unknown key: " << key_event.key();
+ LOG(WARNING) << "Ignoring unknown key: " << key_event->key();
return;
}
@@ -389,14 +372,14 @@ void EventExecutorLinuxPimpl::HandleKey(const KeyEvent& key_event) {
int keycode = XKeysymToKeycode(display_, keysym);
if (keycode == 0) {
LOG(WARNING) << "Ignoring undefined keysym: " << keysym
- << " for key: " << key_event.key();
+ << " for key: " << key_event->key();
return;
}
- VLOG(3) << "Got pepper key: " << key_event.key()
+ VLOG(3) << "Got pepper key: " << key_event->key()
<< " sending keysym: " << keysym
<< " to keycode: " << keycode;
- XTestFakeKeyEvent(display_, keycode, key_event.pressed(), CurrentTime);
+ XTestFakeKeyEvent(display_, keycode, key_event->pressed(), CurrentTime);
}
void EventExecutorLinuxPimpl::DeinitXlib() {
@@ -416,4 +399,42 @@ void EventExecutorLinuxPimpl::DeinitXlib() {
}
}
+EventExecutorLinux::EventExecutorLinux(
+ MessageLoop* message_loop, Capturer* capturer)
+ : message_loop_(message_loop),
+ capturer_(capturer),
+ pimpl_(new EventExecutorLinuxPimpl(this)) {
+ CHECK(pimpl_->Init());
+}
+
+EventExecutorLinux::~EventExecutorLinux() {
+}
+
+void EventExecutorLinux::InjectKeyEvent(const KeyEvent* event, Task* done) {
+ if (MessageLoop::current() != message_loop_) {
+ message_loop_->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(this, &EventExecutorLinux::InjectKeyEvent,
+ event, done));
+ return;
+ }
+ pimpl_->HandleKey(event);
+ done->Run();
+ delete done;
+}
+
+void EventExecutorLinux::InjectMouseEvent(const MouseEvent* event,
+ Task* done) {
+ if (MessageLoop::current() != message_loop_) {
+ message_loop_->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(this, &EventExecutorLinux::InjectMouseEvent,
+ event, done));
+ return;
+ }
+ pimpl_->HandleMouse(event);
+ done->Run();
+ delete done;
+}
+
} // namespace remoting
diff --git a/remoting/host/event_executor_linux.h b/remoting/host/event_executor_linux.h
index cda6476..ef28660 100644
--- a/remoting/host/event_executor_linux.h
+++ b/remoting/host/event_executor_linux.h
@@ -5,22 +5,34 @@
#ifndef REMOTING_HOST_EVENT_EXECUTOR_LINUX_H_
#define REMOTING_HOST_EVENT_EXECUTOR_LINUX_H_
+#include <vector>
+
+#include "base/task.h"
+#include "base/basictypes.h"
#include "base/scoped_ptr.h"
-#include "remoting/host/event_executor.h"
+#include "remoting/protocol/input_stub.h"
+
+class MessageLoop;
namespace remoting {
+class Capturer;
+class ChromotingClientMessage;
class EventExecutorLinuxPimpl;
// A class to generate events on Linux.
-class EventExecutorLinux : public EventExecutor {
+class EventExecutorLinux : public protocol::InputStub {
public:
- EventExecutorLinux(Capturer* capturer);
+ EventExecutorLinux(MessageLoop* message_loop,
+ Capturer* capturer);
virtual ~EventExecutorLinux();
- virtual void HandleInputEvent(ChromotingClientMessage* message);
+ virtual void InjectKeyEvent(const KeyEvent* event, Task* done);
+ virtual void InjectMouseEvent(const MouseEvent* event, Task* done);
private:
+ MessageLoop* message_loop_;
+ Capturer* capturer_;
scoped_ptr<EventExecutorLinuxPimpl> pimpl_;
DISALLOW_COPY_AND_ASSIGN(EventExecutorLinux);
@@ -28,4 +40,6 @@ class EventExecutorLinux : public EventExecutor {
} // namespace remoting
+DISABLE_RUNNABLE_METHOD_REFCOUNT(remoting::EventExecutorLinux);
+
#endif // REMOTING_HOST_EVENT_EXECUTOR_LINUX_H_
diff --git a/remoting/host/event_executor_mac.cc b/remoting/host/event_executor_mac.cc
index 7e64324..553222a 100644
--- a/remoting/host/event_executor_mac.cc
+++ b/remoting/host/event_executor_mac.cc
@@ -4,20 +4,29 @@
#include "remoting/host/event_executor_mac.h"
-#include "remoting/proto/internal.pb.h"
+#include "base/message_loop.h"
+#include "base/task.h"
#include "remoting/protocol/message_decoder.h"
namespace remoting {
-EventExecutorMac::EventExecutorMac(Capturer* capturer)
- : EventExecutor(capturer) {
+EventExecutorMac::EventExecutorMac(
+ MessageLoop* message_loop, Capturer* capturer)
+ : message_loop_(message_loop),
+ capturer_(capturer) {
}
EventExecutorMac::~EventExecutorMac() {
}
-void EventExecutorMac::HandleInputEvent(ChromotingClientMessage* message) {
- delete message;
+void EventExecutorMac::InjectKeyEvent(const KeyEvent* event, Task* done) {
+ done->Run();
+ delete done;
+}
+
+void EventExecutorMac::InjectMouseEvent(const MouseEvent* event, Task* done) {
+ done->Run();
+ delete done;
}
} // namespace remoting
diff --git a/remoting/host/event_executor_mac.h b/remoting/host/event_executor_mac.h
index f8934b1..052ca48 100644
--- a/remoting/host/event_executor_mac.h
+++ b/remoting/host/event_executor_mac.h
@@ -7,19 +7,29 @@
#include <vector>
-#include "remoting/host/event_executor.h"
+#include "base/basictypes.h"
+#include "remoting/protocol/input_stub.h"
+
+class MessageLoop;
namespace remoting {
+class Capturer;
+class ChromotingClientMessage;
+
// A class to generate events on Mac.
-class EventExecutorMac : public EventExecutor {
+class EventExecutorMac : public protocol::InputStub {
public:
- EventExecutorMac(Capturer* capturer);
+ EventExecutorMac(MessageLoop* message_loop, Capturer* capturer);
virtual ~EventExecutorMac();
- virtual void HandleInputEvent(ChromotingClientMessage* message);
+ virtual void InjectKeyEvent(const KeyEvent* event, Task* done);
+ virtual void InjectMouseEvent(const MouseEvent* event, Task* done);
private:
+ MessageLoop* message_loop_;
+ Capturer* capturer_;
+
DISALLOW_COPY_AND_ASSIGN(EventExecutorMac);
};
diff --git a/remoting/host/event_executor_win.cc b/remoting/host/event_executor_win.cc
index 283d4aa..2ee24bd 100644
--- a/remoting/host/event_executor_win.cc
+++ b/remoting/host/event_executor_win.cc
@@ -5,43 +5,64 @@
#include "remoting/host/event_executor_win.h"
#include <windows.h>
+
#include "app/keyboard_codes.h"
+#include "base/message_loop.h"
#include "base/stl_util-inl.h"
#include "remoting/host/capturer.h"
-// TODO(hclam): Should not include internal.pb.h here.
-#include "remoting/proto/internal.pb.h"
+#include "remoting/proto/event.pb.h"
namespace remoting {
-EventExecutorWin::EventExecutorWin(Capturer* capturer)
- : EventExecutor(capturer) {
+EventExecutorWin::EventExecutorWin(
+ MessageLoop* message_loop, Capturer* capturer)
+ : message_loop_(message_loop), capturer_(capturer) {
}
EventExecutorWin::~EventExecutorWin() {
}
-void EventExecutorWin::HandleInputEvent(ChromotingClientMessage* msg) {
- if (msg->has_mouse_set_position_event()) {
- HandleMouseSetPosition(msg);
- } else if (msg->has_mouse_move_event()) {
- HandleMouseMove(msg);
- } else if (msg->has_mouse_wheel_event()) {
- HandleMouseWheel(msg);
- } else if (msg->has_mouse_down_event()) {
- HandleMouseButtonDown(msg);
- } else if (msg->has_mouse_up_event()) {
- HandleMouseButtonUp(msg);
- } else if (msg->has_key_event()) {
- HandleKey(msg);
+void EventExecutorWin::InjectKeyEvent(const KeyEvent* event, Task* done) {
+ if (MessageLoop::current() != message_loop_) {
+ message_loop_->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(this, &EventExecutorWin::InjectKeyEvent,
+ event, done));
+ return;
+ }
+ HandleKey(*event);
+ done->Run();
+ delete done;
+}
+
+void EventExecutorWin::InjectMouseEvent(const MouseEvent* event,
+ Task* done) {
+ if (MessageLoop::current() != message_loop_) {
+ message_loop_->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(this, &EventExecutorWin::InjectMouseEvent,
+ event, done));
+ return;
+ }
+ if (event->has_set_position()) {
+ HandleMouseSetPosition(event->set_position());
+ } else if (event->has_wheel()) {
+ HandleMouseWheel(event->wheel());
+ } else if (event->has_down()) {
+ HandleMouseButtonDown(event->down());
+ } else if (event->has_up()) {
+ HandleMouseButtonUp(event->up());
}
- delete msg;
+ done->Run();
+ delete done;
}
-void EventExecutorWin::HandleMouseSetPosition(ChromotingClientMessage* msg) {
- int x = msg->mouse_set_position_event().x();
- int y = msg->mouse_set_position_event().y();
- int width = msg->mouse_set_position_event().width();
- int height = msg->mouse_set_position_event().height();
+void EventExecutorWin::HandleMouseSetPosition(
+ const MouseSetPositionEvent& event) {
+ int x = event.x();
+ int y = event.y();
+ int width = event.width();
+ int height = event.height();
// Get width and height from the capturer if they are missing from the
// message.
@@ -62,23 +83,14 @@ void EventExecutorWin::HandleMouseSetPosition(ChromotingClientMessage* msg) {
SendInput(1, &input, sizeof(INPUT));
}
-void EventExecutorWin::HandleMouseMove(ChromotingClientMessage* msg) {
- INPUT input;
- input.type = INPUT_MOUSE;
- input.mi.time = 0;
- input.mi.dx = msg->mouse_move_event().offset_x();
- input.mi.dy = msg->mouse_move_event().offset_y();
- input.mi.dwFlags = MOUSEEVENTF_MOVE;
- SendInput(1, &input, sizeof(INPUT));
-}
-
-void EventExecutorWin::HandleMouseWheel(ChromotingClientMessage* msg) {
+void EventExecutorWin::HandleMouseWheel(
+ const MouseWheelEvent& event) {
INPUT input;
input.type = INPUT_MOUSE;
input.mi.time = 0;
- int dx = msg->mouse_wheel_event().offset_x();
- int dy = msg->mouse_wheel_event().offset_y();
+ int dx = event.offset_x();
+ int dy = event.offset_y();
if (dx != 0) {
input.mi.mouseData = dx;
@@ -92,14 +104,14 @@ void EventExecutorWin::HandleMouseWheel(ChromotingClientMessage* msg) {
}
}
-void EventExecutorWin::HandleMouseButtonDown(ChromotingClientMessage* msg) {
+void EventExecutorWin::HandleMouseButtonDown(const MouseDownEvent& event) {
INPUT input;
input.type = INPUT_MOUSE;
input.mi.time = 0;
input.mi.dx = 0;
input.mi.dy = 0;
- MouseButton button = msg->mouse_down_event().button();
+ MouseButton button = event.button();
if (button == MouseButtonLeft) {
input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
} else if (button == MouseButtonMiddle) {
@@ -113,14 +125,14 @@ void EventExecutorWin::HandleMouseButtonDown(ChromotingClientMessage* msg) {
SendInput(1, &input, sizeof(INPUT));
}
-void EventExecutorWin::HandleMouseButtonUp(ChromotingClientMessage* msg) {
+void EventExecutorWin::HandleMouseButtonUp(const MouseUpEvent& event) {
INPUT input;
input.type = INPUT_MOUSE;
input.mi.time = 0;
input.mi.dx = 0;
input.mi.dy = 0;
- MouseButton button = msg->mouse_down_event().button();
+ MouseButton button = event.button();
if (button == MouseButtonLeft) {
input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
} else if (button == MouseButtonMiddle) {
@@ -134,9 +146,9 @@ void EventExecutorWin::HandleMouseButtonUp(ChromotingClientMessage* msg) {
SendInput(1, &input, sizeof(INPUT));
}
-void EventExecutorWin::HandleKey(ChromotingClientMessage* msg) {
- int key = msg->key_event().key();
- bool down = msg->key_event().pressed();
+void EventExecutorWin::HandleKey(const KeyEvent& event) {
+ int key = event.key();
+ bool down = event.pressed();
// Calculate scan code from virtual key.
HKL hkl = GetKeyboardLayout(0);
diff --git a/remoting/host/event_executor_win.h b/remoting/host/event_executor_win.h
index e9a0269..b98d7be 100644
--- a/remoting/host/event_executor_win.h
+++ b/remoting/host/event_executor_win.h
@@ -7,29 +7,46 @@
#include <vector>
-#include "remoting/host/event_executor.h"
+#include "base/task.h"
+#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
+#include "remoting/protocol/input_stub.h"
+
+class MessageLoop;
namespace remoting {
+class Capturer;
+class KeyEvent;
+class MouseDownEvent;
+class MouseSetPositionEvent;
+class MouseUpEvent;
+class MouseWheelEvent;
+
// A class to generate events on Windows.
-class EventExecutorWin : public EventExecutor {
+class EventExecutorWin : public protocol::InputStub {
public:
- EventExecutorWin(Capturer* capturer);
+ EventExecutorWin(MessageLoop* message_loop, Capturer* capturer);
virtual ~EventExecutorWin();
- virtual void HandleInputEvent(ChromotingClientMessage* message);
+ virtual void InjectKeyEvent(const KeyEvent* event, Task* done);
+ virtual void InjectMouseEvent(const MouseEvent* event, Task* done);
private:
- void HandleMouseSetPosition(ChromotingClientMessage* msg);
- void HandleMouseMove(ChromotingClientMessage* msg);
- void HandleMouseWheel(ChromotingClientMessage* msg);
- void HandleMouseButtonDown(ChromotingClientMessage* msg);
- void HandleMouseButtonUp(ChromotingClientMessage* msg);
- void HandleKey(ChromotingClientMessage* msg);
+ void HandleMouseSetPosition(const MouseSetPositionEvent& event);
+ void HandleMouseWheel(const MouseWheelEvent& event);
+ void HandleMouseButtonDown(const MouseDownEvent& event);
+ void HandleMouseButtonUp(const MouseUpEvent& event);
+ void HandleKey(const KeyEvent& event);
+
+ MessageLoop* message_loop_;
+ Capturer* capturer_;
DISALLOW_COPY_AND_ASSIGN(EventExecutorWin);
};
} // namespace remoting
+DISABLE_RUNNABLE_METHOD_REFCOUNT(remoting::EventExecutorWin);
+
#endif // REMOTING_HOST_EVENT_EXECUTOR_WIN_H_
diff --git a/remoting/host/mock_objects.h b/remoting/host/mock_objects.h
index 8541d62..3c51097 100644
--- a/remoting/host/mock_objects.h
+++ b/remoting/host/mock_objects.h
@@ -6,8 +6,6 @@
#define REMOTING_HOST_MOCK_OBJECTS_H_
#include "remoting/host/capturer.h"
-#include "remoting/host/event_executor.h"
-#include "remoting/proto/internal.pb.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace remoting {
@@ -30,16 +28,6 @@ class MockCapturer : public Capturer {
DISALLOW_COPY_AND_ASSIGN(MockCapturer);
};
-class MockEventExecutor : public EventExecutor {
- public:
- MockEventExecutor(Capturer* capturer) : EventExecutor(capturer) {}
-
- MOCK_METHOD1(HandleInputEvent, void(ChromotingClientMessage* messages));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockEventExecutor);
-};
-
} // namespace remoting
#endif // REMOTING_HOST_MOCK_OBJECTS_H_
diff --git a/remoting/host/session_manager_unittest.cc b/remoting/host/session_manager_unittest.cc
index bfe1fa4..5c853b28 100644
--- a/remoting/host/session_manager_unittest.cc
+++ b/remoting/host/session_manager_unittest.cc
@@ -37,11 +37,9 @@ class SessionManagerTest : public testing::Test {
capturer_ = new MockCapturer();
encoder_ = new MockEncoder();
connection_ = new MockConnectionToClient();
- record_ = new SessionManager(&message_loop_,
- &message_loop_,
- &message_loop_,
- capturer_,
- encoder_);
+ record_ = new SessionManager(
+ &message_loop_, &message_loop_, &message_loop_,
+ capturer_, encoder_);
}
scoped_refptr<SessionManager> record_;
diff --git a/remoting/host/simple_host_process.cc b/remoting/host/simple_host_process.cc
index 98d9303..0d4b80e 100644
--- a/remoting/host/simple_host_process.cc
+++ b/remoting/host/simple_host_process.cc
@@ -71,20 +71,26 @@ int main(int argc, char** argv) {
const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
base::AtExitManager exit_manager;
-
base::EnsureNSPRInit();
+ // Allocate a chromoting context and starts it.
+ remoting::ChromotingHostContext context;
+ context.Start();
+
scoped_ptr<remoting::Capturer> capturer;
- scoped_ptr<remoting::EventExecutor> event_handler;
+ scoped_ptr<remoting::protocol::InputStub> input_stub;
#if defined(OS_WIN)
capturer.reset(new remoting::CapturerGdi());
- event_handler.reset(new remoting::EventExecutorWin(capturer.get()));
+ input_stub.reset(new remoting::EventExecutorWin(
+ context.capture_message_loop(), capturer.get()));
#elif defined(OS_LINUX)
capturer.reset(new remoting::CapturerLinux());
- event_handler.reset(new remoting::EventExecutorLinux(capturer.get()));
+ input_stub.reset(new remoting::EventExecutorLinux(
+ context.capture_message_loop(), capturer.get()));
#elif defined(OS_MACOSX)
capturer.reset(new remoting::CapturerMac());
- event_handler.reset(new remoting::EventExecutorMac(capturer.get()));
+ input_stub.reset(new remoting::EventExecutorMac(
+ context.capture_message_loop(), capturer.get()));
#endif
// Check the argument to see if we should use a fake capturer.
@@ -117,13 +123,10 @@ int main(int argc, char** argv) {
if (!config->Read()) {
LOG(ERROR) << "Failed to read configuration file " << config_path.value();
+ context.Stop();
return 1;
}
- // Allocate a chromoting context and starts it.
- remoting::ChromotingHostContext context;
- context.Start();
-
FilePath module_path;
PathService::Get(base::DIR_MODULE, &module_path);
CHECK(media::InitializeMediaLibrary(module_path))
@@ -134,7 +137,7 @@ int main(int argc, char** argv) {
new remoting::ChromotingHost(&context,
config,
capturer.release(),
- event_handler.release()));
+ input_stub.release()));
// Let the chromoting host run until the shutdown task is executed.
MessageLoop message_loop(MessageLoop::TYPE_UI);
diff --git a/remoting/proto/event.proto b/remoting/proto/event.proto
index 1f14c9dc..f6ca3f9 100644
--- a/remoting/proto/event.proto
+++ b/remoting/proto/event.proto
@@ -69,16 +69,16 @@ message MouseUpEvent {
// Defines a mouse event message on the event channel.
message MouseEvent {
// Mouse position information.
- optional int32 mouse_x = 1;
- optional int32 mouse_y = 2;
+ optional MouseSetPositionEvent set_position = 1;
// Mouse wheel information.
- optional int32 wheel_offset_x = 3;
- optional int32 wheel_offset_y = 4;
+ optional MouseWheelEvent wheel = 2;
- // Mouse button information.
- optional MouseButton button = 5;
- optional bool button_down = 6;
+ // Mouse down event.
+ optional MouseDownEvent down = 3;
+
+ // Mouse up event.
+ optional MouseUpEvent up = 4;
}
// Defines an event message on the event channel.
diff --git a/remoting/protocol/connection_to_client.cc b/remoting/protocol/connection_to_client.cc
index c3c695d..0661be3 100644
--- a/remoting/protocol/connection_to_client.cc
+++ b/remoting/protocol/connection_to_client.cc
@@ -7,6 +7,7 @@
#include "google/protobuf/message.h"
#include "net/base/io_buffer.h"
#include "remoting/protocol/client_control_sender.h"
+#include "remoting/protocol/host_message_dispatcher.h"
// TODO(hclam): Remove this header once MessageDispatcher is used.
#include "remoting/base/compound_buffer.h"
@@ -19,9 +20,13 @@ namespace protocol {
static const size_t kAverageUpdateStream = 10;
ConnectionToClient::ConnectionToClient(MessageLoop* message_loop,
- EventHandler* handler)
+ EventHandler* handler,
+ HostStub* host_stub,
+ InputStub* input_stub)
: loop_(message_loop),
- handler_(handler) {
+ handler_(handler),
+ host_stub_(host_stub),
+ input_stub_(input_stub) {
DCHECK(loop_);
DCHECK(handler_);
}
@@ -74,23 +79,17 @@ void ConnectionToClient::OnSessionStateChange(
protocol::Session::State state) {
if (state == protocol::Session::CONNECTED) {
client_stub_.reset(new ClientControlSender(session_->control_channel()));
- event_reader_.Init<ChromotingClientMessage>(
- session_->event_channel(),
- NewCallback(this, &ConnectionToClient::OnMessageReceived));
video_writer_.reset(VideoWriter::Create(session_->config()));
video_writer_->Init(session_);
+
+ dispatcher_.reset(new HostMessageDispatcher());
+ dispatcher_->Initialize(session_.get(), host_stub_, input_stub_);
}
loop_->PostTask(FROM_HERE,
NewRunnableMethod(this, &ConnectionToClient::StateChangeTask, state));
}
-void ConnectionToClient::OnMessageReceived(ChromotingClientMessage* message) {
- loop_->PostTask(FROM_HERE,
- NewRunnableMethod(this, &ConnectionToClient::MessageReceivedTask,
- message));
-}
-
void ConnectionToClient::StateChangeTask(protocol::Session::State state) {
DCHECK_EQ(loop_, MessageLoop::current());
@@ -114,12 +113,6 @@ void ConnectionToClient::StateChangeTask(protocol::Session::State state) {
}
}
-void ConnectionToClient::MessageReceivedTask(ChromotingClientMessage* message) {
- DCHECK_EQ(loop_, MessageLoop::current());
- DCHECK(handler_);
- handler_->HandleMessage(this, message);
-}
-
// OnClosed() is used as a callback for protocol::Session::Close().
void ConnectionToClient::OnClosed() {
}
diff --git a/remoting/protocol/connection_to_client.h b/remoting/protocol/connection_to_client.h
index 769b0a8..546db76 100644
--- a/remoting/protocol/connection_to_client.h
+++ b/remoting/protocol/connection_to_client.h
@@ -11,7 +11,6 @@
#include "base/message_loop.h"
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
-#include "remoting/protocol/message_reader.h"
#include "remoting/protocol/session.h"
#include "remoting/protocol/stream_writer.h"
#include "remoting/protocol/video_writer.h"
@@ -20,6 +19,9 @@ namespace remoting {
namespace protocol {
class ClientStub;
+class HostStub;
+class InputStub;
+class HostMessageDispatcher;
// This class represents a remote viewer connected to the chromoting host
// through a libjingle connection. A viewer object is responsible for sending
@@ -27,19 +29,12 @@ class ClientStub;
// responsible for receiving and parsing data from the remote viewer and
// delegating events to the event handler.
class ConnectionToClient :
- public base::RefCountedThreadSafe<ConnectionToClient> {
+ public base::RefCountedThreadSafe<ConnectionToClient> {
public:
class EventHandler {
public:
virtual ~EventHandler() {}
- // Handles an event received by the ConnectionToClient. Receiver will own
- // the ClientMessages in ClientMessageList and needs to delete them.
- // Note that the sender of messages will not reference messages
- // again so it is okay to clear |messages| in this method.
- virtual void HandleMessage(ConnectionToClient* connection,
- ChromotingClientMessage* message) = 0;
-
// Called when the network connection is opened.
virtual void OnConnectionOpened(ConnectionToClient* connection) = 0;
@@ -55,7 +50,9 @@ class ConnectionToClient :
// a libjingle channel, these events are delegated to |handler|.
// It is guranteed that |handler| is called only on the |message_loop|.
ConnectionToClient(MessageLoop* message_loop,
- EventHandler* handler);
+ EventHandler* handler,
+ HostStub* host_stub,
+ InputStub* input_stub);
virtual ~ConnectionToClient();
@@ -90,21 +87,14 @@ class ConnectionToClient :
// Callback for protocol Session.
void OnSessionStateChange(protocol::Session::State state);
- // Callback for MessageReader.
- void OnMessageReceived(ChromotingClientMessage* message);
-
// Process a libjingle state change event on the |loop_|.
void StateChangeTask(protocol::Session::State state);
- // Process a data buffer received from libjingle.
- void MessageReceivedTask(ChromotingClientMessage* message);
-
void OnClosed();
// The libjingle channel used to send and receive data from the remote client.
scoped_refptr<protocol::Session> session_;
- MessageReader event_reader_;
scoped_ptr<VideoWriter> video_writer_;
// ClientStub for sending messages to the client.
@@ -116,6 +106,15 @@ class ConnectionToClient :
// Event handler for handling events sent from this object.
EventHandler* handler_;
+ // HostStub for receiving control events from the client.
+ HostStub* host_stub_;
+
+ // InputStub for receiving input events from the client.
+ InputStub* input_stub_;
+
+ // Dispatcher for submitting messages to stubs.
+ scoped_ptr<HostMessageDispatcher> dispatcher_;
+
DISALLOW_COPY_AND_ASSIGN(ConnectionToClient);
};
diff --git a/remoting/protocol/connection_to_client_unittest.cc b/remoting/protocol/connection_to_client_unittest.cc
index e199c12..eaea342 100644
--- a/remoting/protocol/connection_to_client_unittest.cc
+++ b/remoting/protocol/connection_to_client_unittest.cc
@@ -27,7 +27,8 @@ class ConnectionToClientTest : public testing::Test {
session_->set_message_loop(&message_loop_);
// Allocate a ClientConnection object with the mock objects.
- viewer_ = new ConnectionToClient(&message_loop_, &handler_);
+ viewer_ = new ConnectionToClient(&message_loop_, &handler_,
+ &host_stub_, &input_stub_);
viewer_->Init(session_);
EXPECT_CALL(handler_, OnConnectionOpened(viewer_.get()));
session_->state_change_callback()->Run(
@@ -37,6 +38,8 @@ class ConnectionToClientTest : public testing::Test {
MessageLoop message_loop_;
MockConnectionToClientEventHandler handler_;
+ MockHostStub host_stub_;
+ MockInputStub input_stub_;
scoped_refptr<ConnectionToClient> viewer_;
scoped_refptr<protocol::FakeSession> session_;
diff --git a/remoting/protocol/connection_to_host.h b/remoting/protocol/connection_to_host.h
index e2b0ce2..d34b9ee 100644
--- a/remoting/protocol/connection_to_host.h
+++ b/remoting/protocol/connection_to_host.h
@@ -10,7 +10,6 @@
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
#include "remoting/proto/internal.pb.h"
-#include "remoting/protocol/message_decoder.h"
namespace remoting {
namespace protocol {
diff --git a/remoting/protocol/host_message_dispatcher.cc b/remoting/protocol/host_message_dispatcher.cc
index 7ad9cac..13fa803 100644
--- a/remoting/protocol/host_message_dispatcher.cc
+++ b/remoting/protocol/host_message_dispatcher.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/ref_counted.h"
#include "net/base/io_buffer.h"
#include "remoting/proto/control.pb.h"
#include "remoting/proto/event.pb.h"
@@ -77,13 +78,24 @@ void HostMessageDispatcher::OnControlMessageReceived(ControlMessage* message) {
new RefCountedMessage<ControlMessage>(message);
if (message->has_suggest_resolution()) {
host_stub_->SuggestResolution(
- message->suggest_resolution(), NewDeleteTask(ref_msg));
+ &message->suggest_resolution(), NewDeleteTask(ref_msg));
}
}
void HostMessageDispatcher::OnEventMessageReceived(
EventMessage* message) {
- // TODO(hclam): Implement.
+ scoped_refptr<RefCountedMessage<EventMessage> > ref_msg =
+ new RefCountedMessage<EventMessage>(message);
+ for (int i = 0; i < message->event_size(); ++i) {
+ if (message->event(i).has_key()) {
+ input_stub_->InjectKeyEvent(
+ &message->event(i).key(), NewDeleteTask(ref_msg));
+ }
+ if (message->event(i).has_mouse()) {
+ input_stub_->InjectMouseEvent(
+ &message->event(i).mouse(), NewDeleteTask(ref_msg));
+ }
+ }
}
} // namespace protocol
diff --git a/remoting/protocol/host_message_dispatcher.h b/remoting/protocol/host_message_dispatcher.h
index cd95b26..c8b7a39 100644
--- a/remoting/protocol/host_message_dispatcher.h
+++ b/remoting/protocol/host_message_dispatcher.h
@@ -6,7 +6,6 @@
#define REMOTING_PROTOCOL_HOST_MESSAGE_DISPATCHER_H_
#include "base/basictypes.h"
-#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
#include "base/task.h"
@@ -32,8 +31,7 @@ class Session;
//
// Object of this class is owned by ChromotingHost to dispatch messages
// to itself.
-class HostMessageDispatcher :
- public base::RefCountedThreadSafe<HostMessageDispatcher> {
+class HostMessageDispatcher {
public:
// Construct a message dispatcher.
HostMessageDispatcher();
diff --git a/remoting/protocol/host_stub.h b/remoting/protocol/host_stub.h
index a9e2fa5..cf14daa 100644
--- a/remoting/protocol/host_stub.h
+++ b/remoting/protocol/host_stub.h
@@ -24,7 +24,7 @@ class HostStub {
virtual ~HostStub() {};
virtual void SuggestResolution(
- const SuggestResolutionRequest& msg, Task* done) = 0;
+ const SuggestResolutionRequest* msg, Task* done) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(HostStub);
diff --git a/remoting/protocol/input_stub.h b/remoting/protocol/input_stub.h
index 201dda3..c36ff07 100644
--- a/remoting/protocol/input_stub.h
+++ b/remoting/protocol/input_stub.h
@@ -22,8 +22,8 @@ class InputStub {
InputStub() {}
virtual ~InputStub() {}
- virtual void InjectKeyEvent(const KeyEvent& event, Task* done) = 0;
- virtual void InjectMouseEvent(const MouseEvent& event, Task* done) = 0;
+ virtual void InjectKeyEvent(const KeyEvent* event, Task* done) = 0;
+ virtual void InjectMouseEvent(const MouseEvent* event, Task* done) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(InputStub);
diff --git a/remoting/protocol/mock_objects.h b/remoting/protocol/mock_objects.h
index 5acb131..b10c139 100644
--- a/remoting/protocol/mock_objects.h
+++ b/remoting/protocol/mock_objects.h
@@ -7,6 +7,8 @@
#include "remoting/proto/internal.pb.h"
#include "remoting/protocol/connection_to_client.h"
+#include "remoting/protocol/host_stub.h"
+#include "remoting/protocol/input_stub.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace remoting {
@@ -44,6 +46,28 @@ class MockConnectionToClientEventHandler :
DISALLOW_COPY_AND_ASSIGN(MockConnectionToClientEventHandler);
};
+class MockInputStub : public InputStub {
+ public:
+ MockInputStub() {}
+
+ MOCK_METHOD2(InjectKeyEvent, void(const KeyEvent* event, Task* done));
+ MOCK_METHOD2(InjectMouseEvent, void(const MouseEvent* event, Task* done));
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockInputStub);
+};
+
+class MockHostStub : public HostStub {
+ public:
+ MockHostStub() {}
+
+ MOCK_METHOD2(SuggestResolution, void(const SuggestResolutionRequest* msg,
+ Task* done));
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockHostStub);
+};
+
} // namespace protocol
} // namespace remoting
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp
index 4402230..e1b20d3 100644
--- a/remoting/remoting.gyp
+++ b/remoting/remoting.gyp
@@ -197,7 +197,6 @@
'host/differ.cc',
'host/differ_block.h',
'host/differ_block.cc',
- 'host/event_executor.h',
'host/session_manager.cc',
'host/session_manager.h',
'host/heartbeat_sender.cc',