diff options
author | wez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-23 01:02:43 +0000 |
---|---|---|
committer | wez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-23 01:02:43 +0000 |
commit | 437377c9eb18494387be6563594b20d11800b6e2 (patch) | |
tree | e61af2e1397a1aef91daa5991003f0cbce6baf04 /remoting | |
parent | 59f9bdcae3a25c83f3e01a35a438843ac102e17a (diff) | |
download | chromium_src-437377c9eb18494387be6563594b20d11800b6e2.zip chromium_src-437377c9eb18494387be6563594b20d11800b6e2.tar.gz chromium_src-437377c9eb18494387be6563594b20d11800b6e2.tar.bz2 |
Add unit tests for MouseInputFilter and fix bugs in its coordinate scaling.
BUG=93552
Review URL: http://codereview.chromium.org/8962031
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@115651 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r-- | remoting/client/mouse_input_filter.cc | 24 | ||||
-rw-r--r-- | remoting/client/mouse_input_filter.h | 4 | ||||
-rw-r--r-- | remoting/client/mouse_input_filter_unittest.cc | 171 | ||||
-rw-r--r-- | remoting/remoting.gyp | 1 |
4 files changed, 189 insertions, 11 deletions
diff --git a/remoting/client/mouse_input_filter.cc b/remoting/client/mouse_input_filter.cc index 49e33a8..00d981d 100644 --- a/remoting/client/mouse_input_filter.cc +++ b/remoting/client/mouse_input_filter.cc @@ -10,8 +10,8 @@ namespace remoting { MouseInputFilter::MouseInputFilter(protocol::InputStub* input_stub) : input_stub_(input_stub) { - input_size_.setEmpty(); - output_size_.setEmpty(); + input_max_.setEmpty(); + output_max_.setEmpty(); } MouseInputFilter::~MouseInputFilter() { @@ -22,28 +22,34 @@ void MouseInputFilter::InjectKeyEvent(const protocol::KeyEvent& event) { } void MouseInputFilter::InjectMouseEvent(const protocol::MouseEvent& event) { - if (input_size_.isZero() || output_size_.isZero()) + if (input_max_.isEmpty() || output_max_.isEmpty()) return; + // We scale based on the maximum input & output coordinates, rather than the + // input and output sizes, so that it's possible to reach the edge of the + // output when up-scaling. We also take care to round up or down correctly, + // which is important when down-scaling. protocol::MouseEvent out_event(event); if (out_event.has_x()) { - int x = (out_event.x() * output_size_.width()) / input_size_.width(); - out_event.set_x(std::max(0, std::min(output_size_.width() - 1, x))); + int x = out_event.x() * output_max_.width(); + x = (x + input_max_.width() / 2) / input_max_.width(); + out_event.set_x(std::max(0, std::min(output_max_.width(), x))); } if (out_event.has_y()) { - int y = (out_event.y() * output_size_.height()) / input_size_.height(); - out_event.set_y(std::max(0, std::min(output_size_.height() - 1, y))); + int y = out_event.y() * output_max_.height(); + y = (y + input_max_.height() / 2) / input_max_.height(); + out_event.set_y(std::max(0, std::min(output_max_.height(), y))); } input_stub_->InjectMouseEvent(out_event); } void MouseInputFilter::set_input_size(const SkISize& size) { - input_size_ = size; + input_max_ = SkISize::Make(size.width() - 1, size.height() - 1); } void MouseInputFilter::set_output_size(const SkISize& size) { - output_size_ = size; + output_max_ = SkISize::Make(size.width() - 1, size.height() - 1); } } // namespace remoting diff --git a/remoting/client/mouse_input_filter.h b/remoting/client/mouse_input_filter.h index 0c2a0d9..4033621 100644 --- a/remoting/client/mouse_input_filter.h +++ b/remoting/client/mouse_input_filter.h @@ -34,8 +34,8 @@ class MouseInputFilter : public protocol::InputStub { private: protocol::InputStub* input_stub_; - SkISize input_size_; - SkISize output_size_; + SkISize input_max_; + SkISize output_max_; DISALLOW_COPY_AND_ASSIGN(MouseInputFilter); }; diff --git a/remoting/client/mouse_input_filter_unittest.cc b/remoting/client/mouse_input_filter_unittest.cc new file mode 100644 index 0000000..f48ee1f --- /dev/null +++ b/remoting/client/mouse_input_filter_unittest.cc @@ -0,0 +1,171 @@ +// Copyright (c) 2011 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/client/mouse_input_filter.h" +#include "remoting/proto/event.pb.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkPoint.h" + +using ::testing::_; +using ::testing::InSequence; + +namespace remoting { + +MATCHER_P2(EqualsMouseMoveEvent, x, y, "") { + return arg.x() == x && arg.y() == y; +} + +class MockInputStub : public protocol::InputStub { + public: + MockInputStub() {} + + MOCK_METHOD1(InjectKeyEvent, void(const protocol::KeyEvent&)); + MOCK_METHOD1(InjectMouseEvent, void(const protocol::MouseEvent&)); + private: + DISALLOW_COPY_AND_ASSIGN(MockInputStub); +}; + +static protocol::MouseEvent mouseMoveEvent(int x, int y) { + protocol::MouseEvent event; + event.set_x(x); + event.set_y(y); + return event; +} + +static void injectTestSequence(protocol::InputStub* input_stub) { + static const SkIPoint input_sequence[] = { + {-5, 10}, {0, 10}, {-1, 10}, {15, 40}, {15, 45}, {15, 39}, {15, 25} + }; + for (unsigned int i=0; i<arraysize(input_sequence); ++i) { + const SkIPoint& point = input_sequence[i]; + input_stub->InjectMouseEvent(mouseMoveEvent(point.x(), point.y())); + } + for (unsigned int i=0; i<arraysize(input_sequence); ++i) { + const SkIPoint& point = input_sequence[i]; + input_stub->InjectMouseEvent(mouseMoveEvent(point.y(), point.x())); + } +} + +// Verify that no events get through if we don't set either dimensions. +TEST(MouseInputFilterTest, BothDimensionsZero) { + MockInputStub mock_stub; + MouseInputFilter mouse_filter(&mock_stub); + + EXPECT_CALL(mock_stub, InjectMouseEvent(_)) + .Times(0); + + injectTestSequence(&mouse_filter); +} + +// Verify that no events get through if there's no input size. +TEST(MouseInputFilterTest, InputDimensionsZero) { + MockInputStub mock_stub; + MouseInputFilter mouse_filter(&mock_stub); + mouse_filter.set_output_size(SkISize::Make(50,50)); + + EXPECT_CALL(mock_stub, InjectMouseEvent(_)) + .Times(0); + + injectTestSequence(&mouse_filter); +} + +// Verify that no events get through if there's no output size. +TEST(MouseInputFilterTest, OutputDimensionsZero) { + MockInputStub mock_stub; + MouseInputFilter mouse_filter(&mock_stub); + mouse_filter.set_input_size(SkISize::Make(50,50)); + + EXPECT_CALL(mock_stub, InjectMouseEvent(_)) + .Times(0); + + injectTestSequence(&mouse_filter); +} + +// Verify that all events get through, clamped to the output. +TEST(MouseInputFilterTest, NoScalingOrClipping) { + MockInputStub mock_stub; + MouseInputFilter mouse_filter(&mock_stub); + mouse_filter.set_output_size(SkISize::Make(40,40)); + mouse_filter.set_input_size(SkISize::Make(40,40)); + + { + InSequence s; + + EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(0, 10))). + Times(3); + EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(15, 39))). + Times(3); + EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(15, 25))). + Times(1); + + EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(10, 0))). + Times(3); + EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(39, 15))). + Times(3); + EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(25, 15))). + Times(1); + } + + injectTestSequence(&mouse_filter); +} + +// Verify that we can up-scale with clamping. +TEST(MouseInputFilterTest, UpScalingAndClamping) { + MockInputStub mock_stub; + MouseInputFilter mouse_filter(&mock_stub); + mouse_filter.set_output_size(SkISize::Make(80,80)); + mouse_filter.set_input_size(SkISize::Make(40,40)); + + { + InSequence s; + + EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(0, 20))). + Times(3); + EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(30, 79))). + Times(3); + EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(30, 51))). + Times(1); + + EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(20, 0))). + Times(3); + EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(79, 30))). + Times(3); + EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(51, 30))). + Times(1); + } + + injectTestSequence(&mouse_filter); +} + +// Verify that we can down-scale with clamping. +TEST(MouseInputFilterTest, DownScalingAndClamping) { + MockInputStub mock_stub; + MouseInputFilter mouse_filter(&mock_stub); + mouse_filter.set_output_size(SkISize::Make(30,30)); + mouse_filter.set_input_size(SkISize::Make(40,40)); + + { + InSequence s; + + EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(0, 7))). + Times(3); + EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(11, 29))). + Times(3); + EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(11, 19))). + Times(1); + + EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(7, 0))). + Times(3); + EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(29, 11))). + Times(3); + EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(19, 11))). + Times(1); + + } + + injectTestSequence(&mouse_filter); +} + +} // namespace remoting diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index cfa73bc..eadc602 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -903,6 +903,7 @@ 'base/base_mock_objects.cc', 'base/base_mock_objects.h', # BUG57351 'client/chromoting_view_unittest.cc', + 'client/mouse_input_filter_unittest.cc', 'host/capturer_linux_unittest.cc', 'host/capturer_mac_unittest.cc', 'host/capturer_win_unittest.cc', |