1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "remoting/protocol/mouse_input_filter.h"
6
7#include "remoting/proto/event.pb.h"
8#include "remoting/protocol/protocol_mock_objects.h"
9#include "testing/gmock/include/gmock/gmock.h"
10#include "testing/gtest/include/gtest/gtest.h"
11#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
12
13using ::testing::_;
14using ::testing::InSequence;
15
16namespace remoting {
17namespace protocol {
18
19MATCHER_P2(EqualsMouseMoveEvent, x, y, "") {
20  return arg.x() == x && arg.y() == y;
21}
22
23static MouseEvent MouseMoveEvent(int x, int y) {
24  MouseEvent event;
25  event.set_x(x);
26  event.set_y(y);
27  return event;
28}
29
30static void InjectTestSequence(InputStub* input_stub) {
31  struct Point {
32    int x;
33    int y;
34  };
35  static const Point input_sequence[] = {
36    {-5, 10}, {0, 10}, {-1, 10}, {15, 40}, {15, 45}, {15, 39}, {15, 25}
37  };
38  // arraysize() cannot be used here, becase Point is declared inside of a
39  // function.
40  for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(input_sequence); ++i) {
41    const Point& point = input_sequence[i];
42    input_stub->InjectMouseEvent(MouseMoveEvent(point.x, point.y));
43  }
44  for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(input_sequence); ++i) {
45    const Point& point = input_sequence[i];
46    input_stub->InjectMouseEvent(MouseMoveEvent(point.y, point.x));
47  }
48}
49
50// Verify that no events get through if we don't set either dimensions.
51TEST(MouseInputFilterTest, BothDimensionsZero) {
52  MockInputStub mock_stub;
53  MouseInputFilter mouse_filter(&mock_stub);
54
55  EXPECT_CALL(mock_stub, InjectMouseEvent(_))
56        .Times(0);
57
58  InjectTestSequence(&mouse_filter);
59}
60
61// Verify that no events get through if there's no input size.
62TEST(MouseInputFilterTest, InputDimensionsZero) {
63  MockInputStub mock_stub;
64  MouseInputFilter mouse_filter(&mock_stub);
65  mouse_filter.set_output_size(webrtc::DesktopSize(50, 50));
66
67  EXPECT_CALL(mock_stub, InjectMouseEvent(_))
68      .Times(0);
69
70  InjectTestSequence(&mouse_filter);
71}
72
73// Verify that no events get through if there's no output size.
74TEST(MouseInputFilterTest, OutputDimensionsZero) {
75  MockInputStub mock_stub;
76  MouseInputFilter mouse_filter(&mock_stub);
77  mouse_filter.set_input_size(webrtc::DesktopSize(50, 50));
78
79  EXPECT_CALL(mock_stub, InjectMouseEvent(_))
80      .Times(0);
81
82  InjectTestSequence(&mouse_filter);
83}
84
85// Verify that all events get through, clamped to the output.
86TEST(MouseInputFilterTest, NoScalingOrClipping) {
87  MockInputStub mock_stub;
88  MouseInputFilter mouse_filter(&mock_stub);
89  mouse_filter.set_output_size(webrtc::DesktopSize(40,40));
90  mouse_filter.set_input_size(webrtc::DesktopSize(40,40));
91
92  {
93    InSequence s;
94
95    EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(0, 10))).
96        Times(3);
97    EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(15, 39))).
98        Times(3);
99    EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(15, 25))).
100        Times(1);
101
102    EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(10, 0))).
103        Times(3);
104    EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(39, 15))).
105        Times(3);
106    EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(25, 15))).
107        Times(1);
108  }
109
110  InjectTestSequence(&mouse_filter);
111}
112
113// Verify that we can up-scale with clamping.
114TEST(MouseInputFilterTest, UpScalingAndClamping) {
115  MockInputStub mock_stub;
116  MouseInputFilter mouse_filter(&mock_stub);
117  mouse_filter.set_output_size(webrtc::DesktopSize(80, 80));
118  mouse_filter.set_input_size(webrtc::DesktopSize(40, 40));
119
120  {
121    InSequence s;
122
123    EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(0, 20))).
124        Times(3);
125    EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(30, 79))).
126        Times(3);
127    EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(30, 51))).
128        Times(1);
129
130    EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(20, 0))).
131        Times(3);
132    EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(79, 30))).
133        Times(3);
134    EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(51, 30))).
135        Times(1);
136  }
137
138  InjectTestSequence(&mouse_filter);
139}
140
141// Verify that we can down-scale with clamping.
142TEST(MouseInputFilterTest, DownScalingAndClamping) {
143  MockInputStub mock_stub;
144  MouseInputFilter mouse_filter(&mock_stub);
145  mouse_filter.set_output_size(webrtc::DesktopSize(30, 30));
146  mouse_filter.set_input_size(webrtc::DesktopSize(40, 40));
147
148  {
149    InSequence s;
150
151    EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(0, 7))).
152        Times(3);
153    EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(11, 29))).
154        Times(3);
155    EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(11, 19))).
156        Times(1);
157
158    EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(7, 0))).
159        Times(3);
160    EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(29, 11))).
161        Times(3);
162    EXPECT_CALL(mock_stub, InjectMouseEvent(EqualsMouseMoveEvent(19, 11))).
163        Times(1);
164
165  }
166
167  InjectTestSequence(&mouse_filter);
168}
169
170}  // namespace protocol
171}  // namespace remoting
172