1 // Copyright 2013 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/client/plugin/normalizing_input_filter_cros.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::InSequence;
13 using remoting::protocol::InputStub;
14 using remoting::protocol::KeyEvent;
15 using remoting::protocol::MockInputStub;
16 using remoting::protocol::MouseEvent;
22 const unsigned int kUsbLeftOsKey = 0x0700e3;
23 const unsigned int kUsbRightOsKey = 0x0700e7;
24 const unsigned int kUsbLeftAltKey = 0x0700e2;
25 const unsigned int kUsbRightAltKey = 0x0700e6;
27 const unsigned int kUsbFunctionKey = 0x07003a; // F1
28 const unsigned int kUsbExtendedKey = 0x070049; // Insert
29 const unsigned int kUsbOtherKey = 0x07002b; // Tab
31 // A hardcoded value used to verify |lock_states| is preserved.
32 static const uint32 kTestLockStates = protocol::KeyEvent::LOCK_STATES_NUMLOCK;
34 MATCHER_P2(EqualsKeyEvent, usb_keycode, pressed, "") {
35 return arg.usb_keycode() == static_cast<uint32>(usb_keycode) &&
36 arg.pressed() == pressed &&
37 arg.lock_states() == kTestLockStates;
40 KeyEvent MakeKeyEvent(uint32 keycode, bool pressed) {
42 event.set_usb_keycode(keycode);
43 event.set_pressed(pressed);
44 event.set_lock_states(kTestLockStates);
48 void PressAndReleaseKey(InputStub* input_stub, uint32 keycode) {
49 input_stub->InjectKeyEvent(MakeKeyEvent(keycode, true));
50 input_stub->InjectKeyEvent(MakeKeyEvent(keycode, false));
53 MATCHER_P2(EqualsMouseMoveEvent, x, y, "") {
54 return arg.x() == x && arg.y() == y;
57 MATCHER_P2(EqualsMouseButtonEvent, button, button_down, "") {
58 return arg.button() == button && arg.button_down() == button_down;
61 static MouseEvent MakeMouseMoveEvent(int x, int y) {
68 static MouseEvent MakeMouseButtonEvent(MouseEvent::MouseButton button,
71 event.set_button(button);
72 event.set_button_down(button_down);
78 // Test OSKey press/release.
79 TEST(NormalizingInputFilterCrosTest, PressReleaseOsKey) {
81 scoped_ptr<protocol::InputFilter> processor(
82 new NormalizingInputFilterCros(&stub));
87 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftOsKey, true)));
88 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftOsKey, false)));
90 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbRightOsKey, true)));
91 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbRightOsKey, false)));
94 // Inject press & release events for left & right OSKeys.
95 PressAndReleaseKey(processor.get(), kUsbLeftOsKey);
96 PressAndReleaseKey(processor.get(), kUsbRightOsKey);
99 // Test OSKey key repeat switches it to "modifying" mode.
100 TEST(NormalizingInputFilterCrosTest, OSKeyRepeats) {
102 scoped_ptr<protocol::InputFilter> processor(
103 new NormalizingInputFilterCros(&stub));
108 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftOsKey, true)));
109 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftOsKey, true)));
110 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftOsKey, true)));
113 // Inject a press and repeats for the left OSKey, but don't release it, and
114 // verify that the repeats result in press events.
115 processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, true));
116 processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, true));
117 processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, true));
120 // Test OSKey press followed by function key press and release results in
121 // just the function key events.
122 TEST(NormalizingInputFilterCrosTest, FunctionKey) {
124 scoped_ptr<protocol::InputFilter> processor(
125 new NormalizingInputFilterCros(&stub));
130 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbFunctionKey, true)));
131 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbFunctionKey, false)));
134 // Hold the left OSKey while pressing & releasing the function key.
135 processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, true));
136 PressAndReleaseKey(processor.get(), kUsbFunctionKey);
137 processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, false));
140 // Test OSKey press followed by extended key press and release results in
141 // just the function key events.
142 TEST(NormalizingInputFilterCrosTest, ExtendedKey) {
144 scoped_ptr<protocol::InputFilter> processor(
145 new NormalizingInputFilterCros(&stub));
150 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbExtendedKey, true)));
151 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbExtendedKey, false)));
154 // Hold the left OSKey while pressing & releasing the function key.
155 processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, true));
156 PressAndReleaseKey(processor.get(), kUsbExtendedKey);
157 processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, false));
160 // Test OSKey press followed by non-function, non-extended key press and release
161 // results in normal-looking sequence.
162 TEST(NormalizingInputFilterCrosTest, OtherKey) {
164 scoped_ptr<protocol::InputFilter> processor(
165 new NormalizingInputFilterCros(&stub));
170 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftOsKey, true)));
171 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbOtherKey, true)));
172 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbOtherKey, false)));
173 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftOsKey, false)));
176 // Hold the left OSKey while pressing & releasing the function key.
177 processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, true));
178 PressAndReleaseKey(processor.get(), kUsbOtherKey);
179 processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, false));
182 // Test OSKey press followed by extended key press, then normal key press
183 // results in OSKey switching to modifying mode for the normal key.
184 TEST(NormalizingInputFilterCrosTest, ExtendedThenOtherKey) {
186 scoped_ptr<protocol::InputFilter> processor(
187 new NormalizingInputFilterCros(&stub));
192 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbExtendedKey, true)));
193 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbExtendedKey, false)));
194 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftOsKey, true)));
195 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbOtherKey, true)));
196 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbOtherKey, false)));
197 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftOsKey, false)));
200 // Hold the left OSKey while pressing & releasing the function key.
201 processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, true));
202 PressAndReleaseKey(processor.get(), kUsbExtendedKey);
203 PressAndReleaseKey(processor.get(), kUsbOtherKey);
204 processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, false));
207 // Test OSKey press followed by mouse event puts the OSKey into modifying mode.
208 TEST(NormalizingInputFilterCrosTest, MouseEvent) {
210 scoped_ptr<protocol::InputFilter> processor(
211 new NormalizingInputFilterCros(&stub));
216 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftOsKey, true)));
217 EXPECT_CALL(stub, InjectMouseEvent(EqualsMouseMoveEvent(0, 0)));
218 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftOsKey, false)));
221 // Hold the left OSKey while pressing & releasing the function key.
222 processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, true));
223 processor->InjectMouseEvent(MakeMouseMoveEvent(0, 0));
224 processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, false));
227 // Test left alt + right click is remapped to left alt + left click.
228 TEST(NormalizingInputFilterCrosTest, LeftAltClick) {
230 scoped_ptr<protocol::InputFilter> processor(
231 new NormalizingInputFilterCros(&stub));
236 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftAltKey, true)));
237 EXPECT_CALL(stub, InjectMouseEvent(
238 EqualsMouseButtonEvent(MouseEvent::BUTTON_LEFT, true)));
239 EXPECT_CALL(stub, InjectMouseEvent(
240 EqualsMouseButtonEvent(MouseEvent::BUTTON_LEFT, false)));
241 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftAltKey, false)));
244 // Hold the left alt key while left-clicking. ChromeOS will rewrite this as
246 processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftAltKey, true));
247 processor->InjectMouseEvent(
248 MakeMouseButtonEvent(MouseEvent::BUTTON_RIGHT, true));
249 processor->InjectMouseEvent(
250 MakeMouseButtonEvent(MouseEvent::BUTTON_RIGHT, false));
251 processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftAltKey, false));
254 // Test that right alt + right click is unchanged.
255 TEST(NormalizingInputFilterCrosTest, RightAltClick) {
257 scoped_ptr<protocol::InputFilter> processor(
258 new NormalizingInputFilterCros(&stub));
263 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbRightAltKey, true)));
264 EXPECT_CALL(stub, InjectMouseEvent(
265 EqualsMouseButtonEvent(MouseEvent::BUTTON_RIGHT, true)));
266 EXPECT_CALL(stub, InjectMouseEvent(
267 EqualsMouseButtonEvent(MouseEvent::BUTTON_RIGHT, false)));
268 EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbRightAltKey, false)));
271 // Hold the right alt key while left-clicking. ChromeOS will rewrite this as
273 processor->InjectKeyEvent(MakeKeyEvent(kUsbRightAltKey, true));
274 processor->InjectMouseEvent(
275 MakeMouseButtonEvent(MouseEvent::BUTTON_RIGHT, true));
276 processor->InjectMouseEvent(
277 MakeMouseButtonEvent(MouseEvent::BUTTON_RIGHT, false));
278 processor->InjectKeyEvent(MakeKeyEvent(kUsbRightAltKey, false));
281 } // namespace remoting