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.
5 #include "remoting/protocol/input_event_tracker.h"
7 #include "remoting/proto/event.pb.h"
8 #include "remoting/protocol/protocol_mock_objects.h"
9 #include "remoting/protocol/test_event_matchers.h"
10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
14 using ::testing::ExpectationSet
;
15 using ::testing::InSequence
;
20 using test::EqualsKeyEventWithCapsLock
;
21 using test::EqualsMouseEvent
;
22 using test::EqualsKeyEventWithoutLockStates
;
26 static const MouseEvent::MouseButton BUTTON_LEFT
= MouseEvent::BUTTON_LEFT
;
27 static const MouseEvent::MouseButton BUTTON_RIGHT
= MouseEvent::BUTTON_RIGHT
;
29 MATCHER_P2(TouchPointIdsAndTypeEqual
, ids
, type
, "") {
30 if (arg
.event_type() != type
)
33 std::set
<uint32
> touch_ids
;
34 for (const TouchEventPoint
& point
: arg
.touch_points()) {
35 touch_ids
.insert(point
.id());
37 return touch_ids
== ids
;
40 static KeyEvent
NewUsbEvent(uint32 usb_keycode
, bool pressed
) {
42 event
.set_usb_keycode(usb_keycode
);
43 event
.set_pressed(pressed
);
44 // Create all key events with the hardcoded |lock_state| in this test.
45 event
.set_lock_states(KeyEvent::LOCK_STATES_CAPSLOCK
);
49 static void PressAndReleaseUsb(InputStub
* input_stub
, uint32 usb_keycode
) {
50 input_stub
->InjectKeyEvent(NewUsbEvent(usb_keycode
, true));
51 input_stub
->InjectKeyEvent(NewUsbEvent(usb_keycode
, false));
54 static MouseEvent
NewMouseEvent(int x
,
56 MouseEvent::MouseButton button
,
61 event
.set_button(button
);
62 event
.set_button_down(down
);
66 void AddTouchPoint(uint32 id
, TouchEvent
* event
) {
67 TouchEventPoint
* p
= event
->add_touch_points();
73 // Verify that keys that were pressed and released aren't re-released.
74 TEST(InputEventTrackerTest
, NothingToRelease
) {
75 MockInputStub mock_stub
;
76 InputEventTracker
input_tracker(&mock_stub
);
81 EXPECT_CALL(mock_stub
, InjectKeyEvent(EqualsKeyEventWithCapsLock(1, true)));
82 EXPECT_CALL(mock_stub
,
83 InjectKeyEvent(EqualsKeyEventWithCapsLock(1, false)));
84 EXPECT_CALL(mock_stub
, InjectKeyEvent(EqualsKeyEventWithCapsLock(2, true)));
85 EXPECT_CALL(mock_stub
,
86 InjectKeyEvent(EqualsKeyEventWithCapsLock(2, false)));
88 EXPECT_CALL(mock_stub
,
89 InjectMouseEvent(EqualsMouseEvent(0, 0, BUTTON_LEFT
, true)));
90 EXPECT_CALL(mock_stub
,
91 InjectMouseEvent(EqualsMouseEvent(0, 0, BUTTON_LEFT
, false)));
94 PressAndReleaseUsb(&input_tracker
, 1);
95 PressAndReleaseUsb(&input_tracker
, 2);
97 input_tracker
.InjectMouseEvent(NewMouseEvent(0, 0, BUTTON_LEFT
, true));
98 input_tracker
.InjectMouseEvent(NewMouseEvent(0, 0, BUTTON_LEFT
, false));
100 input_tracker
.ReleaseAll();
103 // Verify that keys that were left pressed get released.
104 TEST(InputEventTrackerTest
, ReleaseAllKeys
) {
105 MockInputStub mock_stub
;
106 InputEventTracker
input_tracker(&mock_stub
);
107 ExpectationSet injects
;
112 injects
+= EXPECT_CALL(mock_stub
,
113 InjectKeyEvent(EqualsKeyEventWithCapsLock(3, true)));
114 injects
+= EXPECT_CALL(mock_stub
,
115 InjectKeyEvent(EqualsKeyEventWithCapsLock(1, true)));
116 injects
+= EXPECT_CALL(
117 mock_stub
, InjectKeyEvent(EqualsKeyEventWithCapsLock(1, false)));
118 injects
+= EXPECT_CALL(mock_stub
,
119 InjectKeyEvent(EqualsKeyEventWithCapsLock(2, true)));
120 injects
+= EXPECT_CALL(
121 mock_stub
, InjectKeyEvent(EqualsKeyEventWithCapsLock(2, false)));
123 injects
+= EXPECT_CALL(mock_stub
, InjectMouseEvent(EqualsMouseEvent(
124 0, 0, BUTTON_RIGHT
, true)));
125 injects
+= EXPECT_CALL(
126 mock_stub
, InjectMouseEvent(EqualsMouseEvent(0, 0, BUTTON_LEFT
, true)));
127 injects
+= EXPECT_CALL(mock_stub
, InjectMouseEvent(EqualsMouseEvent(
128 1, 1, BUTTON_LEFT
, false)));
131 // The key should be released but |lock_states| should not be set.
132 EXPECT_CALL(mock_stub
, InjectKeyEvent(EqualsKeyEventWithoutLockStates(
133 3, false))).After(injects
);
134 EXPECT_CALL(mock_stub
, InjectMouseEvent(EqualsMouseEvent(
135 1, 1, BUTTON_RIGHT
, false))).After(injects
);
137 input_tracker
.InjectKeyEvent(NewUsbEvent(3, true));
138 PressAndReleaseUsb(&input_tracker
, 1);
139 PressAndReleaseUsb(&input_tracker
, 2);
141 input_tracker
.InjectMouseEvent(NewMouseEvent(0, 0, BUTTON_RIGHT
, true));
142 input_tracker
.InjectMouseEvent(NewMouseEvent(0, 0, BUTTON_LEFT
, true));
143 input_tracker
.InjectMouseEvent(NewMouseEvent(1, 1, BUTTON_LEFT
, false));
145 EXPECT_FALSE(input_tracker
.IsKeyPressed(1));
146 EXPECT_FALSE(input_tracker
.IsKeyPressed(2));
147 EXPECT_TRUE(input_tracker
.IsKeyPressed(3));
148 EXPECT_EQ(1, input_tracker
.PressedKeyCount());
150 input_tracker
.ReleaseAll();
153 // Verify that we track both USB-based key events correctly.
154 TEST(InputEventTrackerTest
, TrackUsbKeyEvents
) {
155 MockInputStub mock_stub
;
156 InputEventTracker
input_tracker(&mock_stub
);
157 ExpectationSet injects
;
162 injects
+= EXPECT_CALL(mock_stub
,
163 InjectKeyEvent(EqualsKeyEventWithCapsLock(3, true)));
164 injects
+= EXPECT_CALL(mock_stub
,
165 InjectKeyEvent(EqualsKeyEventWithCapsLock(6, true)));
166 injects
+= EXPECT_CALL(mock_stub
,
167 InjectKeyEvent(EqualsKeyEventWithCapsLock(7, true)));
168 injects
+= EXPECT_CALL(mock_stub
,
169 InjectKeyEvent(EqualsKeyEventWithCapsLock(5, true)));
170 injects
+= EXPECT_CALL(mock_stub
,
171 InjectKeyEvent(EqualsKeyEventWithCapsLock(5, true)));
172 injects
+= EXPECT_CALL(mock_stub
,
173 InjectKeyEvent(EqualsKeyEventWithCapsLock(2, true)));
174 injects
+= EXPECT_CALL(
175 mock_stub
, InjectKeyEvent(EqualsKeyEventWithCapsLock(2, false)));
178 // The key should be auto released with no |lock_states|.
179 EXPECT_CALL(mock_stub
,
180 InjectKeyEvent(EqualsKeyEventWithoutLockStates(3, false)))
182 EXPECT_CALL(mock_stub
,
183 InjectKeyEvent(EqualsKeyEventWithoutLockStates(6, false)))
185 EXPECT_CALL(mock_stub
,
186 InjectKeyEvent(EqualsKeyEventWithoutLockStates(7, false)))
188 EXPECT_CALL(mock_stub
,
189 InjectKeyEvent(EqualsKeyEventWithoutLockStates(5, false)))
192 input_tracker
.InjectKeyEvent(NewUsbEvent(3, true));
193 input_tracker
.InjectKeyEvent(NewUsbEvent(6, true));
194 input_tracker
.InjectKeyEvent(NewUsbEvent(7, true));
195 input_tracker
.InjectKeyEvent(NewUsbEvent(5, true));
196 input_tracker
.InjectKeyEvent(NewUsbEvent(5, true));
197 PressAndReleaseUsb(&input_tracker
, 2);
199 EXPECT_FALSE(input_tracker
.IsKeyPressed(1));
200 EXPECT_FALSE(input_tracker
.IsKeyPressed(2));
201 EXPECT_TRUE(input_tracker
.IsKeyPressed(3));
202 EXPECT_TRUE(input_tracker
.IsKeyPressed(5));
203 EXPECT_TRUE(input_tracker
.IsKeyPressed(6));
204 EXPECT_TRUE(input_tracker
.IsKeyPressed(7));
205 EXPECT_EQ(4, input_tracker
.PressedKeyCount());
207 input_tracker
.ReleaseAll();
210 // Verify that invalid events get passed through but not tracked.
211 TEST(InputEventTrackerTest
, InvalidEventsNotTracked
) {
212 MockInputStub mock_stub
;
213 InputEventTracker
input_tracker(&mock_stub
);
214 ExpectationSet injects
;
219 injects
+= EXPECT_CALL(mock_stub
,
220 InjectKeyEvent(EqualsKeyEventWithCapsLock(3, true)));
221 injects
+= EXPECT_CALL(mock_stub
,
222 InjectKeyEvent(EqualsKeyEventWithCapsLock(1, true)));
223 injects
+= EXPECT_CALL(
224 mock_stub
, InjectKeyEvent(EqualsKeyEventWithCapsLock(1, false)));
225 injects
+= EXPECT_CALL(mock_stub
, InjectKeyEvent(_
)).Times(2);
226 injects
+= EXPECT_CALL(mock_stub
,
227 InjectKeyEvent(EqualsKeyEventWithCapsLock(2, true)));
228 injects
+= EXPECT_CALL(
229 mock_stub
, InjectKeyEvent(EqualsKeyEventWithCapsLock(2, false)));
232 EXPECT_CALL(mock_stub
,
233 InjectKeyEvent(EqualsKeyEventWithoutLockStates(3, false)))
236 input_tracker
.InjectKeyEvent(NewUsbEvent(3, true));
237 PressAndReleaseUsb(&input_tracker
, 1);
239 KeyEvent invalid_event1
;
240 invalid_event1
.set_pressed(true);
241 input_tracker
.InjectKeyEvent(invalid_event1
);
243 KeyEvent invalid_event2
;
244 invalid_event2
.set_usb_keycode(6);
245 input_tracker
.InjectKeyEvent(invalid_event2
);
247 PressAndReleaseUsb(&input_tracker
, 2);
249 EXPECT_FALSE(input_tracker
.IsKeyPressed(1));
250 EXPECT_FALSE(input_tracker
.IsKeyPressed(2));
251 EXPECT_TRUE(input_tracker
.IsKeyPressed(3));
252 EXPECT_EQ(1, input_tracker
.PressedKeyCount());
254 input_tracker
.ReleaseAll();
257 // All touch points added with multiple touch events should be released as a
259 TEST(InputEventTrackerTest
, ReleaseAllTouchPoints
) {
260 MockInputStub mock_stub
;
261 InputEventTracker
input_tracker(&mock_stub
);
263 std::set
<uint32
> expected_ids1
;
264 expected_ids1
.insert(1);
265 expected_ids1
.insert(2);
266 std::set
<uint32
> expected_ids2
;
267 expected_ids2
.insert(3);
268 expected_ids2
.insert(5);
269 expected_ids2
.insert(8);
271 std::set
<uint32
> all_touch_point_ids
;
272 all_touch_point_ids
.insert(expected_ids1
.begin(), expected_ids1
.end());
273 all_touch_point_ids
.insert(expected_ids2
.begin(), expected_ids2
.end());
276 EXPECT_CALL(mock_stub
, InjectTouchEvent(TouchPointIdsAndTypeEqual(
277 expected_ids1
, TouchEvent::TOUCH_POINT_START
)));
278 EXPECT_CALL(mock_stub
, InjectTouchEvent(TouchPointIdsAndTypeEqual(
279 expected_ids2
, TouchEvent::TOUCH_POINT_START
)));
281 EXPECT_CALL(mock_stub
,
282 InjectTouchEvent(TouchPointIdsAndTypeEqual(
283 all_touch_point_ids
, TouchEvent::TOUCH_POINT_CANCEL
)));
285 TouchEvent start_event1
;
286 start_event1
.set_event_type(TouchEvent::TOUCH_POINT_START
);
287 AddTouchPoint(1, &start_event1
);
288 AddTouchPoint(2, &start_event1
);
289 input_tracker
.InjectTouchEvent(start_event1
);
291 TouchEvent start_event2
;
292 start_event2
.set_event_type(TouchEvent::TOUCH_POINT_START
);
293 AddTouchPoint(3, &start_event2
);
294 AddTouchPoint(5, &start_event2
);
295 AddTouchPoint(8, &start_event2
);
296 input_tracker
.InjectTouchEvent(start_event2
);
298 input_tracker
.ReleaseAll();
301 // Add some touch points and remove only a subset of them. ReleaseAll() should
302 // cancel all the remaining touch points.
303 TEST(InputEventTrackerTest
, ReleaseAllRemainingTouchPoints
) {
304 MockInputStub mock_stub
;
305 InputEventTracker
input_tracker(&mock_stub
);
307 std::set
<uint32
> start_expected_ids
;
308 start_expected_ids
.insert(1);
309 start_expected_ids
.insert(2);
310 start_expected_ids
.insert(3);
312 std::set
<uint32
> end_expected_ids
;
313 end_expected_ids
.insert(1);
314 std::set
<uint32
> cancel_expected_ids
;
315 cancel_expected_ids
.insert(3);
317 std::set
<uint32
> all_remaining_touch_point_ids
;
318 all_remaining_touch_point_ids
.insert(2);
321 EXPECT_CALL(mock_stub
,
322 InjectTouchEvent(TouchPointIdsAndTypeEqual(
323 start_expected_ids
, TouchEvent::TOUCH_POINT_START
)));
324 EXPECT_CALL(mock_stub
, InjectTouchEvent(TouchPointIdsAndTypeEqual(
325 end_expected_ids
, TouchEvent::TOUCH_POINT_END
)));
326 EXPECT_CALL(mock_stub
,
327 InjectTouchEvent(TouchPointIdsAndTypeEqual(
328 cancel_expected_ids
, TouchEvent::TOUCH_POINT_CANCEL
)));
330 EXPECT_CALL(mock_stub
, InjectTouchEvent(TouchPointIdsAndTypeEqual(
331 all_remaining_touch_point_ids
,
332 TouchEvent::TOUCH_POINT_CANCEL
)));
334 TouchEvent start_event
;
335 start_event
.set_event_type(TouchEvent::TOUCH_POINT_START
);
336 AddTouchPoint(1, &start_event
);
337 AddTouchPoint(2, &start_event
);
338 AddTouchPoint(3, &start_event
);
339 input_tracker
.InjectTouchEvent(start_event
);
341 TouchEvent end_event
;
342 end_event
.set_event_type(TouchEvent::TOUCH_POINT_END
);
343 AddTouchPoint(1, &end_event
);
344 input_tracker
.InjectTouchEvent(end_event
);
346 TouchEvent cancel_event
;
347 cancel_event
.set_event_type(TouchEvent::TOUCH_POINT_CANCEL
);
348 AddTouchPoint(3, &cancel_event
);
349 input_tracker
.InjectTouchEvent(cancel_event
);
351 input_tracker
.ReleaseAll();
354 } // namespace protocol
355 } // namespace remoting