diff options
author | simonmorris@chromium.org <simonmorris@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-22 22:29:24 +0000 |
---|---|---|
committer | simonmorris@chromium.org <simonmorris@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-22 22:29:24 +0000 |
commit | ff3761a1e35e0d5ef9e3c00beeadd3c565a4b84f (patch) | |
tree | 6ec789e2b8ba63d88d29af7e6741bf335784a73e | |
parent | b44a986ebf6b56ad74a5efcbd2395851e815489c (diff) | |
download | chromium_src-ff3761a1e35e0d5ef9e3c00beeadd3c565a4b84f.zip chromium_src-ff3761a1e35e0d5ef9e3c00beeadd3c565a4b84f.tar.gz chromium_src-ff3761a1e35e0d5ef9e3c00beeadd3c565a4b84f.tar.bz2 |
[Chromoting] Add a filter that will stop the host sending unnecessary clipboard events to the client.
The host does not yet send any clipboard events to the client. A follow-up CL will make that happen.
BUG=117473
Review URL: https://chromiumcodereview.appspot.com/10399052
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@138377 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | remoting/client/chromoting_client.h | 1 | ||||
-rw-r--r-- | remoting/host/client_session.cc | 5 | ||||
-rw-r--r-- | remoting/host/client_session.h | 5 | ||||
-rw-r--r-- | remoting/protocol/client_stub.h | 5 | ||||
-rw-r--r-- | remoting/protocol/clipboard_echo_filter.cc | 78 | ||||
-rw-r--r-- | remoting/protocol/clipboard_echo_filter.h | 75 | ||||
-rw-r--r-- | remoting/protocol/clipboard_echo_filter_unittest.cc | 111 | ||||
-rw-r--r-- | remoting/protocol/host_control_dispatcher.h | 7 | ||||
-rw-r--r-- | remoting/protocol/protocol_mock_objects.h | 2 | ||||
-rw-r--r-- | remoting/remoting.gyp | 3 |
10 files changed, 284 insertions, 8 deletions
diff --git a/remoting/client/chromoting_client.h b/remoting/client/chromoting_client.h index 765b523..d784b5a 100644 --- a/remoting/client/chromoting_client.h +++ b/remoting/client/chromoting_client.h @@ -36,7 +36,6 @@ class RectangleUpdateDecoder; // TODO(sergeyu): Move VideoStub implementation to RectangleUpdateDecoder. class ChromotingClient : public protocol::ConnectionToHost::HostEventCallback, public protocol::ClientStub, - public protocol::ClipboardStub, public protocol::VideoStub { public: // Objects passed in are not owned by this class. diff --git a/remoting/host/client_session.cc b/remoting/host/client_session.cc index 180ecc8..86a6753 100644 --- a/remoting/host/client_session.cc +++ b/remoting/host/client_session.cc @@ -10,6 +10,7 @@ #include "remoting/host/capturer.h" #include "remoting/proto/control.pb.h" #include "remoting/proto/event.pb.h" +#include "remoting/protocol/client_stub.h" namespace remoting { @@ -35,6 +36,7 @@ ClientSession::ClientSession( connection_->set_clipboard_stub(this); connection_->set_host_stub(this); connection_->set_input_stub(this); + clipboard_echo_filter_.set_host_stub(host_event_stub_); } ClientSession::~ClientSession() { @@ -51,7 +53,7 @@ void ClientSession::InjectClipboardEvent( if (disable_input_filter_.input_stub() == NULL) return; - host_event_stub_->InjectClipboardEvent(event); + clipboard_echo_filter_.host_filter()->InjectClipboardEvent(event); } void ClientSession::InjectKeyEvent(const protocol::KeyEvent& event) { @@ -93,6 +95,7 @@ void ClientSession::OnConnectionAuthenticated( DCHECK_EQ(connection_.get(), connection); is_authenticated_ = true; auth_input_filter_.set_input_stub(&disable_input_filter_); + clipboard_echo_filter_.set_client_stub(connection_->client_stub()); event_handler_->OnSessionAuthenticated(this); } diff --git a/remoting/host/client_session.h b/remoting/host/client_session.h index e61e846..fd2b9a08 100644 --- a/remoting/host/client_session.h +++ b/remoting/host/client_session.h @@ -10,6 +10,7 @@ #include "base/time.h" #include "base/threading/non_thread_safe.h" #include "remoting/host/remote_input_filter.h" +#include "remoting/protocol/clipboard_echo_filter.h" #include "remoting/protocol/clipboard_stub.h" #include "remoting/protocol/connection_to_client.h" #include "remoting/protocol/host_event_stub.h" @@ -148,6 +149,10 @@ class ClientSession : public protocol::HostEventStub, // Filter used to disable inputs when we're not authenticated. protocol::InputFilter auth_input_filter_; + // Filter to used to stop clipboard items sent from the client being echoed + // back to it. + protocol::ClipboardEchoFilter clipboard_echo_filter_; + // Capturer, used to determine current screen size for ensuring injected // mouse events fall within the screen area. // TODO(lambroslambrou): Move floor-control logic, and clamping to screen diff --git a/remoting/protocol/client_stub.h b/remoting/protocol/client_stub.h index f4e4fef..119132b 100644 --- a/remoting/protocol/client_stub.h +++ b/remoting/protocol/client_stub.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. @@ -11,11 +11,12 @@ #define REMOTING_PROTOCOL_CLIENT_STUB_H_ #include "base/basictypes.h" +#include "remoting/protocol/clipboard_stub.h" namespace remoting { namespace protocol { -class ClientStub { +class ClientStub : public ClipboardStub { public: ClientStub() {} virtual ~ClientStub() {} diff --git a/remoting/protocol/clipboard_echo_filter.cc b/remoting/protocol/clipboard_echo_filter.cc new file mode 100644 index 0000000..d89c43c --- /dev/null +++ b/remoting/protocol/clipboard_echo_filter.cc @@ -0,0 +1,78 @@ +// 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/protocol/clipboard_echo_filter.h" + +#include "remoting/proto/event.pb.h" + +namespace remoting { +namespace protocol { + +ClipboardEchoFilter::ClipboardEchoFilter() + : host_stub_(NULL), + client_stub_(NULL), + client_filter_(this), + host_filter_(this) { +} + +ClipboardEchoFilter::~ClipboardEchoFilter() { +} + +void ClipboardEchoFilter::set_client_stub(ClipboardStub* client_stub) { + client_stub_ = client_stub; +} + +void ClipboardEchoFilter::set_host_stub(ClipboardStub* host_stub) { + host_stub_ = host_stub; +} + +ClipboardStub* ClipboardEchoFilter::client_filter() { + return &client_filter_; +} + +ClipboardStub* ClipboardEchoFilter::host_filter() { + return &host_filter_; +} + +void ClipboardEchoFilter::InjectClipboardEventToClient( + const ClipboardEvent& event) { + if (!client_stub_) { + return; + } + if (event.mime_type() == client_latest_mime_type_ && + event.data() == client_latest_data_) { + return; + } + client_stub_->InjectClipboardEvent(event); +} + +void ClipboardEchoFilter::InjectClipboardEventToHost( + const ClipboardEvent& event) { + client_latest_mime_type_ = event.mime_type(); + client_latest_data_ = event.data(); + if (host_stub_) { + host_stub_->InjectClipboardEvent(event); + } +} + +ClipboardEchoFilter::ClientFilter::ClientFilter( + ClipboardEchoFilter* filter) : filter_(filter) { +} + +void ClipboardEchoFilter::ClientFilter::InjectClipboardEvent( + const ClipboardEvent& event) { + filter_->InjectClipboardEventToClient(event); +} + +ClipboardEchoFilter::HostFilter::HostFilter( + ClipboardEchoFilter* filter) : filter_(filter) { +} + +void ClipboardEchoFilter::HostFilter::InjectClipboardEvent( + const ClipboardEvent& event) { + filter_->InjectClipboardEventToHost(event); +} + +} // namespace protocol +} // namespace remoting diff --git a/remoting/protocol/clipboard_echo_filter.h b/remoting/protocol/clipboard_echo_filter.h new file mode 100644 index 0000000..6348685 --- /dev/null +++ b/remoting/protocol/clipboard_echo_filter.h @@ -0,0 +1,75 @@ +// 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. + +#ifndef REMOTING_PROTOCOL_CLIPBOARD_ECHO_FILTER_H_ +#define REMOTING_PROTOCOL_CLIPBOARD_ECHO_FILTER_H_ + +#include <map> +#include <string> + +#include "base/compiler_specific.h" +#include "remoting/protocol/clipboard_stub.h" + +namespace remoting { +namespace protocol { + +// ClipboardEchoFilter stops the host sending a clipboard item to the +// client, if that item was the latest item received from the client. +class ClipboardEchoFilter { + public: + ClipboardEchoFilter(); + ~ClipboardEchoFilter(); + + // Sets the ClipboardStub that sends events to the client. + void set_client_stub(ClipboardStub* client_stub); + + // Sets the ClipboardStub that sends events to the host. + void set_host_stub(ClipboardStub* host_stub); + + // Gets the ClipboardStub that sends events through this filter and on to the + // client. + ClipboardStub* client_filter(); + + // Gets the ClipboardStub that sends events through this filter and on to the + // host. + ClipboardStub* host_filter(); + + private: + class ClientFilter : public ClipboardStub { + public: + ClientFilter(ClipboardEchoFilter* filter); + virtual void InjectClipboardEvent(const ClipboardEvent& event) OVERRIDE; + + private: + ClipboardEchoFilter* filter_; + }; + + class HostFilter : public ClipboardStub { + public: + HostFilter(ClipboardEchoFilter* filter); + virtual void InjectClipboardEvent(const ClipboardEvent& event) OVERRIDE; + + private: + ClipboardEchoFilter* filter_; + }; + + void InjectClipboardEventToHost(const ClipboardEvent& event); + void InjectClipboardEventToClient(const ClipboardEvent& event); + + ClipboardStub* host_stub_; + ClipboardStub* client_stub_; + ClientFilter client_filter_; + HostFilter host_filter_; + + // The latest item received from the client. + std::string client_latest_mime_type_; + std::string client_latest_data_; + + DISALLOW_COPY_AND_ASSIGN(ClipboardEchoFilter); +}; + +} // namespace protocol +} // namespace remoting + +#endif // REMOTING_PROTOCOL_CLIPBOARD_ECHO_FILTER_H_ diff --git a/remoting/protocol/clipboard_echo_filter_unittest.cc b/remoting/protocol/clipboard_echo_filter_unittest.cc new file mode 100644 index 0000000..25f5de1 --- /dev/null +++ b/remoting/protocol/clipboard_echo_filter_unittest.cc @@ -0,0 +1,111 @@ +// 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/protocol/clipboard_echo_filter.h" + +#include "remoting/proto/event.pb.h" +#include "remoting/protocol/protocol_mock_objects.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::_; +using ::testing::InSequence; + +namespace remoting { +namespace protocol { + +MATCHER_P2(EqualsClipboardEvent, mime_type, data, "") { + return arg.mime_type() == mime_type && arg.data() == data; +} + +static ClipboardEvent MakeClipboardEvent(const std::string& mime_type, + const std::string& data) { + ClipboardEvent event; + event.set_mime_type(mime_type); + event.set_data(data); + return event; +} + +// Check that the filter only filters out events identical to the latest +// clipboard item from the client. +TEST(ClipboardEchoFilterTest, FromClientBlocksIdenticalEventToClient) { + MockClipboardStub client_stub; + MockClipboardStub host_stub; + + { + InSequence s; + EXPECT_CALL(host_stub, + InjectClipboardEvent(EqualsClipboardEvent("text", "a"))); + EXPECT_CALL(host_stub, + InjectClipboardEvent(EqualsClipboardEvent("text", "b"))); + EXPECT_CALL(client_stub, + InjectClipboardEvent(EqualsClipboardEvent("text", "a"))); + EXPECT_CALL(host_stub, + InjectClipboardEvent(EqualsClipboardEvent("image", "a"))); + EXPECT_CALL(client_stub, + InjectClipboardEvent(EqualsClipboardEvent("text", "a"))); + } + + ClipboardEchoFilter filter; + filter.set_client_stub(&client_stub); + filter.set_host_stub(&host_stub); + + filter.host_filter()->InjectClipboardEvent( + MakeClipboardEvent("text", "a")); + // The client has sent ("text", "a") to the host, so make sure the filter + // will stop the host echoing that item back to the client. + filter.client_filter()->InjectClipboardEvent( + MakeClipboardEvent("text", "a")); + filter.host_filter()->InjectClipboardEvent( + MakeClipboardEvent("text", "b")); + filter.client_filter()->InjectClipboardEvent( + MakeClipboardEvent("text", "a")); + filter.host_filter()->InjectClipboardEvent( + MakeClipboardEvent("image", "a")); + filter.client_filter()->InjectClipboardEvent( + MakeClipboardEvent("text", "a")); +} + +// Check that the filter will drop events sent to the host, if there is no host +// stub, whether or not there is a client stub. +TEST(ClipboardEchoFilterTest, NoHostStub) { + MockClipboardStub client_stub; + MockClipboardStub host_stub; + + EXPECT_CALL(host_stub, + InjectClipboardEvent(EqualsClipboardEvent("text", "a"))); + + ClipboardEchoFilter filter; + ClipboardEvent event = MakeClipboardEvent("text", "a"); + filter.host_filter()->InjectClipboardEvent(event); + + filter.set_client_stub(&client_stub); + filter.host_filter()->InjectClipboardEvent(event); + + filter.set_host_stub(&host_stub); + filter.host_filter()->InjectClipboardEvent(event); +} + +// Check that the filter will drop events sent to the client, if there is no +// client stub, whether or not there is a host stub. +TEST(ClipboardEchoFilter, NoClientStub) { + MockClipboardStub client_stub; + MockClipboardStub host_stub; + + EXPECT_CALL(client_stub, + InjectClipboardEvent(EqualsClipboardEvent("text", "a"))); + + ClipboardEchoFilter filter; + ClipboardEvent event = MakeClipboardEvent("text", "a"); + filter.client_filter()->InjectClipboardEvent(event); + + filter.set_host_stub(&host_stub); + filter.client_filter()->InjectClipboardEvent(event); + + filter.set_client_stub(&client_stub); + filter.client_filter()->InjectClipboardEvent(event); +} + +} // namespace protocol +} // namespace remoting diff --git a/remoting/protocol/host_control_dispatcher.h b/remoting/protocol/host_control_dispatcher.h index 0e36ce4..8f0473b 100644 --- a/remoting/protocol/host_control_dispatcher.h +++ b/remoting/protocol/host_control_dispatcher.h @@ -24,10 +24,9 @@ class HostStub; class Session; // HostControlDispatcher dispatches incoming messages on the control -// channel to HostStub or ClipboardStub, and also implements ClientStub and -// ClipboardStub for outgoing messages. -class HostControlDispatcher : public ChannelDispatcherBase, public ClientStub, - public ClipboardStub { +// channel to HostStub or ClipboardStub, and also implements ClientStub for +// outgoing messages. +class HostControlDispatcher : public ChannelDispatcherBase, public ClientStub { public: HostControlDispatcher(); virtual ~HostControlDispatcher(); diff --git a/remoting/protocol/protocol_mock_objects.h b/remoting/protocol/protocol_mock_objects.h index 592f199..a333e61 100644 --- a/remoting/protocol/protocol_mock_objects.h +++ b/remoting/protocol/protocol_mock_objects.h @@ -117,6 +117,8 @@ class MockClientStub : public ClientStub { MockClientStub(); virtual ~MockClientStub(); + MOCK_METHOD1(InjectClipboardEvent, void(const ClipboardEvent& event)); + private: DISALLOW_COPY_AND_ASSIGN(MockClientStub); }; diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index 1c45ad0..a7cdcc1 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -1530,6 +1530,8 @@ 'protocol/client_event_dispatcher.cc', 'protocol/client_event_dispatcher.h', 'protocol/client_stub.h', + 'protocol/clipboard_echo_filter.cc', + 'protocol/clipboard_echo_filter.h', 'protocol/clipboard_filter.h', 'protocol/clipboard_filter.cc', 'protocol/clipboard_stub.h', @@ -1722,6 +1724,7 @@ 'jingle_glue/mock_objects.h', 'protocol/authenticator_test_base.cc', 'protocol/authenticator_test_base.h', + 'protocol/clipboard_echo_filter_unittest.cc', 'protocol/connection_tester.cc', 'protocol/connection_tester.h', 'protocol/connection_to_client_unittest.cc', |