ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / remoting / protocol / input_event_tracker_unittest.cc
blobe8b5746552618ba81a594d10e9c33b645082cf46
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 "testing/gmock/include/gmock/gmock.h"
10 #include "testing/gtest/include/gtest/gtest.h"
12 using ::testing::_;
13 using ::testing::ExpectationSet;
14 using ::testing::InSequence;
16 namespace remoting {
17 namespace protocol {
19 namespace {
21 static const MouseEvent::MouseButton BUTTON_LEFT = MouseEvent::BUTTON_LEFT;
22 static const MouseEvent::MouseButton BUTTON_RIGHT = MouseEvent::BUTTON_RIGHT;
24 // A hardcoded value used to verify |lock_states| is preserved.
25 static const uint32 kTestLockStates = protocol::KeyEvent::LOCK_STATES_CAPSLOCK;
27 // Verify the usb key code and the "pressed" state.
28 // Also verify that the event doesn't have |lock_states| set.
29 MATCHER_P2(EqualsUsbEventWithoutLockStates, usb_keycode, pressed, "") {
30 return arg.usb_keycode() == static_cast<uint32>(usb_keycode) &&
31 arg.pressed() == pressed &&
32 !arg.has_lock_states();
35 // Verify the usb key code, the "pressed" state, and the lock states.
36 MATCHER_P2(EqualsUsbEvent, usb_keycode, pressed, "") {
37 return arg.usb_keycode() == static_cast<uint32>(usb_keycode) &&
38 arg.pressed() == pressed &&
39 arg.lock_states() == kTestLockStates;
42 MATCHER_P4(EqualsMouseEvent, x, y, button, down, "") {
43 return arg.x() == x && arg.y() == y && arg.button() == button &&
44 arg.button_down() == down;
47 MATCHER_P2(TouchPointIdsAndTypeEqual, ids, type, "") {
48 if (arg.event_type() != type)
49 return false;
51 std::set<uint32> touch_ids;
52 for (const TouchEventPoint& point : arg.touch_points()) {
53 touch_ids.insert(point.id());
55 return touch_ids == ids;
58 static KeyEvent NewUsbEvent(uint32 usb_keycode,
59 bool pressed) {
60 KeyEvent event;
61 event.set_usb_keycode(usb_keycode);
62 event.set_pressed(pressed);
63 // Create all key events with the hardcoded |lock_state| in this test.
64 event.set_lock_states(kTestLockStates);
65 return event;
68 static void PressAndReleaseUsb(InputStub* input_stub,
69 uint32 usb_keycode) {
70 input_stub->InjectKeyEvent(NewUsbEvent(usb_keycode, true));
71 input_stub->InjectKeyEvent(NewUsbEvent(usb_keycode, false));
74 static MouseEvent NewMouseEvent(int x, int y,
75 MouseEvent::MouseButton button, bool down) {
76 MouseEvent event;
77 event.set_x(x);
78 event.set_y(y);
79 event.set_button(button);
80 event.set_button_down(down);
81 return event;
84 void AddTouchPoint(uint32 id, TouchEvent* event) {
85 TouchEventPoint* p = event->add_touch_points();
86 p->set_id(id);
89 } // namespace
91 // Verify that keys that were pressed and released aren't re-released.
92 TEST(InputEventTrackerTest, NothingToRelease) {
93 MockInputStub mock_stub;
94 InputEventTracker input_tracker(&mock_stub);
97 InSequence s;
99 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(1, true)));
100 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(1, false)));
101 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, true)));
102 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, false)));
104 EXPECT_CALL(mock_stub,
105 InjectMouseEvent(EqualsMouseEvent(0, 0, BUTTON_LEFT, true)));
106 EXPECT_CALL(mock_stub,
107 InjectMouseEvent(EqualsMouseEvent(0, 0, BUTTON_LEFT, false)));
110 PressAndReleaseUsb(&input_tracker, 1);
111 PressAndReleaseUsb(&input_tracker, 2);
113 input_tracker.InjectMouseEvent(NewMouseEvent(0, 0, BUTTON_LEFT, true));
114 input_tracker.InjectMouseEvent(NewMouseEvent(0, 0, BUTTON_LEFT, false));
116 input_tracker.ReleaseAll();
119 // Verify that keys that were left pressed get released.
120 TEST(InputEventTrackerTest, ReleaseAllKeys) {
121 MockInputStub mock_stub;
122 InputEventTracker input_tracker(&mock_stub);
123 ExpectationSet injects;
126 InSequence s;
128 injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(3, true)));
129 injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(1, true)));
130 injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(1, false)));
131 injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, true)));
132 injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, false)));
134 injects += EXPECT_CALL(mock_stub,
135 InjectMouseEvent(EqualsMouseEvent(0, 0, BUTTON_RIGHT, true)));
136 injects += EXPECT_CALL(mock_stub,
137 InjectMouseEvent(EqualsMouseEvent(0, 0, BUTTON_LEFT, true)));
138 injects += EXPECT_CALL(mock_stub,
139 InjectMouseEvent(EqualsMouseEvent(1, 1, BUTTON_LEFT, false)));
142 // The key should be released but |lock_states| should not be set.
143 EXPECT_CALL(mock_stub,
144 InjectKeyEvent(EqualsUsbEventWithoutLockStates(3, false)))
145 .After(injects);
146 EXPECT_CALL(mock_stub,
147 InjectMouseEvent(EqualsMouseEvent(1, 1, BUTTON_RIGHT, false)))
148 .After(injects);
150 input_tracker.InjectKeyEvent(NewUsbEvent(3, true));
151 PressAndReleaseUsb(&input_tracker, 1);
152 PressAndReleaseUsb(&input_tracker, 2);
154 input_tracker.InjectMouseEvent(NewMouseEvent(0, 0, BUTTON_RIGHT, true));
155 input_tracker.InjectMouseEvent(NewMouseEvent(0, 0, BUTTON_LEFT, true));
156 input_tracker.InjectMouseEvent(NewMouseEvent(1, 1, BUTTON_LEFT, false));
158 EXPECT_FALSE(input_tracker.IsKeyPressed(1));
159 EXPECT_FALSE(input_tracker.IsKeyPressed(2));
160 EXPECT_TRUE(input_tracker.IsKeyPressed(3));
161 EXPECT_EQ(1, input_tracker.PressedKeyCount());
163 input_tracker.ReleaseAll();
166 // Verify that we track both USB-based key events correctly.
167 TEST(InputEventTrackerTest, TrackUsbKeyEvents) {
168 MockInputStub mock_stub;
169 InputEventTracker input_tracker(&mock_stub);
170 ExpectationSet injects;
173 InSequence s;
175 injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(3, true)));
176 injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(6, true)));
177 injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(7, true)));
178 injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(5, true)));
179 injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(5, true)));
180 injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, true)));
181 injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, false)));
184 // The key should be auto released with no |lock_states|.
185 EXPECT_CALL(mock_stub,
186 InjectKeyEvent(EqualsUsbEventWithoutLockStates(3, false)))
187 .After(injects);
188 EXPECT_CALL(mock_stub,
189 InjectKeyEvent(EqualsUsbEventWithoutLockStates(6, false)))
190 .After(injects);
191 EXPECT_CALL(mock_stub,
192 InjectKeyEvent(EqualsUsbEventWithoutLockStates(7, false)))
193 .After(injects);
194 EXPECT_CALL(mock_stub,
195 InjectKeyEvent(EqualsUsbEventWithoutLockStates(5, false)))
196 .After(injects);
198 input_tracker.InjectKeyEvent(NewUsbEvent(3, true));
199 input_tracker.InjectKeyEvent(NewUsbEvent(6, true));
200 input_tracker.InjectKeyEvent(NewUsbEvent(7, true));
201 input_tracker.InjectKeyEvent(NewUsbEvent(5, true));
202 input_tracker.InjectKeyEvent(NewUsbEvent(5, true));
203 PressAndReleaseUsb(&input_tracker, 2);
205 EXPECT_FALSE(input_tracker.IsKeyPressed(1));
206 EXPECT_FALSE(input_tracker.IsKeyPressed(2));
207 EXPECT_TRUE(input_tracker.IsKeyPressed(3));
208 EXPECT_TRUE(input_tracker.IsKeyPressed(5));
209 EXPECT_TRUE(input_tracker.IsKeyPressed(6));
210 EXPECT_TRUE(input_tracker.IsKeyPressed(7));
211 EXPECT_EQ(4, input_tracker.PressedKeyCount());
213 input_tracker.ReleaseAll();
216 // Verify that invalid events get passed through but not tracked.
217 TEST(InputEventTrackerTest, InvalidEventsNotTracked) {
218 MockInputStub mock_stub;
219 InputEventTracker input_tracker(&mock_stub);
220 ExpectationSet injects;
223 InSequence s;
225 injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(3, true)));
226 injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(1, true)));
227 injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(1, false)));
228 injects += EXPECT_CALL(mock_stub, InjectKeyEvent(_)).Times(2);
229 injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, true)));
230 injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, false)));
233 EXPECT_CALL(mock_stub,
234 InjectKeyEvent(EqualsUsbEventWithoutLockStates(3, false)))
235 .After(injects);
237 input_tracker.InjectKeyEvent(NewUsbEvent(3, true));
238 PressAndReleaseUsb(&input_tracker, 1);
240 KeyEvent invalid_event1;
241 invalid_event1.set_pressed(true);
242 input_tracker.InjectKeyEvent(invalid_event1);
244 KeyEvent invalid_event2;
245 invalid_event2.set_usb_keycode(6);
246 input_tracker.InjectKeyEvent(invalid_event2);
248 PressAndReleaseUsb(&input_tracker, 2);
250 EXPECT_FALSE(input_tracker.IsKeyPressed(1));
251 EXPECT_FALSE(input_tracker.IsKeyPressed(2));
252 EXPECT_TRUE(input_tracker.IsKeyPressed(3));
253 EXPECT_EQ(1, input_tracker.PressedKeyCount());
255 input_tracker.ReleaseAll();
258 // All touch points added with multiple touch events should be released as a
259 // cancel event.
260 TEST(InputEventTrackerTest, ReleaseAllTouchPoints) {
261 MockInputStub mock_stub;
262 InputEventTracker input_tracker(&mock_stub);
264 std::set<uint32> expected_ids1;
265 expected_ids1.insert(1);
266 expected_ids1.insert(2);
267 std::set<uint32> expected_ids2;
268 expected_ids2.insert(3);
269 expected_ids2.insert(5);
270 expected_ids2.insert(8);
272 std::set<uint32> all_touch_point_ids;
273 all_touch_point_ids.insert(expected_ids1.begin(), expected_ids1.end());
274 all_touch_point_ids.insert(expected_ids2.begin(), expected_ids2.end());
276 InSequence s;
277 EXPECT_CALL(mock_stub, InjectTouchEvent(TouchPointIdsAndTypeEqual(
278 expected_ids1, TouchEvent::TOUCH_POINT_START)));
279 EXPECT_CALL(mock_stub, InjectTouchEvent(TouchPointIdsAndTypeEqual(
280 expected_ids2, TouchEvent::TOUCH_POINT_START)));
282 EXPECT_CALL(mock_stub,
283 InjectTouchEvent(TouchPointIdsAndTypeEqual(
284 all_touch_point_ids, TouchEvent::TOUCH_POINT_CANCEL)));
286 TouchEvent start_event1;
287 start_event1.set_event_type(TouchEvent::TOUCH_POINT_START);
288 AddTouchPoint(1, &start_event1);
289 AddTouchPoint(2, &start_event1);
290 input_tracker.InjectTouchEvent(start_event1);
292 TouchEvent start_event2;
293 start_event2.set_event_type(TouchEvent::TOUCH_POINT_START);
294 AddTouchPoint(3, &start_event2);
295 AddTouchPoint(5, &start_event2);
296 AddTouchPoint(8, &start_event2);
297 input_tracker.InjectTouchEvent(start_event2);
299 input_tracker.ReleaseAll();
302 // Add some touch points and remove only a subset of them. ReleaseAll() should
303 // cancel all the remaining touch points.
304 TEST(InputEventTrackerTest, ReleaseAllRemainingTouchPoints) {
305 MockInputStub mock_stub;
306 InputEventTracker input_tracker(&mock_stub);
308 std::set<uint32> start_expected_ids;
309 start_expected_ids.insert(1);
310 start_expected_ids.insert(2);
311 start_expected_ids.insert(3);
313 std::set<uint32> end_expected_ids;
314 end_expected_ids.insert(1);
315 std::set<uint32> cancel_expected_ids;
316 cancel_expected_ids.insert(3);
318 std::set<uint32> all_remaining_touch_point_ids;
319 all_remaining_touch_point_ids.insert(2);
321 InSequence s;
322 EXPECT_CALL(mock_stub,
323 InjectTouchEvent(TouchPointIdsAndTypeEqual(
324 start_expected_ids, TouchEvent::TOUCH_POINT_START)));
325 EXPECT_CALL(mock_stub, InjectTouchEvent(TouchPointIdsAndTypeEqual(
326 end_expected_ids, TouchEvent::TOUCH_POINT_END)));
327 EXPECT_CALL(mock_stub,
328 InjectTouchEvent(TouchPointIdsAndTypeEqual(
329 cancel_expected_ids, TouchEvent::TOUCH_POINT_CANCEL)));
331 EXPECT_CALL(mock_stub, InjectTouchEvent(TouchPointIdsAndTypeEqual(
332 all_remaining_touch_point_ids,
333 TouchEvent::TOUCH_POINT_CANCEL)));
335 TouchEvent start_event;
336 start_event.set_event_type(TouchEvent::TOUCH_POINT_START);
337 AddTouchPoint(1, &start_event);
338 AddTouchPoint(2, &start_event);
339 AddTouchPoint(3, &start_event);
340 input_tracker.InjectTouchEvent(start_event);
342 TouchEvent end_event;
343 end_event.set_event_type(TouchEvent::TOUCH_POINT_END);
344 AddTouchPoint(1, &end_event);
345 input_tracker.InjectTouchEvent(end_event);
347 TouchEvent cancel_event;
348 cancel_event.set_event_type(TouchEvent::TOUCH_POINT_CANCEL);
349 AddTouchPoint(3, &cancel_event);
350 input_tracker.InjectTouchEvent(cancel_event);
352 input_tracker.ReleaseAll();
355 } // namespace protocol
356 } // namespace remoting