summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsimonmorris@chromium.org <simonmorris@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-22 22:29:24 +0000
committersimonmorris@chromium.org <simonmorris@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-22 22:29:24 +0000
commitff3761a1e35e0d5ef9e3c00beeadd3c565a4b84f (patch)
tree6ec789e2b8ba63d88d29af7e6741bf335784a73e
parentb44a986ebf6b56ad74a5efcbd2395851e815489c (diff)
downloadchromium_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.h1
-rw-r--r--remoting/host/client_session.cc5
-rw-r--r--remoting/host/client_session.h5
-rw-r--r--remoting/protocol/client_stub.h5
-rw-r--r--remoting/protocol/clipboard_echo_filter.cc78
-rw-r--r--remoting/protocol/clipboard_echo_filter.h75
-rw-r--r--remoting/protocol/clipboard_echo_filter_unittest.cc111
-rw-r--r--remoting/protocol/host_control_dispatcher.h7
-rw-r--r--remoting/protocol/protocol_mock_objects.h2
-rw-r--r--remoting/remoting.gyp3
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',