diff options
author | simonmorris@chromium.org <simonmorris@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-16 17:28:03 +0000 |
---|---|---|
committer | simonmorris@chromium.org <simonmorris@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-16 17:28:03 +0000 |
commit | e265ad798d7713116f2e9168eaa4913854029c20 (patch) | |
tree | 762319020e8f734beda094e7e8d0a32b8249f454 /remoting | |
parent | 856ff54b27138c316bd5433a20eeb527032e1608 (diff) | |
download | chromium_src-e265ad798d7713116f2e9168eaa4913854029c20.zip chromium_src-e265ad798d7713116f2e9168eaa4913854029c20.tar.gz chromium_src-e265ad798d7713116f2e9168eaa4913854029c20.tar.bz2 |
Add the plumbing that will carry a clipboard item from a chromoting client to a host.
BUG=117473
Review URL: http://codereview.chromium.org/9646013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@127195 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
29 files changed, 312 insertions, 71 deletions
diff --git a/remoting/base/constants.cc b/remoting/base/constants.cc index 178ec91..6c59a4c 100644 --- a/remoting/base/constants.cc +++ b/remoting/base/constants.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -18,4 +18,6 @@ const char kVideoChannelName[] = "video"; const char kVideoRtpChannelName[] = "videortp"; const char kVideoRtcpChannelName[] = "videortpc"; +const char kMimeTypeText[] = "text/plain; charset=UTF-8"; + } // namespace remoting diff --git a/remoting/base/constants.h b/remoting/base/constants.h index ed95ccc..f74159f 100644 --- a/remoting/base/constants.h +++ b/remoting/base/constants.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -24,6 +24,9 @@ extern const char kVideoChannelName[]; extern const char kVideoRtpChannelName[]; extern const char kVideoRtcpChannelName[]; +// MIME types for the clipboard. +extern const char kMimeTypeText[]; + } // namespace remoting #endif // REMOTING_BASE_CONSTANTS_H_ diff --git a/remoting/host/chromoting_host_unittest.cc b/remoting/host/chromoting_host_unittest.cc index f04be7c..a797e4b 100644 --- a/remoting/host/chromoting_host_unittest.cc +++ b/remoting/host/chromoting_host_unittest.cc @@ -93,7 +93,7 @@ class ChromotingHostTest : public testing::Test { desktop_environment_ = DesktopEnvironment::CreateFake( &context_, capturer.Pass(), - scoped_ptr<protocol::InputStub>(event_executor_)); + scoped_ptr<protocol::HostEventStub>(event_executor_)); host_ = new ChromotingHost( &context_, &signal_strategy_, desktop_environment_.get(), diff --git a/remoting/host/client_session.cc b/remoting/host/client_session.cc index 6ff6164..81abc71 100644 --- a/remoting/host/client_session.cc +++ b/remoting/host/client_session.cc @@ -28,12 +28,12 @@ using protocol::MouseEvent; ClientSession::ClientSession( EventHandler* event_handler, protocol::ConnectionToClient* connection, - protocol::InputStub* input_stub, + protocol::HostEventStub* host_event_stub, Capturer* capturer) : event_handler_(event_handler), connection_(connection), client_jid_(connection->session()->jid()), - input_stub_(input_stub), + host_event_stub_(host_event_stub), capturer_(capturer), authenticated_(false), awaiting_continue_approval_(false), @@ -43,6 +43,7 @@ ClientSession::ClientSession( // TODO(sergeyu): Currently ConnectionToClient expects stubs to be // set before channels are connected. Make it possible to set stubs // later and set them only when connection is authenticated. + connection_->set_clipboard_stub(this); connection_->set_host_stub(this); connection_->set_input_stub(this); } @@ -50,12 +51,21 @@ ClientSession::ClientSession( ClientSession::~ClientSession() { } +void ClientSession::InjectClipboardEvent( + const protocol::ClipboardEvent& event) { + DCHECK(CalledOnValidThread()); + + if (authenticated_) { + host_event_stub_->InjectClipboardEvent(event); + } +} + void ClientSession::InjectKeyEvent(const KeyEvent& event) { DCHECK(CalledOnValidThread()); if (authenticated_ && !ShouldIgnoreRemoteKeyboardInput(event)) { RecordKeyEvent(event); - input_stub_->InjectKeyEvent(event); + host_event_stub_->InjectKeyEvent(event); } } @@ -88,7 +98,7 @@ void ClientSession::InjectMouseEvent(const MouseEvent& event) { injected_mouse_positions_.pop_front(); } } - input_stub_->InjectMouseEvent(event_to_inject); + host_event_stub_->InjectMouseEvent(event_to_inject); } } @@ -242,7 +252,7 @@ void ClientSession::RestoreEventState() { KeyEvent key; key.set_keycode(*i); key.set_pressed(false); - input_stub_->InjectKeyEvent(key); + host_event_stub_->InjectKeyEvent(key); } pressed_keys_.clear(); @@ -255,7 +265,7 @@ void ClientSession::RestoreEventState() { mouse.set_y(remote_mouse_pos_.y()); mouse.set_button((MouseEvent::MouseButton)i); mouse.set_button_down(false); - input_stub_->InjectMouseEvent(mouse); + host_event_stub_->InjectMouseEvent(mouse); } } remote_mouse_button_state_ = 0; diff --git a/remoting/host/client_session.h b/remoting/host/client_session.h index 31ac079..6103c08 100644 --- a/remoting/host/client_session.h +++ b/remoting/host/client_session.h @@ -10,9 +10,10 @@ #include "base/time.h" #include "base/threading/non_thread_safe.h" +#include "remoting/protocol/clipboard_stub.h" #include "remoting/protocol/connection_to_client.h" +#include "remoting/protocol/host_event_stub.h" #include "remoting/protocol/host_stub.h" -#include "remoting/protocol/input_stub.h" #include "third_party/skia/include/core/SkPoint.h" namespace remoting { @@ -21,8 +22,8 @@ class Capturer; // A ClientSession keeps a reference to a connection to a client, and maintains // per-client state. -class ClientSession : public protocol::HostStub, - public protocol::InputStub, +class ClientSession : public protocol::HostEventStub, + public protocol::HostStub, public protocol::ConnectionToClient::EventHandler, public base::NonThreadSafe { public: @@ -57,13 +58,17 @@ class ClientSession : public protocol::HostStub, }; // Takes ownership of |connection|. Does not take ownership of - // |event_handler|, |input_stub| or |capturer|. + // |event_handler|, |host_event_stub|, or |capturer|. ClientSession(EventHandler* event_handler, protocol::ConnectionToClient* connection, - protocol::InputStub* input_stub, + protocol::HostEventStub* host_event_stub, Capturer* capturer); virtual ~ClientSession(); + // protocol::ClipboardStub interface. + virtual void InjectClipboardEvent( + const protocol::ClipboardEvent& event) OVERRIDE; + // protocol::InputStub interface. virtual void InjectKeyEvent(const protocol::KeyEvent& event) OVERRIDE; virtual void InjectMouseEvent(const protocol::MouseEvent& event) OVERRIDE; @@ -130,8 +135,8 @@ class ClientSession : public protocol::HostStub, std::string client_jid_; - // The input stub to which this object delegates. - protocol::InputStub* input_stub_; + // The host event stub to which this object delegates. + protocol::HostEventStub* host_event_stub_; // Capturer, used to determine current screen size for ensuring injected // mouse events fall within the screen area. diff --git a/remoting/host/client_session_unittest.cc b/remoting/host/client_session_unittest.cc index 0f8b61e..38a9171 100644 --- a/remoting/host/client_session_unittest.cc +++ b/remoting/host/client_session_unittest.cc @@ -1,7 +1,8 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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/base/constants.h" #include "remoting/host/client_session.h" #include "remoting/host/host_mock_objects.h" #include "remoting/protocol/protocol_mock_objects.h" @@ -12,7 +13,7 @@ namespace remoting { using protocol::MockConnectionToClient; using protocol::MockConnectionToClientEventHandler; using protocol::MockHostStub; -using protocol::MockInputStub; +using protocol::MockHostEventStub; using protocol::MockSession; using testing::_; @@ -40,7 +41,7 @@ class ClientSessionTest : public testing::Test { client_session_.reset(new ClientSession( &session_event_handler_, new protocol::ConnectionToClient(session), - &input_stub_, &capturer_)); + &host_event_stub_, &capturer_)); } virtual void TearDown() OVERRIDE { @@ -55,12 +56,47 @@ class ClientSessionTest : public testing::Test { MessageLoop message_loop_; std::string client_jid_; MockHostStub host_stub_; - MockInputStub input_stub_; + MockHostEventStub host_event_stub_; MockCapturer capturer_; MockClientSessionEventHandler session_event_handler_; scoped_ptr<ClientSession> client_session_; }; +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(kMimeTypeText); + clipboard_event1.set_data("a"); + + protocol::ClipboardEvent clipboard_event2; + clipboard_event2.set_mime_type(kMimeTypeText); + clipboard_event2.set_data("b"); + + protocol::ClipboardEvent clipboard_event3; + clipboard_event3.set_mime_type(kMimeTypeText); + clipboard_event3.set_data("c"); + + InSequence s; + EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_)); + EXPECT_CALL(host_event_stub_, InjectClipboardEvent(EqualsClipboardEvent( + kMimeTypeText, "b"))); + + // This event should not get through to the clipboard stub, + // because the client isn't authenticated yet. + client_session_->InjectClipboardEvent(clipboard_event1); + client_session_->OnConnectionOpened(client_session_->connection()); + // This event should get through to the clipboard stub. + client_session_->InjectClipboardEvent(clipboard_event2); + client_session_->Disconnect(); + // This event should not get through to the clipboard stub, + // because the client has disconnected. + client_session_->InjectClipboardEvent(clipboard_event3); +} + MATCHER_P2(EqualsKeyEvent, keycode, pressed, "") { return arg.keycode() == keycode && arg.pressed() == pressed; } @@ -104,9 +140,9 @@ TEST_F(ClientSessionTest, InputStubFilter) { InSequence s; EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_)); - EXPECT_CALL(input_stub_, InjectKeyEvent(EqualsKeyEvent(2, true))); - EXPECT_CALL(input_stub_, InjectKeyEvent(EqualsKeyEvent(2, false))); - EXPECT_CALL(input_stub_, InjectMouseEvent(EqualsMouseEvent(200, 201))); + EXPECT_CALL(host_event_stub_, InjectKeyEvent(EqualsKeyEvent(2, true))); + EXPECT_CALL(host_event_stub_, InjectKeyEvent(EqualsKeyEvent(2, false))); + EXPECT_CALL(host_event_stub_, InjectMouseEvent(EqualsMouseEvent(200, 201))); // These events should not get through to the input stub, // because the client isn't authenticated yet. @@ -138,8 +174,8 @@ TEST_F(ClientSessionTest, LocalInputTest) { InSequence s; EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(client_session_.get())); - EXPECT_CALL(input_stub_, InjectMouseEvent(EqualsMouseEvent(100, 101))); - EXPECT_CALL(input_stub_, InjectMouseEvent(EqualsMouseEvent(200, 201))); + EXPECT_CALL(host_event_stub_, InjectMouseEvent(EqualsMouseEvent(100, 101))); + EXPECT_CALL(host_event_stub_, InjectMouseEvent(EqualsMouseEvent(200, 201))); client_session_->OnConnectionOpened(client_session_->connection()); // This event should get through to the input stub. @@ -174,9 +210,9 @@ TEST_F(ClientSessionTest, RestoreEventState) { client_session_->RecordKeyEvent(key2); client_session_->RecordMouseButtonState(mousedown); - EXPECT_CALL(input_stub_, InjectKeyEvent(EqualsKeyEvent(1, false))); - EXPECT_CALL(input_stub_, InjectKeyEvent(EqualsKeyEvent(2, false))); - EXPECT_CALL(input_stub_, InjectMouseEvent(EqualsMouseUpEvent( + EXPECT_CALL(host_event_stub_, InjectKeyEvent(EqualsKeyEvent(1, false))); + EXPECT_CALL(host_event_stub_, InjectKeyEvent(EqualsKeyEvent(2, false))); + EXPECT_CALL(host_event_stub_, InjectMouseEvent(EqualsMouseUpEvent( protocol::MouseEvent::BUTTON_LEFT))); client_session_->RestoreEventState(); @@ -201,7 +237,7 @@ TEST_F(ClientSessionTest, ClampMouseEvents) { for (int i = 0; i < 3; i++) { event.set_x(input_x[i]); event.set_y(input_y[j]); - EXPECT_CALL(input_stub_, InjectMouseEvent(EqualsMouseEvent( + EXPECT_CALL(host_event_stub_, InjectMouseEvent(EqualsMouseEvent( expected_x[i], expected_y[j]))); client_session_->InjectMouseEvent(event); } diff --git a/remoting/host/desktop_environment.cc b/remoting/host/desktop_environment.cc index 43ed501..75e784b 100644 --- a/remoting/host/desktop_environment.cc +++ b/remoting/host/desktop_environment.cc @@ -21,7 +21,7 @@ namespace remoting { scoped_ptr<DesktopEnvironment> DesktopEnvironment::Create( ChromotingHostContext* context) { scoped_ptr<Capturer> capturer(Capturer::Create()); - scoped_ptr<protocol::InputStub> event_executor = + scoped_ptr<protocol::HostEventStub> event_executor = EventExecutor::Create(context->desktop_message_loop(), capturer.get()); @@ -47,7 +47,7 @@ scoped_ptr<DesktopEnvironment> DesktopEnvironment::Create( scoped_ptr<DesktopEnvironment> DesktopEnvironment::CreateFake( ChromotingHostContext* context, scoped_ptr<Capturer> capturer, - scoped_ptr<protocol::InputStub> event_executor) { + scoped_ptr<protocol::HostEventStub> event_executor) { return scoped_ptr<DesktopEnvironment>( new DesktopEnvironment(context, capturer.Pass(), @@ -57,7 +57,7 @@ scoped_ptr<DesktopEnvironment> DesktopEnvironment::CreateFake( DesktopEnvironment::DesktopEnvironment( ChromotingHostContext* context, scoped_ptr<Capturer> capturer, - scoped_ptr<protocol::InputStub> event_executor) + scoped_ptr<protocol::HostEventStub> event_executor) : host_(NULL), context_(context), capturer_(capturer.Pass()), diff --git a/remoting/host/desktop_environment.h b/remoting/host/desktop_environment.h index 5573cfc..d3058e0 100644 --- a/remoting/host/desktop_environment.h +++ b/remoting/host/desktop_environment.h @@ -20,7 +20,7 @@ class ChromotingHost; class ChromotingHostContext; namespace protocol { -class InputStub; +class HostEventStub; }; class DesktopEnvironment { @@ -29,19 +29,21 @@ class DesktopEnvironment { static scoped_ptr<DesktopEnvironment> CreateFake( ChromotingHostContext* context, scoped_ptr<Capturer> capturer, - scoped_ptr<protocol::InputStub> event_executor); + scoped_ptr<protocol::HostEventStub> event_executor); virtual ~DesktopEnvironment(); void set_host(ChromotingHost* host) { host_ = host; } Capturer* capturer() const { return capturer_.get(); } - protocol::InputStub* event_executor() const { return event_executor_.get(); } + protocol::HostEventStub* event_executor() const { + return event_executor_.get(); + } private: DesktopEnvironment(ChromotingHostContext* context, scoped_ptr<Capturer> capturer, - scoped_ptr<protocol::InputStub> event_executor); + scoped_ptr<protocol::HostEventStub> event_executor); // The host that owns this DesktopEnvironment. ChromotingHost* host_; @@ -53,8 +55,8 @@ class DesktopEnvironment { // Capturer to be used by ScreenRecorder. scoped_ptr<Capturer> capturer_; - // Executes input events received from the client. - scoped_ptr<protocol::InputStub> event_executor_; + // Executes input and clipboard events received from the client. + scoped_ptr<protocol::HostEventStub> event_executor_; DISALLOW_COPY_AND_ASSIGN(DesktopEnvironment); }; diff --git a/remoting/host/event_executor.h b/remoting/host/event_executor.h index bcde0ba..70727d0 100644 --- a/remoting/host/event_executor.h +++ b/remoting/host/event_executor.h @@ -6,8 +6,7 @@ #define REMOTING_HOST_EVENT_EXECUTOR_H_ #include "base/memory/scoped_ptr.h" - -#include "remoting/protocol/input_stub.h" +#include "remoting/protocol/host_event_stub.h" class MessageLoop; @@ -15,12 +14,12 @@ namespace remoting { class Capturer; -class EventExecutor : public protocol::InputStub { +class EventExecutor : public protocol::HostEventStub { public: // Creates default event executor for the current platform. // Does not take ownership of |message_loop| or |capturer|. - static scoped_ptr<protocol::InputStub> Create(MessageLoop* message_loop, - Capturer* capturer); + static scoped_ptr<protocol::HostEventStub> Create(MessageLoop* message_loop, + Capturer* capturer); }; } // namespace remoting diff --git a/remoting/host/event_executor_linux.cc b/remoting/host/event_executor_linux.cc index b1829ec..bf2d518 100644 --- a/remoting/host/event_executor_linux.cc +++ b/remoting/host/event_executor_linux.cc @@ -20,8 +20,9 @@ namespace remoting { -using protocol::MouseEvent; +using protocol::ClipboardEvent; using protocol::KeyEvent; +using protocol::MouseEvent; namespace { @@ -37,6 +38,11 @@ class EventExecutorLinux : public EventExecutor { bool Init(); + // Clipboard stub interface. + virtual void InjectClipboardEvent(const ClipboardEvent& event) + OVERRIDE; + + // InputStub interface. virtual void InjectKeyEvent(const KeyEvent& event) OVERRIDE; virtual void InjectMouseEvent(const MouseEvent& event) OVERRIDE; @@ -314,6 +320,10 @@ bool EventExecutorLinux::Init() { return true; } +void EventExecutorLinux::InjectClipboardEvent(const ClipboardEvent& event) { + // TODO(simonmorris): Implement clipboard injection. +} + void EventExecutorLinux::InjectKeyEvent(const KeyEvent& event) { if (MessageLoop::current() != message_loop_) { message_loop_->PostTask( @@ -453,14 +463,14 @@ void EventExecutorLinux::InjectMouseEvent(const MouseEvent& event) { } // namespace -scoped_ptr<protocol::InputStub> EventExecutor::Create(MessageLoop* message_loop, - Capturer* capturer) { +scoped_ptr<protocol::HostEventStub> EventExecutor::Create( + MessageLoop* message_loop, Capturer* capturer) { scoped_ptr<EventExecutorLinux> executor( new EventExecutorLinux(message_loop, capturer)); if (!executor->Init()) { executor.reset(NULL); } - return executor.PassAs<protocol::InputStub>(); + return executor.PassAs<protocol::HostEventStub>(); } } // namespace remoting diff --git a/remoting/host/event_executor_mac.cc b/remoting/host/event_executor_mac.cc index 799b892..022e13d 100644 --- a/remoting/host/event_executor_mac.cc +++ b/remoting/host/event_executor_mac.cc @@ -24,8 +24,9 @@ namespace { #include "remoting/host/usb_keycode_map.h" #define INVALID_KEYCODE 0xffff -using protocol::MouseEvent; +using protocol::ClipboardEvent; using protocol::KeyEvent; +using protocol::MouseEvent; // A class to generate events on Mac. class EventExecutorMac : public EventExecutor { @@ -33,6 +34,10 @@ class EventExecutorMac : public EventExecutor { EventExecutorMac(MessageLoop* message_loop, Capturer* capturer); virtual ~EventExecutorMac() {} + // ClipboardStub interface. + virtual void InjectClipboardEvent(const ClipboardEvent& event) OVERRIDE; + + // InputStub interface. virtual void InjectKeyEvent(const KeyEvent& event) OVERRIDE; virtual void InjectMouseEvent(const MouseEvent& event) OVERRIDE; @@ -245,6 +250,10 @@ uint16_t UsbKeycodeToMacKeycode(uint32_t usb_keycode) { return INVALID_KEYCODE; } +void EventExecutorMac::InjectClipboardEvent(const ClipboardEvent& event) { + // TODO(simonmorris): Implement clipboard injection. +} + void EventExecutorMac::InjectKeyEvent(const KeyEvent& event) { int keycode = 0; if (event.has_usb_keycode() && event.usb_keycode() != INVALID_KEYCODE) { @@ -331,9 +340,9 @@ void EventExecutorMac::InjectMouseEvent(const MouseEvent& event) { } // namespace -scoped_ptr<protocol::InputStub> EventExecutor::Create(MessageLoop* message_loop, - Capturer* capturer) { - return scoped_ptr<protocol::InputStub>( +scoped_ptr<protocol::HostEventStub> EventExecutor::Create( + MessageLoop* message_loop, Capturer* capturer) { + return scoped_ptr<protocol::HostEventStub>( new EventExecutorMac(message_loop, capturer)); } diff --git a/remoting/host/event_executor_win.cc b/remoting/host/event_executor_win.cc index 2a1871e..75ce205 100644 --- a/remoting/host/event_executor_win.cc +++ b/remoting/host/event_executor_win.cc @@ -15,8 +15,9 @@ namespace remoting { -using protocol::MouseEvent; +using protocol::ClipboardEvent; using protocol::KeyEvent; +using protocol::MouseEvent; namespace { @@ -32,6 +33,10 @@ class EventExecutorWin : public EventExecutor { EventExecutorWin(MessageLoop* message_loop, Capturer* capturer); virtual ~EventExecutorWin() {} + // ClipboardStub interface. + virtual void InjectClipboardEvent(const ClipboardEvent& event) OVERRIDE; + + // InputStub interface. virtual void InjectKeyEvent(const KeyEvent& event) OVERRIDE; virtual void InjectMouseEvent(const MouseEvent& event) OVERRIDE; @@ -51,6 +56,10 @@ EventExecutorWin::EventExecutorWin(MessageLoop* message_loop, capturer_(capturer) { } +void EventExecutorWin::InjectClipboardEvent(const ClipboardEvent& event) { + // TODO(simonmorris): Implement clipboard injection. +} + void EventExecutorWin::InjectKeyEvent(const KeyEvent& event) { if (MessageLoop::current() != message_loop_) { message_loop_->PostTask( @@ -194,9 +203,9 @@ void EventExecutorWin::HandleMouse(const MouseEvent& event) { } // namespace -scoped_ptr<protocol::InputStub> EventExecutor::Create(MessageLoop* message_loop, - Capturer* capturer) { - return scoped_ptr<protocol::InputStub>( +scoped_ptr<protocol::HostEventStub> EventExecutor::Create( + MessageLoop* message_loop, Capturer* capturer) { + return scoped_ptr<protocol::HostEventStub>( new EventExecutorWin(message_loop, capturer)); } diff --git a/remoting/host/host_mock_objects.h b/remoting/host/host_mock_objects.h index 967613f..4df9e2a 100644 --- a/remoting/host/host_mock_objects.h +++ b/remoting/host/host_mock_objects.h @@ -120,6 +120,8 @@ class MockEventExecutor : public EventExecutor { MockEventExecutor(); virtual ~MockEventExecutor(); + MOCK_METHOD1(InjectClipboardEvent, + void(const protocol::ClipboardEvent& event)); MOCK_METHOD1(InjectKeyEvent, void(const protocol::KeyEvent& event)); MOCK_METHOD1(InjectMouseEvent, void(const protocol::MouseEvent& event)); diff --git a/remoting/host/simple_host_process.cc b/remoting/host/simple_host_process.cc index 16ed0a1..eda7fa7 100644 --- a/remoting/host/simple_host_process.cc +++ b/remoting/host/simple_host_process.cc @@ -216,7 +216,7 @@ class SimpleHost { if (fake_) { scoped_ptr<Capturer> capturer(new CapturerFake()); - scoped_ptr<protocol::InputStub> event_executor = + scoped_ptr<protocol::HostEventStub> event_executor = EventExecutor::Create( context_.desktop_message_loop(), capturer.get()); desktop_environment_ = DesktopEnvironment::CreateFake( diff --git a/remoting/proto/event.proto b/remoting/proto/event.proto index dcc2aae..e42f5d3 100644 --- a/remoting/proto/event.proto +++ b/remoting/proto/event.proto @@ -48,3 +48,13 @@ message MouseEvent { optional MouseButton button = 5; optional bool button_down = 6; } + +// Defines an event that sends clipboard data between peers. +message ClipboardEvent { + + // The MIME type of the data being sent. + optional string mime_type = 1; + + // The data being sent. + optional bytes data = 2; +} diff --git a/remoting/proto/internal.proto b/remoting/proto/internal.proto index e63982d..a65b677 100644 --- a/remoting/proto/internal.proto +++ b/remoting/proto/internal.proto @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -16,12 +16,13 @@ package remoting.protocol; // Represents a message being sent on the control channel. message ControlMessage { + optional ClipboardEvent clipboard_event = 1; } // Defines an event message on the event channel. message EventMessage { - required int64 sequence_number = 1; // Client timestamp for event - optional bool dummy = 2; // Is this a dummy event? + required int64 sequence_number = 1; // Client timestamp for event. + optional bool dummy = 2; // Whether this is a dummy event. optional KeyEvent key_event = 3; optional MouseEvent mouse_event = 4; diff --git a/remoting/protocol/client_control_dispatcher.cc b/remoting/protocol/client_control_dispatcher.cc index e9b7d09..8503f19 100644 --- a/remoting/protocol/client_control_dispatcher.cc +++ b/remoting/protocol/client_control_dispatcher.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -13,6 +13,7 @@ #include "remoting/proto/internal.pb.h" #include "remoting/protocol/buffered_socket_writer.h" #include "remoting/protocol/client_stub.h" +#include "remoting/protocol/util.h" namespace remoting { namespace protocol { @@ -34,6 +35,13 @@ void ClientControlDispatcher::OnInitialized() { &ClientControlDispatcher::OnMessageReceived, base::Unretained(this))); } +void ClientControlDispatcher::InjectClipboardEvent( + const ClipboardEvent& event) { + ControlMessage message; + message.mutable_clipboard_event()->CopyFrom(event); + writer_->Write(SerializeAndFrameMessage(message), base::Closure()); +} + void ClientControlDispatcher::OnMessageReceived( ControlMessage* message, const base::Closure& done_task) { DCHECK(client_stub_); diff --git a/remoting/protocol/client_control_dispatcher.h b/remoting/protocol/client_control_dispatcher.h index 2550a2c..df43420 100644 --- a/remoting/protocol/client_control_dispatcher.h +++ b/remoting/protocol/client_control_dispatcher.h @@ -7,6 +7,7 @@ #include "base/memory/ref_counted.h" #include "remoting/protocol/channel_dispatcher_base.h" +#include "remoting/protocol/clipboard_stub.h" #include "remoting/protocol/host_stub.h" #include "remoting/protocol/message_reader.h" @@ -19,13 +20,18 @@ class BufferedSocketWriter; class Session; // ClientControlDispatcher dispatches incoming messages on the control -// channel to ClientStub, and also implements HostStub for outgoing -// messages. -class ClientControlDispatcher : public ChannelDispatcherBase, public HostStub { +// channel to ClientStub, and also implements ClipboardStub and HostStub for +// outgoing messages. +class ClientControlDispatcher : public ChannelDispatcherBase, + public ClipboardStub, + public HostStub { public: ClientControlDispatcher(); virtual ~ClientControlDispatcher(); + // ClipboardStub implementation. + virtual void InjectClipboardEvent(const ClipboardEvent& event) OVERRIDE; + // Sets ClientStub that will be called for each incoming control // message. Doesn't take ownership of |client_stub|. It must outlive // this dispatcher. diff --git a/remoting/protocol/clipboard_stub.h b/remoting/protocol/clipboard_stub.h new file mode 100644 index 0000000..2cc5051 --- /dev/null +++ b/remoting/protocol/clipboard_stub.h @@ -0,0 +1,32 @@ +// Copyright (c) 2012 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. + +// Interface for an object that receives clipboard events. +// This interface handles some event messages defined in event.proto. + +#ifndef REMOTING_PROTOCOL_CLIPBOARD_STUB_H_ +#define REMOTING_PROTOCOL_CLIPBOARD_STUB_H_ + +#include "base/basictypes.h" + +namespace remoting { +namespace protocol { + +class ClipboardEvent; + +class ClipboardStub { + public: + ClipboardStub() {} + virtual ~ClipboardStub() {} + + virtual void InjectClipboardEvent(const ClipboardEvent& event) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(ClipboardStub); +}; + +} // namespace protocol +} // namespace remoting + +#endif // REMOTING_PROTOCOL_CLIPBOARD_STUB_H_ diff --git a/remoting/protocol/connection_to_client.cc b/remoting/protocol/connection_to_client.cc index b88cb06..8226b1f 100644 --- a/remoting/protocol/connection_to_client.cc +++ b/remoting/protocol/connection_to_client.cc @@ -9,6 +9,7 @@ #include "base/message_loop_proxy.h" #include "google/protobuf/message.h" #include "net/base/io_buffer.h" +#include "remoting/protocol/clipboard_stub.h" #include "remoting/protocol/host_control_dispatcher.h" #include "remoting/protocol/host_event_dispatcher.h" #include "remoting/protocol/host_stub.h" @@ -19,6 +20,7 @@ namespace protocol { ConnectionToClient::ConnectionToClient(protocol::Session* session) : handler_(NULL), + clipboard_stub_(NULL), host_stub_(NULL), input_stub_(NULL), session_(session) { @@ -72,6 +74,12 @@ ClientStub* ConnectionToClient::client_stub() { return control_dispatcher_.get(); } +void ConnectionToClient::set_clipboard_stub( + protocol::ClipboardStub* clipboard_stub) { + DCHECK(CalledOnValidThread()); + clipboard_stub_ = clipboard_stub; +} + void ConnectionToClient::set_host_stub(protocol::HostStub* host_stub) { DCHECK(CalledOnValidThread()); host_stub_ = host_stub; @@ -98,6 +106,7 @@ void ConnectionToClient::OnSessionStateChange(Session::State state) { control_dispatcher_.reset(new HostControlDispatcher()); control_dispatcher_->Init(session_.get(), base::Bind( &ConnectionToClient::OnChannelInitialized, base::Unretained(this))); + control_dispatcher_->set_clipboard_stub(clipboard_stub_); control_dispatcher_->set_host_stub(host_stub_); event_dispatcher_.reset(new HostEventDispatcher()); diff --git a/remoting/protocol/connection_to_client.h b/remoting/protocol/connection_to_client.h index 80a91fb..3b2f57e 100644 --- a/remoting/protocol/connection_to_client.h +++ b/remoting/protocol/connection_to_client.h @@ -23,6 +23,7 @@ namespace remoting { namespace protocol { class ClientStub; +class ClipboardStub; class HostStub; class InputStub; class HostControlDispatcher; @@ -84,7 +85,8 @@ class ConnectionToClient : public base::NonThreadSafe { // Return pointer to ClientStub. virtual ClientStub* client_stub(); - // These two setters should be called before Init(). + // These three setters should be called before Init(). + virtual void set_clipboard_stub(ClipboardStub* clipboard_stub); virtual void set_host_stub(HostStub* host_stub); virtual void set_input_stub(InputStub* input_stub); @@ -110,6 +112,7 @@ class ConnectionToClient : public base::NonThreadSafe { EventHandler* handler_; // Stubs that are called for incoming messages. + ClipboardStub* clipboard_stub_; HostStub* host_stub_; InputStub* input_stub_; diff --git a/remoting/protocol/connection_to_client_unittest.cc b/remoting/protocol/connection_to_client_unittest.cc index 0be7389..2e16de7 100644 --- a/remoting/protocol/connection_to_client_unittest.cc +++ b/remoting/protocol/connection_to_client_unittest.cc @@ -31,6 +31,7 @@ class ConnectionToClientTest : public testing::Test { // Allocate a ClientConnection object with the mock objects. viewer_.reset(new ConnectionToClient(session_)); + viewer_->set_clipboard_stub(&clipboard_stub_); viewer_->set_host_stub(&host_stub_); viewer_->set_input_stub(&input_stub_); viewer_->SetEventHandler(&handler_); @@ -49,6 +50,7 @@ class ConnectionToClientTest : public testing::Test { MessageLoop message_loop_; MockConnectionToClientEventHandler handler_; + MockClipboardStub clipboard_stub_; MockHostStub host_stub_; MockInputStub input_stub_; scoped_ptr<ConnectionToClient> viewer_; diff --git a/remoting/protocol/host_control_dispatcher.cc b/remoting/protocol/host_control_dispatcher.cc index 44f302c..0906b6c 100644 --- a/remoting/protocol/host_control_dispatcher.cc +++ b/remoting/protocol/host_control_dispatcher.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -10,6 +10,7 @@ #include "remoting/proto/control.pb.h" #include "remoting/proto/internal.pb.h" #include "remoting/protocol/buffered_socket_writer.h" +#include "remoting/protocol/clipboard_stub.h" #include "remoting/protocol/host_stub.h" #include "remoting/protocol/util.h" @@ -18,6 +19,7 @@ namespace protocol { HostControlDispatcher::HostControlDispatcher() : ChannelDispatcherBase(kControlChannelName), + clipboard_stub_(NULL), host_stub_(NULL), writer_(new BufferedSocketWriter(base::MessageLoopProxy::current())) { } @@ -34,9 +36,16 @@ void HostControlDispatcher::OnInitialized() { void HostControlDispatcher::OnMessageReceived( ControlMessage* message, const base::Closure& done_task) { + DCHECK(clipboard_stub_); DCHECK(host_stub_); - LOG(WARNING) << "Unknown control message received."; - done_task.Run(); + + base::ScopedClosureRunner done_runner(done_task); + + if (message->has_clipboard_event()) { + clipboard_stub_->InjectClipboardEvent(message->clipboard_event()); + } else { + LOG(WARNING) << "Unknown control message received."; + } } } // namespace protocol diff --git a/remoting/protocol/host_control_dispatcher.h b/remoting/protocol/host_control_dispatcher.h index 2bda655..fab197d 100644 --- a/remoting/protocol/host_control_dispatcher.h +++ b/remoting/protocol/host_control_dispatcher.h @@ -18,18 +18,26 @@ namespace remoting { namespace protocol { class BufferedSocketWriter; +class ClipboardStub; class ControlMessage; class HostStub; class Session; // HostControlDispatcher dispatches incoming messages on the control -// channel to HostStub, and also implements ClientStub for outgoing -// messages. +// channel to HostStub or ClipboardStub, and also implements ClientStub for +// outgoing messages. class HostControlDispatcher : public ChannelDispatcherBase, public ClientStub { public: HostControlDispatcher(); virtual ~HostControlDispatcher(); + // Sets the ClipboardStub that will be called for each incoming clipboard + // message. Doesn't take ownership of |clipboard_stub|, which must outlive + // the dispatcher. + void set_clipboard_stub(ClipboardStub* clipboard_stub) { + clipboard_stub_ = clipboard_stub; + } + // Sets HostStub that will be called for each incoming control // message. Doesn't take ownership of |host_stub|. It must outlive // this dispatcher. @@ -43,6 +51,7 @@ class HostControlDispatcher : public ChannelDispatcherBase, public ClientStub { void OnMessageReceived(ControlMessage* message, const base::Closure& done_task); + ClipboardStub* clipboard_stub_; HostStub* host_stub_; ProtobufMessageReader<ControlMessage> reader_; diff --git a/remoting/protocol/host_event_stub.h b/remoting/protocol/host_event_stub.h new file mode 100644 index 0000000..6b55d55 --- /dev/null +++ b/remoting/protocol/host_event_stub.h @@ -0,0 +1,29 @@ +// Copyright (c) 2012 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. + +// Interface for an object that handles input and clipboard events. + +#ifndef REMOTING_PROTOCOL_HOST_EVENT_STUB_H_ +#define REMOTING_PROTOCOL_HOST_EVENT_STUB_H_ + +#include "base/basictypes.h" +#include "remoting/protocol/clipboard_stub.h" +#include "remoting/protocol/input_stub.h" + +namespace remoting { +namespace protocol { + +class HostEventStub : public ClipboardStub, public InputStub { + public: + HostEventStub() {} + virtual ~HostEventStub() {} + + private: + DISALLOW_COPY_AND_ASSIGN(HostEventStub); +}; + +} // namespace protocol +} // namespace remoting + +#endif // REMOTING_PROTOCOL_HOST_EVENT_STUB_H_ diff --git a/remoting/protocol/input_stub.h b/remoting/protocol/input_stub.h index b7ec67e..121ca98 100644 --- a/remoting/protocol/input_stub.h +++ b/remoting/protocol/input_stub.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. // Interface for a device that receives input events. -// This interface handles event messages defined in event.proto. +// This interface handles input event messages defined in event.proto. #ifndef REMOTING_PROTOCOL_INPUT_STUB_H_ #define REMOTING_PROTOCOL_INPUT_STUB_H_ diff --git a/remoting/protocol/protocol_mock_objects.cc b/remoting/protocol/protocol_mock_objects.cc index 09a169d..5a48cd8 100644 --- a/remoting/protocol/protocol_mock_objects.cc +++ b/remoting/protocol/protocol_mock_objects.cc @@ -25,10 +25,18 @@ MockConnectionToClientEventHandler::MockConnectionToClientEventHandler() {} MockConnectionToClientEventHandler::~MockConnectionToClientEventHandler() {} +MockClipboardStub::MockClipboardStub() {} + +MockClipboardStub::~MockClipboardStub() {} + MockInputStub::MockInputStub() {} MockInputStub::~MockInputStub() {} +MockHostEventStub::MockHostEventStub() {} + +MockHostEventStub::~MockHostEventStub() {} + MockHostStub::MockHostStub() {} MockHostStub::~MockHostStub() {} diff --git a/remoting/protocol/protocol_mock_objects.h b/remoting/protocol/protocol_mock_objects.h index 20a56b3..6a7c0a84 100644 --- a/remoting/protocol/protocol_mock_objects.h +++ b/remoting/protocol/protocol_mock_objects.h @@ -10,7 +10,9 @@ #include "net/base/ip_endpoint.h" #include "remoting/proto/internal.pb.h" #include "remoting/protocol/client_stub.h" +#include "remoting/protocol/clipboard_stub.h" #include "remoting/protocol/connection_to_client.h" +#include "remoting/protocol/host_event_stub.h" #include "remoting/protocol/host_stub.h" #include "remoting/protocol/input_stub.h" #include "remoting/protocol/session.h" @@ -59,6 +61,17 @@ class MockConnectionToClientEventHandler : DISALLOW_COPY_AND_ASSIGN(MockConnectionToClientEventHandler); }; +class MockClipboardStub : public ClipboardStub { + public: + MockClipboardStub(); + virtual ~MockClipboardStub(); + + MOCK_METHOD1(InjectClipboardEvent, void(const ClipboardEvent& event)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockClipboardStub); +}; + class MockInputStub : public InputStub { public: MockInputStub(); @@ -71,6 +84,19 @@ class MockInputStub : public InputStub { DISALLOW_COPY_AND_ASSIGN(MockInputStub); }; +class MockHostEventStub : public HostEventStub { + public: + MockHostEventStub(); + virtual ~MockHostEventStub(); + + MOCK_METHOD1(InjectClipboardEvent, void(const ClipboardEvent& event)); + MOCK_METHOD1(InjectKeyEvent, void(const KeyEvent& event)); + MOCK_METHOD1(InjectMouseEvent, void(const MouseEvent& event)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockHostEventStub); +}; + class MockHostStub : public HostStub { public: MockHostStub(); diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index a37d057..c3ce7f6 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -846,6 +846,7 @@ 'protocol/client_event_dispatcher.cc', 'protocol/client_event_dispatcher.h', 'protocol/client_stub.h', + 'protocol/clipboard_stub.h', 'protocol/connection_to_client.cc', 'protocol/connection_to_client.h', 'protocol/connection_to_host.cc', @@ -857,6 +858,7 @@ 'protocol/host_control_dispatcher.h', 'protocol/host_event_dispatcher.cc', 'protocol/host_event_dispatcher.h', + 'protocol/host_event_stub.h', 'protocol/host_stub.h', 'protocol/input_filter.cc', 'protocol/input_filter.h', |