Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / chromeos / events / event_rewriter_unittest.cc
blobbae1131a5190aa3f6d9ed00f7552d16d11f2f576
1 // Copyright 2014 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 "chrome/browser/chromeos/events/event_rewriter.h"
7 #include <vector>
9 #include "ash/shell.h"
10 #include "ash/sticky_keys/sticky_keys_controller.h"
11 #include "ash/sticky_keys/sticky_keys_overlay.h"
12 #include "ash/test/ash_test_base.h"
13 #include "ash/wm/window_state.h"
14 #include "base/basictypes.h"
15 #include "base/command_line.h"
16 #include "base/prefs/pref_member.h"
17 #include "base/strings/stringprintf.h"
18 #include "chrome/browser/chromeos/input_method/input_method_configuration.h"
19 #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h"
20 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
21 #include "chrome/browser/chromeos/preferences.h"
22 #include "chrome/common/pref_names.h"
23 #include "chrome/test/base/testing_pref_service_syncable.h"
24 #include "chromeos/chromeos_switches.h"
25 #include "components/user_manager/fake_user_manager.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "ui/aura/window.h"
28 #include "ui/aura/window_tree_host.h"
29 #include "ui/base/ime/chromeos/fake_ime_keyboard.h"
30 #include "ui/events/event.h"
31 #include "ui/events/event_rewriter.h"
32 #include "ui/events/event_utils.h"
33 #include "ui/events/test/events_test_utils.h"
34 #include "ui/events/test/test_event_processor.h"
36 #if defined(USE_X11)
37 #include <X11/keysym.h>
39 #include "ui/events/devices/x11/touch_factory_x11.h"
40 #include "ui/events/event_utils.h"
41 #include "ui/events/test/events_test_utils_x11.h"
42 #include "ui/gfx/x/x11_types.h"
43 #endif
45 namespace {
47 // The device id of the test touchpad device.
48 const unsigned int kTouchPadDeviceId = 1;
49 const int kKeyboardDeviceId = 2;
50 const int kMasterKeyboardDeviceId = 3;
52 std::string GetExpectedResultAsString(ui::KeyboardCode ui_keycode,
53 int ui_flags,
54 ui::EventType ui_type) {
55 return base::StringPrintf("ui_keycode=0x%X ui_flags=0x%X ui_type=%d",
56 ui_keycode,
57 ui_flags & ~ui::EF_IS_REPEAT,
58 ui_type);
61 std::string GetKeyEventAsString(const ui::KeyEvent& keyevent) {
62 return GetExpectedResultAsString(
63 keyevent.key_code(), keyevent.flags(), keyevent.type());
66 std::string GetRewrittenEventAsString(chromeos::EventRewriter* rewriter,
67 ui::KeyboardCode ui_keycode,
68 int ui_flags,
69 ui::EventType ui_type) {
70 const ui::KeyEvent event(ui_type, ui_keycode, ui_flags);
71 scoped_ptr<ui::Event> new_event;
72 rewriter->RewriteEvent(event, &new_event);
73 if (new_event)
74 return GetKeyEventAsString(
75 static_cast<const ui::KeyEvent&>(*new_event.get()));
76 return GetKeyEventAsString(event);
79 // Table entry for simple single key event rewriting tests.
80 struct KeyTestCase {
81 enum {
82 // Test types:
83 TEST_VKEY = 1 << 0, // Test ui::KeyEvent with no native event
84 TEST_X11 = 1 << 1, // Test ui::KeyEvent with native XKeyEvent
85 TEST_ALL = TEST_VKEY|TEST_X11,
86 // Special test flags:
87 NUMPAD = 1 << 8, // Set EF_NUMPAD_KEY on native-based event, because
88 // |XKeysymForWindowsKeyCode()| can not distinguish
89 // between pairs like XK_Insert and XK_KP_Insert.
91 int test;
92 ui::EventType type;
93 struct {
94 ui::KeyboardCode key_code;
95 int flags;
96 } input, expected;
99 #if defined(USE_X11)
100 // Check rewriting of an X11-based key event.
101 void CheckX11KeyTestCase(const std::string& expected,
102 chromeos::EventRewriter* rewriter,
103 const KeyTestCase& test,
104 XEvent* xevent) {
105 ui::KeyEvent xkey_event(xevent);
106 if (test.test & KeyTestCase::NUMPAD)
107 xkey_event.set_flags(xkey_event.flags() | ui::EF_NUMPAD_KEY);
108 // Verify that the X11-based key event is as expected.
109 EXPECT_EQ(GetExpectedResultAsString(
110 test.input.key_code, test.input.flags, test.type),
111 GetKeyEventAsString(xkey_event));
112 // Rewrite the event and check the result.
113 scoped_ptr<ui::Event> new_event;
114 rewriter->RewriteEvent(xkey_event, &new_event);
115 ui::KeyEvent& rewritten_key_event =
116 new_event ? *static_cast<ui::KeyEvent*>(new_event.get()) : xkey_event;
117 EXPECT_EQ(expected, GetKeyEventAsString(rewritten_key_event));
118 if (xevent->type == GenericEvent)
119 EXPECT_EQ(nullptr, rewritten_key_event.native_event());
120 else
121 EXPECT_NE(nullptr, rewritten_key_event.native_event());
123 #endif
125 // Tests a single stateless key rewrite operation.
126 // |i| is a an identifying number to locate failing tests in the tables.
127 void CheckKeyTestCase(chromeos::EventRewriter* rewriter,
128 const KeyTestCase& test) {
129 std::string expected =
130 GetExpectedResultAsString(
131 test.expected.key_code, test.expected.flags, test.type);
133 if (test.test & KeyTestCase::TEST_VKEY) {
134 // Check rewriting of a non-native-based key event.
135 EXPECT_EQ(
136 expected,
137 GetRewrittenEventAsString(
138 rewriter, test.input.key_code, test.input.flags, test.type));
141 #if defined(USE_X11)
142 if (test.test & KeyTestCase::TEST_X11) {
143 ui::ScopedXI2Event xev;
144 // Test an XKeyEvent.
145 xev.InitKeyEvent(test.type, test.input.key_code, test.input.flags);
146 XEvent* xevent = xev;
147 DCHECK((xevent->type == KeyPress) || (xevent->type == KeyRelease));
148 if (xevent->xkey.keycode)
149 CheckX11KeyTestCase(expected, rewriter, test, xevent);
150 // Test an XI2 GenericEvent.
151 xev.InitGenericKeyEvent(kMasterKeyboardDeviceId,
152 kKeyboardDeviceId,
153 test.type,
154 test.input.key_code,
155 test.input.flags);
156 xevent = xev;
157 DCHECK(xevent->type == GenericEvent);
158 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xevent->xcookie.data);
159 DCHECK((xievent->evtype == XI_KeyPress) ||
160 (xievent->evtype == XI_KeyRelease));
161 if (xievent->detail)
162 CheckX11KeyTestCase(expected, rewriter, test, xevent);
164 #endif
167 // Table entry for simple single function key event rewriting tests.
168 struct FunctionKeyTestCase {
169 ui::EventType type;
170 struct {
171 ui::KeyboardCode key_code;
172 int flags;
173 } input, vkey_expected, native_expected;
176 // Tests a single stateless function key rewrite operation.
177 // |i| is a an identifying number to locate failing tests in the tables.
178 // Function key mapping differs from the other key mappings because the
179 // EF_FUNCTION_KEY flag is set during ui::KeyEvent construction when passing in
180 // a native X11 event and the flag is not set when using other constructors.
181 void CheckFunctionKeyTestCase(chromeos::EventRewriter* rewriter,
182 const FunctionKeyTestCase& test) {
183 std::string vkey_expected =
184 GetExpectedResultAsString(
185 test.vkey_expected.key_code,
186 test.vkey_expected.flags,
187 test.type);
188 // Check rewriting of a non-native-based key event.
189 EXPECT_EQ(
190 vkey_expected,
191 GetRewrittenEventAsString(
192 rewriter, test.input.key_code, test.input.flags, test.type));
194 #if defined(USE_X11)
195 ui::ScopedXI2Event xev;
196 xev.InitKeyEvent(test.type, test.input.key_code, test.input.flags);
197 XEvent* xevent = xev;
198 if (xevent->xkey.keycode) {
199 ui::KeyEvent xkey_event(xevent);
200 // Rewrite the event and check the result.
201 scoped_ptr<ui::Event> new_event;
202 rewriter->RewriteEvent(xkey_event, &new_event);
203 ui::KeyEvent& rewritten_key_event =
204 new_event ? *static_cast<ui::KeyEvent*>(new_event.get()) : xkey_event;
205 std::string native_expected =
206 GetExpectedResultAsString(
207 test.native_expected.key_code,
208 test.native_expected.flags,
209 test.type);
210 EXPECT_EQ(native_expected, GetKeyEventAsString(rewritten_key_event));
212 #endif
215 } // namespace
217 namespace chromeos {
219 class EventRewriterTest : public ash::test::AshTestBase {
220 public:
221 EventRewriterTest()
222 : fake_user_manager_(new user_manager::FakeUserManager),
223 user_manager_enabler_(fake_user_manager_),
224 input_method_manager_mock_(NULL) {}
225 ~EventRewriterTest() override {}
227 void SetUp() override {
228 input_method_manager_mock_ =
229 new chromeos::input_method::MockInputMethodManager;
230 chromeos::input_method::InitializeForTesting(
231 input_method_manager_mock_); // pass ownership
233 AshTestBase::SetUp();
236 void TearDown() override {
237 AshTestBase::TearDown();
238 // Shutdown() deletes the IME mock object.
239 chromeos::input_method::Shutdown();
242 protected:
243 void TestRewriteNumPadKeys();
244 void TestRewriteNumPadKeysOnAppleKeyboard();
246 const ui::MouseEvent* RewriteMouseButtonEvent(
247 chromeos::EventRewriter* rewriter,
248 const ui::MouseEvent& event,
249 scoped_ptr<ui::Event>* new_event) {
250 rewriter->RewriteMouseButtonEventForTesting(event, new_event);
251 return *new_event ? static_cast<const ui::MouseEvent*>(new_event->get())
252 : &event;
255 user_manager::FakeUserManager* fake_user_manager_; // Not owned.
256 chromeos::ScopedUserManagerEnabler user_manager_enabler_;
257 chromeos::input_method::MockInputMethodManager* input_method_manager_mock_;
260 TEST_F(EventRewriterTest, TestRewriteCommandToControl) {
261 // First, test with a PC keyboard.
262 TestingPrefServiceSyncable prefs;
263 EventRewriter rewriter(NULL);
264 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
265 rewriter.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId);
266 rewriter.set_pref_service_for_testing(&prefs);
268 KeyTestCase pc_keyboard_tests[] = {
269 // VKEY_A, Alt modifier.
270 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
271 {ui::VKEY_A, ui::EF_ALT_DOWN},
272 {ui::VKEY_A, ui::EF_ALT_DOWN}},
274 // VKEY_A, Win modifier.
275 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
276 {ui::VKEY_A, ui::EF_COMMAND_DOWN},
277 {ui::VKEY_A, ui::EF_COMMAND_DOWN}},
279 // VKEY_A, Alt+Win modifier.
280 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
281 {ui::VKEY_A, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN},
282 {ui::VKEY_A, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN}},
284 // VKEY_LWIN (left Windows key), Alt modifier.
285 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
286 {ui::VKEY_LWIN, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN},
287 {ui::VKEY_LWIN, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN}},
289 // VKEY_RWIN (right Windows key), Alt modifier.
290 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
291 {ui::VKEY_RWIN, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN},
292 {ui::VKEY_RWIN, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN}},
295 for (size_t i = 0; i < arraysize(pc_keyboard_tests); ++i) {
296 SCOPED_TRACE(i);
297 CheckKeyTestCase(&rewriter, pc_keyboard_tests[i]);
300 // An Apple keyboard reusing the ID, zero.
301 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "Apple Keyboard");
302 rewriter.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId);
304 KeyTestCase apple_keyboard_tests[] = {
305 // VKEY_A, Alt modifier.
306 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
307 {ui::VKEY_A, ui::EF_ALT_DOWN},
308 {ui::VKEY_A, ui::EF_ALT_DOWN}},
310 // VKEY_A, Win modifier.
311 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
312 {ui::VKEY_A, ui::EF_COMMAND_DOWN},
313 {ui::VKEY_A, ui::EF_CONTROL_DOWN}},
315 // VKEY_A, Alt+Win modifier.
316 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
317 {ui::VKEY_A, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN},
318 {ui::VKEY_A, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN}},
320 // VKEY_LWIN (left Windows key), Alt modifier.
321 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
322 {ui::VKEY_LWIN, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN},
323 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN}},
325 // VKEY_RWIN (right Windows key), Alt modifier.
326 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
327 {ui::VKEY_RWIN, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN},
328 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN}},
331 for (size_t i = 0; i < arraysize(apple_keyboard_tests); ++i) {
332 SCOPED_TRACE(i);
333 CheckKeyTestCase(&rewriter, apple_keyboard_tests[i]);
337 // For crbug.com/133896.
338 TEST_F(EventRewriterTest, TestRewriteCommandToControlWithControlRemapped) {
339 // Remap Control to Alt.
340 TestingPrefServiceSyncable prefs;
341 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
342 IntegerPrefMember control;
343 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
344 control.SetValue(chromeos::input_method::kAltKey);
346 EventRewriter rewriter(NULL);
347 rewriter.set_pref_service_for_testing(&prefs);
348 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
349 rewriter.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId);
351 KeyTestCase pc_keyboard_tests[] = {// Control should be remapped to Alt.
352 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
353 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN},
354 {ui::VKEY_MENU, ui::EF_ALT_DOWN}},
357 for (size_t i = 0; i < arraysize(pc_keyboard_tests); ++i) {
358 SCOPED_TRACE(i);
359 CheckKeyTestCase(&rewriter, pc_keyboard_tests[i]);
362 // An Apple keyboard reusing the ID, zero.
363 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "Apple Keyboard");
364 rewriter.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId);
366 KeyTestCase apple_keyboard_tests[] = {
367 // VKEY_LWIN (left Command key) with Alt modifier. The remapped Command
368 // key should never be re-remapped to Alt.
369 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
370 {ui::VKEY_LWIN, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN},
371 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN}},
373 // VKEY_RWIN (right Command key) with Alt modifier. The remapped Command
374 // key should never be re-remapped to Alt.
375 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
376 {ui::VKEY_RWIN, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN},
377 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN}},
380 for (size_t i = 0; i < arraysize(apple_keyboard_tests); ++i) {
381 SCOPED_TRACE(i);
382 CheckKeyTestCase(&rewriter, apple_keyboard_tests[i]);
386 void EventRewriterTest::TestRewriteNumPadKeys() {
387 TestingPrefServiceSyncable prefs;
388 EventRewriter rewriter(NULL);
389 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
390 rewriter.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId);
391 rewriter.set_pref_service_for_testing(&prefs);
393 KeyTestCase tests[] = {
394 // XK_KP_Insert (= NumPad 0 without Num Lock), no modifier.
395 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
396 {ui::VKEY_INSERT, ui::EF_NUMPAD_KEY},
397 {ui::VKEY_NUMPAD0, ui::EF_NUMPAD_KEY}},
399 // XK_KP_Insert (= NumPad 0 without Num Lock), Alt modifier.
400 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
401 {ui::VKEY_INSERT, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY},
402 {ui::VKEY_NUMPAD0, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY}},
404 // XK_KP_Delete (= NumPad . without Num Lock), Alt modifier.
405 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
406 {ui::VKEY_DELETE, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY},
407 {ui::VKEY_DECIMAL, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY}},
409 // XK_KP_End (= NumPad 1 without Num Lock), Alt modifier.
410 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
411 {ui::VKEY_END, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY},
412 {ui::VKEY_NUMPAD1, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY}},
414 // XK_KP_Down (= NumPad 2 without Num Lock), Alt modifier.
415 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
416 {ui::VKEY_DOWN, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY},
417 {ui::VKEY_NUMPAD2, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY}},
419 // XK_KP_Next (= NumPad 3 without Num Lock), Alt modifier.
420 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
421 {ui::VKEY_NEXT, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY},
422 {ui::VKEY_NUMPAD3, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY}},
424 // XK_KP_Left (= NumPad 4 without Num Lock), Alt modifier.
425 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
426 {ui::VKEY_LEFT, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY},
427 {ui::VKEY_NUMPAD4, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY}},
429 // XK_KP_Begin (= NumPad 5 without Num Lock), Alt modifier.
430 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
431 {ui::VKEY_CLEAR, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY},
432 {ui::VKEY_NUMPAD5, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY}},
434 // XK_KP_Right (= NumPad 6 without Num Lock), Alt modifier.
435 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
436 {ui::VKEY_RIGHT, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY},
437 {ui::VKEY_NUMPAD6, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY}},
439 // XK_KP_Home (= NumPad 7 without Num Lock), Alt modifier.
440 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
441 {ui::VKEY_HOME, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY},
442 {ui::VKEY_NUMPAD7, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY}},
444 // XK_KP_Up (= NumPad 8 without Num Lock), Alt modifier.
445 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
446 {ui::VKEY_UP, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY},
447 {ui::VKEY_NUMPAD8, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY}},
449 // XK_KP_Prior (= NumPad 9 without Num Lock), Alt modifier.
450 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
451 {ui::VKEY_PRIOR, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY},
452 {ui::VKEY_NUMPAD9, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY}},
454 // XK_KP_0 (= NumPad 0 with Num Lock), Num Lock modifier.
455 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
456 {ui::VKEY_NUMPAD0, ui::EF_NUMPAD_KEY},
457 {ui::VKEY_NUMPAD0, ui::EF_NUMPAD_KEY}},
459 // XK_KP_DECIMAL (= NumPad . with Num Lock), Num Lock modifier.
460 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
461 {ui::VKEY_DECIMAL, ui::EF_NUMPAD_KEY},
462 {ui::VKEY_DECIMAL, ui::EF_NUMPAD_KEY}},
464 // XK_KP_1 (= NumPad 1 with Num Lock), Num Lock modifier.
465 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
466 {ui::VKEY_NUMPAD1, ui::EF_NUMPAD_KEY},
467 {ui::VKEY_NUMPAD1, ui::EF_NUMPAD_KEY}},
469 // XK_KP_2 (= NumPad 2 with Num Lock), Num Lock modifier.
470 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
471 {ui::VKEY_NUMPAD2, ui::EF_NUMPAD_KEY},
472 {ui::VKEY_NUMPAD2, ui::EF_NUMPAD_KEY}},
474 // XK_KP_3 (= NumPad 3 with Num Lock), Num Lock modifier.
475 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
476 {ui::VKEY_NUMPAD3, ui::EF_NUMPAD_KEY},
477 {ui::VKEY_NUMPAD3, ui::EF_NUMPAD_KEY}},
479 // XK_KP_4 (= NumPad 4 with Num Lock), Num Lock modifier.
480 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
481 {ui::VKEY_NUMPAD4, ui::EF_NUMPAD_KEY},
482 {ui::VKEY_NUMPAD4, ui::EF_NUMPAD_KEY}},
484 // XK_KP_5 (= NumPad 5 with Num Lock), Num Lock modifier.
485 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
486 {ui::VKEY_NUMPAD5, ui::EF_NUMPAD_KEY},
487 {ui::VKEY_NUMPAD5, ui::EF_NUMPAD_KEY}},
489 // XK_KP_6 (= NumPad 6 with Num Lock), Num Lock modifier.
490 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
491 {ui::VKEY_NUMPAD6, ui::EF_NUMPAD_KEY},
492 {ui::VKEY_NUMPAD6, ui::EF_NUMPAD_KEY}},
494 // XK_KP_7 (= NumPad 7 with Num Lock), Num Lock modifier.
495 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
496 {ui::VKEY_NUMPAD7, ui::EF_NUMPAD_KEY},
497 {ui::VKEY_NUMPAD7, ui::EF_NUMPAD_KEY}},
499 // XK_KP_8 (= NumPad 8 with Num Lock), Num Lock modifier.
500 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
501 {ui::VKEY_NUMPAD8, ui::EF_NUMPAD_KEY},
502 {ui::VKEY_NUMPAD8, ui::EF_NUMPAD_KEY}},
504 // XK_KP_9 (= NumPad 9 with Num Lock), Num Lock modifier.
505 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
506 {ui::VKEY_NUMPAD9, ui::EF_NUMPAD_KEY},
507 {ui::VKEY_NUMPAD9, ui::EF_NUMPAD_KEY}},
510 for (size_t i = 0; i < arraysize(tests); ++i) {
511 SCOPED_TRACE(i);
512 CheckKeyTestCase(&rewriter, tests[i]);
516 TEST_F(EventRewriterTest, TestRewriteNumPadKeys) {
517 TestRewriteNumPadKeys();
520 TEST_F(EventRewriterTest, TestRewriteNumPadKeysWithDiamondKeyFlag) {
521 // Make sure the num lock works correctly even when Diamond key exists.
522 const base::CommandLine original_cl(*base::CommandLine::ForCurrentProcess());
523 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
524 chromeos::switches::kHasChromeOSDiamondKey, "");
526 TestRewriteNumPadKeys();
527 *base::CommandLine::ForCurrentProcess() = original_cl;
530 // Tests if the rewriter can handle a Command + Num Pad event.
531 void EventRewriterTest::TestRewriteNumPadKeysOnAppleKeyboard() {
532 TestingPrefServiceSyncable prefs;
533 EventRewriter rewriter(NULL);
534 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "Apple Keyboard");
535 rewriter.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId);
536 rewriter.set_pref_service_for_testing(&prefs);
538 KeyTestCase tests[] = {
539 // XK_KP_End (= NumPad 1 without Num Lock), Win modifier.
540 // The result should be "Num Pad 1 with Control + Num Lock modifiers".
541 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
542 {ui::VKEY_END, ui::EF_COMMAND_DOWN | ui::EF_NUMPAD_KEY},
543 {ui::VKEY_NUMPAD1, ui::EF_CONTROL_DOWN | ui::EF_NUMPAD_KEY}},
545 // XK_KP_1 (= NumPad 1 with Num Lock), Win modifier.
546 // The result should also be "Num Pad 1 with Control + Num Lock
547 // modifiers".
548 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
549 {ui::VKEY_NUMPAD1, ui::EF_COMMAND_DOWN | ui::EF_NUMPAD_KEY},
550 {ui::VKEY_NUMPAD1, ui::EF_CONTROL_DOWN | ui::EF_NUMPAD_KEY}},
553 for (size_t i = 0; i < arraysize(tests); ++i) {
554 SCOPED_TRACE(i);
555 CheckKeyTestCase(&rewriter, tests[i]);
559 TEST_F(EventRewriterTest, TestRewriteNumPadKeysOnAppleKeyboard) {
560 TestRewriteNumPadKeysOnAppleKeyboard();
563 TEST_F(EventRewriterTest,
564 TestRewriteNumPadKeysOnAppleKeyboardWithDiamondKeyFlag) {
565 // Makes sure the num lock works correctly even when Diamond key exists.
566 const base::CommandLine original_cl(*base::CommandLine::ForCurrentProcess());
567 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
568 chromeos::switches::kHasChromeOSDiamondKey, "");
570 TestRewriteNumPadKeysOnAppleKeyboard();
571 *base::CommandLine::ForCurrentProcess() = original_cl;
574 TEST_F(EventRewriterTest, TestRewriteModifiersNoRemap) {
575 TestingPrefServiceSyncable prefs;
576 EventRewriter rewriter(NULL);
577 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
578 rewriter.set_pref_service_for_testing(&prefs);
580 KeyTestCase tests[] = {
581 // Press Search. Confirm the event is not rewritten.
582 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
583 {ui::VKEY_LWIN, ui::EF_NONE},
584 {ui::VKEY_LWIN, ui::EF_COMMAND_DOWN}},
586 // Press left Control. Confirm the event is not rewritten.
587 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
588 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN},
589 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN}},
591 // Press right Control. Confirm the event is not rewritten.
592 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
593 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN},
594 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN}},
596 // Press left Alt. Confirm the event is not rewritten.
597 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
598 {ui::VKEY_MENU, ui::EF_ALT_DOWN},
599 {ui::VKEY_MENU, ui::EF_ALT_DOWN}},
601 // Press right Alt. Confirm the event is not rewritten.
602 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
603 {ui::VKEY_MENU, ui::EF_ALT_DOWN},
604 {ui::VKEY_MENU, ui::EF_ALT_DOWN}},
606 // Test KeyRelease event, just in case.
607 // Release Search. Confirm the release event is not rewritten.
608 {KeyTestCase::TEST_ALL, ui::ET_KEY_RELEASED,
609 {ui::VKEY_LWIN, ui::EF_NONE},
610 {ui::VKEY_LWIN, ui::EF_NONE}},
613 for (size_t i = 0; i < arraysize(tests); ++i) {
614 SCOPED_TRACE(i);
615 CheckKeyTestCase(&rewriter, tests[i]);
619 TEST_F(EventRewriterTest, TestRewriteModifiersNoRemapMultipleKeys) {
620 TestingPrefServiceSyncable prefs;
621 EventRewriter rewriter(NULL);
622 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
623 rewriter.set_pref_service_for_testing(&prefs);
625 KeyTestCase tests[] = {
626 // Press Alt with Shift. Confirm the event is not rewritten.
627 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
628 {ui::VKEY_MENU, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN},
629 {ui::VKEY_MENU, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN}},
631 // Press Search with Caps Lock mask. Confirm the event is not rewritten.
632 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
633 {ui::VKEY_LWIN, ui::EF_CAPS_LOCK_DOWN | ui::EF_COMMAND_DOWN},
634 {ui::VKEY_LWIN, ui::EF_CAPS_LOCK_DOWN | ui::EF_COMMAND_DOWN}},
636 // Release Search with Caps Lock mask. Confirm the event is not rewritten.
637 {KeyTestCase::TEST_ALL, ui::ET_KEY_RELEASED,
638 {ui::VKEY_LWIN, ui::EF_CAPS_LOCK_DOWN},
639 {ui::VKEY_LWIN, ui::EF_CAPS_LOCK_DOWN}},
641 // Press Shift+Ctrl+Alt+Search+A. Confirm the event is not rewritten.
642 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
643 {ui::VKEY_B, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN |
644 ui::EF_COMMAND_DOWN},
645 {ui::VKEY_B, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN |
646 ui::EF_COMMAND_DOWN}},
649 for (size_t i = 0; i < arraysize(tests); ++i) {
650 SCOPED_TRACE(i);
651 CheckKeyTestCase(&rewriter, tests[i]);
655 TEST_F(EventRewriterTest, TestRewriteModifiersDisableSome) {
656 // Disable Search and Control keys.
657 TestingPrefServiceSyncable prefs;
658 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
659 IntegerPrefMember search;
660 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
661 search.SetValue(chromeos::input_method::kVoidKey);
662 IntegerPrefMember control;
663 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
664 control.SetValue(chromeos::input_method::kVoidKey);
666 EventRewriter rewriter(NULL);
667 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
668 rewriter.set_pref_service_for_testing(&prefs);
670 KeyTestCase disabled_modifier_tests[] = {
671 // Press Alt with Shift. This key press shouldn't be affected by the
672 // pref. Confirm the event is not rewritten.
673 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
674 {ui::VKEY_MENU, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN},
675 {ui::VKEY_MENU, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN}},
677 // Press Search. Confirm the event is now VKEY_UNKNOWN.
678 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
679 {ui::VKEY_LWIN, ui::EF_NONE},
680 {ui::VKEY_UNKNOWN, ui::EF_NONE}},
682 // Press Control. Confirm the event is now VKEY_UNKNOWN.
683 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
684 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN},
685 {ui::VKEY_UNKNOWN, ui::EF_NONE}},
687 // Press Control+Search. Confirm the event is now VKEY_UNKNOWN
688 // without any modifiers.
689 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
690 {ui::VKEY_LWIN, ui::EF_CONTROL_DOWN},
691 {ui::VKEY_UNKNOWN, ui::EF_NONE}},
693 // Press Control+Search+a. Confirm the event is now VKEY_A without any
694 // modifiers.
695 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
696 {ui::VKEY_A, ui::EF_CONTROL_DOWN},
697 {ui::VKEY_A, ui::EF_NONE}},
699 // Press Control+Search+Alt+a. Confirm the event is now VKEY_A only with
700 // the Alt modifier.
701 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
702 {ui::VKEY_A, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN},
703 {ui::VKEY_A, ui::EF_ALT_DOWN}},
706 for (size_t i = 0; i < arraysize(disabled_modifier_tests); ++i) {
707 SCOPED_TRACE(i);
708 CheckKeyTestCase(&rewriter, disabled_modifier_tests[i]);
711 // Remap Alt to Control.
712 IntegerPrefMember alt;
713 alt.Init(prefs::kLanguageRemapAltKeyTo, &prefs);
714 alt.SetValue(chromeos::input_method::kControlKey);
716 KeyTestCase tests[] = {
717 // Press left Alt. Confirm the event is now VKEY_CONTROL
718 // even though the Control key itself is disabled.
719 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
720 {ui::VKEY_MENU, ui::EF_ALT_DOWN},
721 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN}},
723 // Press Alt+a. Confirm the event is now Control+a even though the Control
724 // key itself is disabled.
725 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
726 {ui::VKEY_A, ui::EF_ALT_DOWN},
727 {ui::VKEY_A, ui::EF_CONTROL_DOWN}},
730 for (size_t i = 0; i < arraysize(tests); ++i) {
731 SCOPED_TRACE(i);
732 CheckKeyTestCase(&rewriter, tests[i]);
736 TEST_F(EventRewriterTest, TestRewriteModifiersRemapToControl) {
737 // Remap Search to Control.
738 TestingPrefServiceSyncable prefs;
739 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
740 IntegerPrefMember search;
741 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
742 search.SetValue(chromeos::input_method::kControlKey);
744 EventRewriter rewriter(NULL);
745 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
746 rewriter.set_pref_service_for_testing(&prefs);
748 KeyTestCase s_tests[] = {
749 // Press Search. Confirm the event is now VKEY_CONTROL.
750 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
751 {ui::VKEY_LWIN, ui::EF_COMMAND_DOWN},
752 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN}},
755 for (size_t i = 0; i < arraysize(s_tests); ++i) {
756 SCOPED_TRACE(i);
757 CheckKeyTestCase(&rewriter, s_tests[i]);
760 // Remap Alt to Control too.
761 IntegerPrefMember alt;
762 alt.Init(prefs::kLanguageRemapAltKeyTo, &prefs);
763 alt.SetValue(chromeos::input_method::kControlKey);
765 KeyTestCase sa_tests[] = {
766 // Press Alt. Confirm the event is now VKEY_CONTROL.
767 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
768 {ui::VKEY_MENU, ui::EF_ALT_DOWN},
769 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN}},
771 // Press Alt+Search. Confirm the event is now VKEY_CONTROL.
772 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
773 {ui::VKEY_LWIN, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN},
774 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN}},
776 // Press Control+Alt+Search. Confirm the event is now VKEY_CONTROL.
777 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
778 {ui::VKEY_LWIN,
779 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN},
780 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN}},
782 // Press Shift+Control+Alt+Search. Confirm the event is now Control with
783 // Shift and Control modifiers.
784 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
785 {ui::VKEY_LWIN, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
786 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN},
787 {ui::VKEY_CONTROL, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN}},
789 // Press Shift+Control+Alt+Search+B. Confirm the event is now B with Shift
790 // and Control modifiers.
791 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
792 {ui::VKEY_B, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN |
793 ui::EF_COMMAND_DOWN},
794 {ui::VKEY_B, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN}},
797 for (size_t i = 0; i < arraysize(sa_tests); ++i) {
798 SCOPED_TRACE(i);
799 CheckKeyTestCase(&rewriter, sa_tests[i]);
803 TEST_F(EventRewriterTest, TestRewriteModifiersRemapToEscape) {
804 // Remap Search to ESC.
805 TestingPrefServiceSyncable prefs;
806 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
807 IntegerPrefMember search;
808 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
809 search.SetValue(chromeos::input_method::kEscapeKey);
811 EventRewriter rewriter(NULL);
812 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
813 rewriter.set_pref_service_for_testing(&prefs);
815 KeyTestCase tests[] = {// Press Search. Confirm the event is now VKEY_ESCAPE.
816 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
817 {ui::VKEY_LWIN, ui::EF_COMMAND_DOWN},
818 {ui::VKEY_ESCAPE, ui::EF_NONE}},
821 for (size_t i = 0; i < arraysize(tests); ++i) {
822 SCOPED_TRACE(i);
823 CheckKeyTestCase(&rewriter, tests[i]);
827 TEST_F(EventRewriterTest, TestRewriteModifiersRemapMany) {
828 // Remap Search to Alt.
829 TestingPrefServiceSyncable prefs;
830 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
831 IntegerPrefMember search;
832 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
833 search.SetValue(chromeos::input_method::kAltKey);
835 EventRewriter rewriter(NULL);
836 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
837 rewriter.set_pref_service_for_testing(&prefs);
839 KeyTestCase s2a_tests[] = {
840 // Press Search. Confirm the event is now VKEY_MENU.
841 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
842 {ui::VKEY_LWIN, ui::EF_COMMAND_DOWN},
843 {ui::VKEY_MENU, ui::EF_ALT_DOWN}},
846 for (size_t i = 0; i < arraysize(s2a_tests); ++i) {
847 SCOPED_TRACE(i);
848 CheckKeyTestCase(&rewriter, s2a_tests[i]);
851 // Remap Alt to Control.
852 IntegerPrefMember alt;
853 alt.Init(prefs::kLanguageRemapAltKeyTo, &prefs);
854 alt.SetValue(chromeos::input_method::kControlKey);
856 KeyTestCase a2c_tests[] = {
857 // Press left Alt. Confirm the event is now VKEY_CONTROL.
858 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
859 {ui::VKEY_MENU, ui::EF_ALT_DOWN},
860 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN}},
861 // Press Shift+comma. Verify that only the flags are changed.
862 // The X11 portion of the test addresses crbug.com/390263 by verifying
863 // that the X keycode remains that for ',<' and not for 105-key '<>'.
864 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
865 {ui::VKEY_OEM_COMMA, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN},
866 {ui::VKEY_OEM_COMMA, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN}},
867 // Press Shift+9. Verify that only the flags are changed.
868 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
869 {ui::VKEY_9, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN},
870 {ui::VKEY_9, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN}},
873 for (size_t i = 0; i < arraysize(a2c_tests); ++i) {
874 SCOPED_TRACE(i);
875 CheckKeyTestCase(&rewriter, a2c_tests[i]);
878 // Remap Control to Search.
879 IntegerPrefMember control;
880 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
881 control.SetValue(chromeos::input_method::kSearchKey);
883 KeyTestCase c2s_tests[] = {
884 // Press left Control. Confirm the event is now VKEY_LWIN.
885 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
886 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN},
887 {ui::VKEY_LWIN, ui::EF_COMMAND_DOWN}},
889 // Then, press all of the three, Control+Alt+Search.
890 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
891 {ui::VKEY_LWIN,
892 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN},
893 {ui::VKEY_MENU,
894 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN}},
896 // Press Shift+Control+Alt+Search.
897 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
898 {ui::VKEY_LWIN, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
899 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN},
900 {ui::VKEY_MENU, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
901 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN}},
903 // Press Shift+Control+Alt+Search+B
904 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
905 {ui::VKEY_B, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN |
906 ui::EF_COMMAND_DOWN},
907 {ui::VKEY_B, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN |
908 ui::EF_COMMAND_DOWN}},
911 for (size_t i = 0; i < arraysize(c2s_tests); ++i) {
912 SCOPED_TRACE(i);
913 CheckKeyTestCase(&rewriter, c2s_tests[i]);
917 TEST_F(EventRewriterTest, TestRewriteModifiersRemapToCapsLock) {
918 // Remap Search to Caps Lock.
919 TestingPrefServiceSyncable prefs;
920 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
921 IntegerPrefMember search;
922 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
923 search.SetValue(chromeos::input_method::kCapsLockKey);
925 chromeos::input_method::FakeImeKeyboard ime_keyboard;
926 EventRewriter rewriter(NULL);
927 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
928 rewriter.set_pref_service_for_testing(&prefs);
929 rewriter.set_ime_keyboard_for_testing(&ime_keyboard);
930 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
932 // Press Search.
933 EXPECT_EQ(
934 GetExpectedResultAsString(ui::VKEY_CAPITAL,
935 ui::EF_CAPS_LOCK_DOWN | ui::EF_MOD3_DOWN,
936 ui::ET_KEY_PRESSED),
937 GetRewrittenEventAsString(
938 &rewriter, ui::VKEY_LWIN, ui::EF_COMMAND_DOWN, ui::ET_KEY_PRESSED));
939 // Confirm that the Caps Lock status is changed.
940 EXPECT_TRUE(ime_keyboard.caps_lock_is_enabled_);
942 // Release Search.
943 EXPECT_EQ(GetExpectedResultAsString(
944 ui::VKEY_CAPITAL, ui::EF_NONE, ui::ET_KEY_RELEASED),
945 GetRewrittenEventAsString(
946 &rewriter, ui::VKEY_LWIN, ui::EF_NONE, ui::ET_KEY_RELEASED));
947 // Confirm that the Caps Lock status is not changed.
948 EXPECT_TRUE(ime_keyboard.caps_lock_is_enabled_);
950 // Press Search.
951 EXPECT_EQ(
952 GetExpectedResultAsString(ui::VKEY_CAPITAL,
953 ui::EF_CAPS_LOCK_DOWN | ui::EF_MOD3_DOWN,
954 ui::ET_KEY_PRESSED),
955 GetRewrittenEventAsString(&rewriter,
956 ui::VKEY_LWIN,
957 ui::EF_COMMAND_DOWN | ui::EF_CAPS_LOCK_DOWN,
958 ui::ET_KEY_PRESSED));
959 // Confirm that the Caps Lock status is changed.
960 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
962 // Release Search.
963 EXPECT_EQ(GetExpectedResultAsString(
964 ui::VKEY_CAPITAL, ui::EF_NONE, ui::ET_KEY_RELEASED),
965 GetRewrittenEventAsString(
966 &rewriter, ui::VKEY_LWIN, ui::EF_NONE, ui::ET_KEY_RELEASED));
967 // Confirm that the Caps Lock status is not changed.
968 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
970 // Press Caps Lock (on an external keyboard).
971 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
972 ui::EF_CAPS_LOCK_DOWN | ui::EF_MOD3_DOWN,
973 ui::ET_KEY_PRESSED),
974 GetRewrittenEventAsString(&rewriter,
975 ui::VKEY_CAPITAL,
976 ui::EF_CAPS_LOCK_DOWN | ui::EF_MOD3_DOWN,
977 ui::ET_KEY_PRESSED));
979 // Confirm that calling RewriteForTesting() does not change the state of
980 // |ime_keyboard|. In this case, X Window system itself should change the
981 // Caps Lock state, not ash::EventRewriter.
982 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
984 // Release Caps Lock (on an external keyboard).
985 EXPECT_EQ(GetExpectedResultAsString(
986 ui::VKEY_CAPITAL, ui::EF_NONE, ui::ET_KEY_RELEASED),
987 GetRewrittenEventAsString(
988 &rewriter, ui::VKEY_CAPITAL, ui::EF_NONE, ui::ET_KEY_RELEASED));
989 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
992 TEST_F(EventRewriterTest, TestRewriteCapsLock) {
993 TestingPrefServiceSyncable prefs;
994 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
996 chromeos::input_method::FakeImeKeyboard ime_keyboard;
997 EventRewriter rewriter(NULL);
998 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
999 rewriter.set_pref_service_for_testing(&prefs);
1000 rewriter.set_ime_keyboard_for_testing(&ime_keyboard);
1001 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
1003 // On Chrome OS, CapsLock is mapped to F16 with Mod3Mask.
1004 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
1005 ui::EF_CAPS_LOCK_DOWN | ui::EF_MOD3_DOWN,
1006 ui::ET_KEY_PRESSED),
1007 GetRewrittenEventAsString(
1008 &rewriter, ui::VKEY_F16, ui::EF_MOD3_DOWN, ui::ET_KEY_PRESSED));
1009 EXPECT_TRUE(ime_keyboard.caps_lock_is_enabled_);
1012 TEST_F(EventRewriterTest, TestRewriteDiamondKey) {
1013 TestingPrefServiceSyncable prefs;
1014 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1016 chromeos::input_method::FakeImeKeyboard ime_keyboard;
1017 EventRewriter rewriter(NULL);
1018 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
1019 rewriter.set_pref_service_for_testing(&prefs);
1020 rewriter.set_ime_keyboard_for_testing(&ime_keyboard);
1022 KeyTestCase tests[] = {
1023 // F15 should work as Ctrl when --has-chromeos-diamond-key is not
1024 // specified.
1025 {KeyTestCase::TEST_VKEY,
1026 ui::ET_KEY_PRESSED,
1027 {ui::VKEY_F15, ui::EF_NONE},
1028 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN}},
1030 {KeyTestCase::TEST_VKEY,
1031 ui::ET_KEY_RELEASED,
1032 {ui::VKEY_F15, ui::EF_NONE},
1033 {ui::VKEY_CONTROL, ui::EF_NONE}},
1035 // However, Mod2Mask should not be rewritten to CtrlMask when
1036 // --has-chromeos-diamond-key is not specified.
1037 {KeyTestCase::TEST_VKEY,
1038 ui::ET_KEY_PRESSED,
1039 {ui::VKEY_A, ui::EF_NONE},
1040 {ui::VKEY_A, ui::EF_NONE}},
1043 for (size_t i = 0; i < arraysize(tests); ++i) {
1044 SCOPED_TRACE(i);
1045 CheckKeyTestCase(&rewriter, tests[i]);
1049 TEST_F(EventRewriterTest, TestRewriteDiamondKeyWithFlag) {
1050 const base::CommandLine original_cl(*base::CommandLine::ForCurrentProcess());
1051 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1052 chromeos::switches::kHasChromeOSDiamondKey, "");
1054 TestingPrefServiceSyncable prefs;
1055 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1057 chromeos::input_method::FakeImeKeyboard ime_keyboard;
1058 EventRewriter rewriter(NULL);
1059 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
1060 rewriter.set_pref_service_for_testing(&prefs);
1061 rewriter.set_ime_keyboard_for_testing(&ime_keyboard);
1063 // By default, F15 should work as Control.
1064 EXPECT_EQ(GetExpectedResultAsString(
1065 ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
1066 GetRewrittenEventAsString(
1067 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_PRESSED));
1068 // Check that Control is applied to a subsequent key press.
1069 EXPECT_EQ(GetExpectedResultAsString(
1070 ui::VKEY_A, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
1071 GetRewrittenEventAsString(
1072 &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
1073 // Release F15
1074 EXPECT_EQ(GetExpectedResultAsString(
1075 ui::VKEY_CONTROL, ui::EF_NONE, ui::ET_KEY_RELEASED),
1076 GetRewrittenEventAsString(
1077 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_RELEASED));
1078 // Check that Control is no longer applied to a subsequent key press.
1079 EXPECT_EQ(
1080 GetExpectedResultAsString(ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED),
1081 GetRewrittenEventAsString(
1082 &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
1084 IntegerPrefMember diamond;
1085 diamond.Init(prefs::kLanguageRemapDiamondKeyTo, &prefs);
1086 diamond.SetValue(chromeos::input_method::kVoidKey);
1088 EXPECT_EQ(GetExpectedResultAsString(
1089 ui::VKEY_UNKNOWN, ui::EF_NONE, ui::ET_KEY_PRESSED),
1090 GetRewrittenEventAsString(
1091 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_PRESSED));
1092 // Check that no modifier is applied to another key.
1093 EXPECT_EQ(
1094 GetExpectedResultAsString(ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED),
1095 GetRewrittenEventAsString(
1096 &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
1098 diamond.SetValue(chromeos::input_method::kControlKey);
1100 EXPECT_EQ(GetExpectedResultAsString(
1101 ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
1102 GetRewrittenEventAsString(
1103 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_PRESSED));
1104 // Check that Control is applied to a subsequent key press.
1105 EXPECT_EQ(GetExpectedResultAsString(
1106 ui::VKEY_A, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
1107 GetRewrittenEventAsString(
1108 &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
1109 // Release F15
1110 EXPECT_EQ(GetExpectedResultAsString(
1111 ui::VKEY_CONTROL, ui::EF_NONE, ui::ET_KEY_RELEASED),
1112 GetRewrittenEventAsString(
1113 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_RELEASED));
1114 // Check that Control is no longer applied to a subsequent key press.
1115 EXPECT_EQ(
1116 GetExpectedResultAsString(ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED),
1117 GetRewrittenEventAsString(
1118 &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
1120 diamond.SetValue(chromeos::input_method::kAltKey);
1122 EXPECT_EQ(GetExpectedResultAsString(
1123 ui::VKEY_MENU, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED),
1124 GetRewrittenEventAsString(
1125 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_PRESSED));
1126 // Check that Alt is applied to a subsequent key press.
1127 EXPECT_EQ(GetExpectedResultAsString(
1128 ui::VKEY_A, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED),
1129 GetRewrittenEventAsString(
1130 &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
1131 // Release F15
1132 EXPECT_EQ(GetExpectedResultAsString(
1133 ui::VKEY_MENU, ui::EF_NONE, ui::ET_KEY_RELEASED),
1134 GetRewrittenEventAsString(
1135 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_RELEASED));
1136 // Check that Alt is no longer applied to a subsequent key press.
1137 EXPECT_EQ(
1138 GetExpectedResultAsString(ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED),
1139 GetRewrittenEventAsString(
1140 &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
1142 diamond.SetValue(chromeos::input_method::kCapsLockKey);
1144 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
1145 ui::EF_CAPS_LOCK_DOWN | ui::EF_MOD3_DOWN,
1146 ui::ET_KEY_PRESSED),
1147 GetRewrittenEventAsString(
1148 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_PRESSED));
1149 // Check that Caps is applied to a subsequent key press.
1150 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
1151 ui::EF_CAPS_LOCK_DOWN | ui::EF_MOD3_DOWN,
1152 ui::ET_KEY_PRESSED),
1153 GetRewrittenEventAsString(
1154 &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
1155 // Release F15
1156 EXPECT_EQ(GetExpectedResultAsString(
1157 ui::VKEY_CAPITAL, ui::EF_NONE, ui::ET_KEY_RELEASED),
1158 GetRewrittenEventAsString(
1159 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_RELEASED));
1160 // Check that Control is no longer applied to a subsequent key press.
1161 EXPECT_EQ(
1162 GetExpectedResultAsString(ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED),
1163 GetRewrittenEventAsString(
1164 &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
1166 *base::CommandLine::ForCurrentProcess() = original_cl;
1169 TEST_F(EventRewriterTest, TestRewriteCapsLockToControl) {
1170 // Remap CapsLock to Control.
1171 TestingPrefServiceSyncable prefs;
1172 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1173 IntegerPrefMember control;
1174 control.Init(prefs::kLanguageRemapCapsLockKeyTo, &prefs);
1175 control.SetValue(chromeos::input_method::kControlKey);
1177 EventRewriter rewriter(NULL);
1178 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
1179 rewriter.set_pref_service_for_testing(&prefs);
1181 KeyTestCase tests[] = {
1182 // Press CapsLock+a. Confirm that Mod3Mask is rewritten to ControlMask.
1183 // On Chrome OS, CapsLock works as a Mod3 modifier.
1184 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1185 {ui::VKEY_A, ui::EF_MOD3_DOWN},
1186 {ui::VKEY_A, ui::EF_CONTROL_DOWN}},
1188 // Press Control+CapsLock+a. Confirm that Mod3Mask is rewritten to
1189 // ControlMask
1190 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1191 {ui::VKEY_A, ui::EF_CONTROL_DOWN | ui::EF_MOD3_DOWN},
1192 {ui::VKEY_A, ui::EF_CONTROL_DOWN}},
1194 // Press Alt+CapsLock+a. Confirm that Mod3Mask is rewritten to
1195 // ControlMask.
1196 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1197 {ui::VKEY_A, ui::EF_ALT_DOWN | ui::EF_MOD3_DOWN},
1198 {ui::VKEY_A, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN}},
1201 for (size_t i = 0; i < arraysize(tests); ++i) {
1202 SCOPED_TRACE(i);
1203 CheckKeyTestCase(&rewriter, tests[i]);
1207 TEST_F(EventRewriterTest, TestRewriteCapsLockMod3InUse) {
1208 // Remap CapsLock to Control.
1209 TestingPrefServiceSyncable prefs;
1210 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1211 IntegerPrefMember control;
1212 control.Init(prefs::kLanguageRemapCapsLockKeyTo, &prefs);
1213 control.SetValue(chromeos::input_method::kControlKey);
1215 EventRewriter rewriter(NULL);
1216 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
1217 rewriter.set_pref_service_for_testing(&prefs);
1218 input_method_manager_mock_->set_mod3_used(true);
1220 // Press CapsLock+a. Confirm that Mod3Mask is NOT rewritten to ControlMask
1221 // when Mod3Mask is already in use by the current XKB layout.
1222 EXPECT_EQ(
1223 GetExpectedResultAsString(ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED),
1224 GetRewrittenEventAsString(
1225 &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
1227 input_method_manager_mock_->set_mod3_used(false);
1230 TEST_F(EventRewriterTest, TestRewriteExtendedKeys) {
1231 TestingPrefServiceSyncable prefs;
1232 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1233 EventRewriter rewriter(NULL);
1234 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
1235 rewriter.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId);
1236 rewriter.set_pref_service_for_testing(&prefs);
1238 KeyTestCase tests[] = {
1239 // Alt+Backspace -> Delete
1240 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1241 {ui::VKEY_BACK, ui::EF_ALT_DOWN},
1242 {ui::VKEY_DELETE, ui::EF_NONE}},
1243 // Control+Alt+Backspace -> Control+Delete
1244 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1245 {ui::VKEY_BACK, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN},
1246 {ui::VKEY_DELETE, ui::EF_CONTROL_DOWN}},
1247 // Search+Alt+Backspace -> Alt+Backspace
1248 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1249 {ui::VKEY_BACK, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN},
1250 {ui::VKEY_BACK, ui::EF_ALT_DOWN}},
1251 // Search+Control+Alt+Backspace -> Control+Alt+Backspace
1252 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1253 {ui::VKEY_BACK,
1254 ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN},
1255 {ui::VKEY_BACK, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN}},
1256 // Alt+Up -> Prior
1257 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1258 {ui::VKEY_UP, ui::EF_ALT_DOWN},
1259 {ui::VKEY_PRIOR, ui::EF_NONE}},
1260 // Alt+Down -> Next
1261 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1262 {ui::VKEY_DOWN, ui::EF_ALT_DOWN},
1263 {ui::VKEY_NEXT, ui::EF_NONE}},
1264 // Ctrl+Alt+Up -> Home
1265 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1266 {ui::VKEY_UP, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN},
1267 {ui::VKEY_HOME, ui::EF_NONE}},
1268 // Ctrl+Alt+Down -> End
1269 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1270 {ui::VKEY_DOWN, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN},
1271 {ui::VKEY_END, ui::EF_NONE}},
1273 // Search+Alt+Up -> Alt+Up
1274 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1275 {ui::VKEY_UP, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN},
1276 {ui::VKEY_UP, ui::EF_ALT_DOWN}},
1277 // Search+Alt+Down -> Alt+Down
1278 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1279 {ui::VKEY_DOWN, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN},
1280 {ui::VKEY_DOWN, ui::EF_ALT_DOWN}},
1281 // Search+Ctrl+Alt+Up -> Search+Ctrl+Alt+Up
1282 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1283 {ui::VKEY_UP,
1284 ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN},
1285 {ui::VKEY_UP, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN}},
1286 // Search+Ctrl+Alt+Down -> Ctrl+Alt+Down
1287 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1288 {ui::VKEY_DOWN,
1289 ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN},
1290 {ui::VKEY_DOWN, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN}},
1292 // Period -> Period
1293 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1294 {ui::VKEY_OEM_PERIOD, ui::EF_NONE},
1295 {ui::VKEY_OEM_PERIOD, ui::EF_NONE}},
1297 // Search+Backspace -> Delete
1298 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1299 {ui::VKEY_BACK, ui::EF_COMMAND_DOWN},
1300 {ui::VKEY_DELETE, ui::EF_NONE}},
1301 // Search+Up -> Prior
1302 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1303 {ui::VKEY_UP, ui::EF_COMMAND_DOWN},
1304 {ui::VKEY_PRIOR, ui::EF_NONE}},
1305 // Search+Down -> Next
1306 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1307 {ui::VKEY_DOWN, ui::EF_COMMAND_DOWN},
1308 {ui::VKEY_NEXT, ui::EF_NONE}},
1309 // Search+Left -> Home
1310 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1311 {ui::VKEY_LEFT, ui::EF_COMMAND_DOWN},
1312 {ui::VKEY_HOME, ui::EF_NONE}},
1313 // Control+Search+Left -> Home
1314 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1315 {ui::VKEY_LEFT, ui::EF_COMMAND_DOWN | ui::EF_CONTROL_DOWN},
1316 {ui::VKEY_HOME, ui::EF_CONTROL_DOWN}},
1317 // Search+Right -> End
1318 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1319 {ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN},
1320 {ui::VKEY_END, ui::EF_NONE}},
1321 // Control+Search+Right -> End
1322 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1323 {ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN | ui::EF_CONTROL_DOWN},
1324 {ui::VKEY_END, ui::EF_CONTROL_DOWN}},
1325 // Search+Period -> Insert
1326 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1327 {ui::VKEY_OEM_PERIOD, ui::EF_COMMAND_DOWN},
1328 {ui::VKEY_INSERT, ui::EF_NONE}},
1329 // Control+Search+Period -> Control+Insert
1330 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1331 {ui::VKEY_OEM_PERIOD, ui::EF_COMMAND_DOWN | ui::EF_CONTROL_DOWN},
1332 {ui::VKEY_INSERT, ui::EF_CONTROL_DOWN}}};
1334 for (size_t i = 0; i < arraysize(tests); ++i) {
1335 SCOPED_TRACE(i);
1336 CheckKeyTestCase(&rewriter, tests[i]);
1340 TEST_F(EventRewriterTest, TestRewriteFunctionKeys) {
1341 TestingPrefServiceSyncable prefs;
1342 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1343 EventRewriter rewriter(NULL);
1344 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
1345 rewriter.set_pref_service_for_testing(&prefs);
1347 FunctionKeyTestCase tests[] = {
1348 // F1 -> Back
1349 {ui::ET_KEY_PRESSED,
1350 {ui::VKEY_F1, ui::EF_NONE},
1351 {ui::VKEY_BROWSER_BACK, ui::EF_NONE},
1352 {ui::VKEY_BROWSER_BACK, ui::EF_FUNCTION_KEY}},
1353 {ui::ET_KEY_PRESSED,
1354 {ui::VKEY_F1, ui::EF_CONTROL_DOWN},
1355 {ui::VKEY_BROWSER_BACK, ui::EF_CONTROL_DOWN},
1356 {ui::VKEY_BROWSER_BACK, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1357 {ui::ET_KEY_PRESSED,
1358 {ui::VKEY_F1, ui::EF_ALT_DOWN},
1359 {ui::VKEY_BROWSER_BACK, ui::EF_ALT_DOWN},
1360 {ui::VKEY_BROWSER_BACK, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1361 // F2 -> Forward
1362 {ui::ET_KEY_PRESSED,
1363 {ui::VKEY_F2, ui::EF_NONE},
1364 {ui::VKEY_BROWSER_FORWARD, ui::EF_NONE},
1365 {ui::VKEY_BROWSER_FORWARD, ui::EF_FUNCTION_KEY}},
1366 {ui::ET_KEY_PRESSED,
1367 {ui::VKEY_F2, ui::EF_CONTROL_DOWN},
1368 {ui::VKEY_BROWSER_FORWARD, ui::EF_CONTROL_DOWN},
1369 {ui::VKEY_BROWSER_FORWARD, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1370 {ui::ET_KEY_PRESSED,
1371 {ui::VKEY_F2, ui::EF_ALT_DOWN},
1372 {ui::VKEY_BROWSER_FORWARD, ui::EF_ALT_DOWN},
1373 {ui::VKEY_BROWSER_FORWARD, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1374 // F3 -> Refresh
1375 {ui::ET_KEY_PRESSED,
1376 {ui::VKEY_F3, ui::EF_NONE},
1377 {ui::VKEY_BROWSER_REFRESH, ui::EF_NONE},
1378 {ui::VKEY_BROWSER_REFRESH, ui::EF_FUNCTION_KEY}},
1379 {ui::ET_KEY_PRESSED,
1380 {ui::VKEY_F3, ui::EF_CONTROL_DOWN},
1381 {ui::VKEY_BROWSER_REFRESH, ui::EF_CONTROL_DOWN},
1382 {ui::VKEY_BROWSER_REFRESH, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1383 {ui::ET_KEY_PRESSED,
1384 {ui::VKEY_F3, ui::EF_ALT_DOWN},
1385 {ui::VKEY_BROWSER_REFRESH, ui::EF_ALT_DOWN},
1386 {ui::VKEY_BROWSER_REFRESH, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1387 // F4 -> Launch App 2
1388 {ui::ET_KEY_PRESSED,
1389 {ui::VKEY_F4, ui::EF_NONE},
1390 {ui::VKEY_MEDIA_LAUNCH_APP2, ui::EF_NONE},
1391 {ui::VKEY_MEDIA_LAUNCH_APP2, ui::EF_FUNCTION_KEY}},
1392 {ui::ET_KEY_PRESSED,
1393 {ui::VKEY_F4, ui::EF_CONTROL_DOWN},
1394 {ui::VKEY_MEDIA_LAUNCH_APP2, ui::EF_CONTROL_DOWN},
1395 {ui::VKEY_MEDIA_LAUNCH_APP2, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1396 {ui::ET_KEY_PRESSED,
1397 {ui::VKEY_F4, ui::EF_ALT_DOWN},
1398 {ui::VKEY_MEDIA_LAUNCH_APP2, ui::EF_ALT_DOWN},
1399 {ui::VKEY_MEDIA_LAUNCH_APP2, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1400 // F5 -> Launch App 1
1401 {ui::ET_KEY_PRESSED,
1402 {ui::VKEY_F5, ui::EF_NONE},
1403 {ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_NONE},
1404 {ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_FUNCTION_KEY}},
1405 {ui::ET_KEY_PRESSED,
1406 {ui::VKEY_F5, ui::EF_CONTROL_DOWN},
1407 {ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN},
1408 {ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1409 {ui::ET_KEY_PRESSED,
1410 {ui::VKEY_F5, ui::EF_ALT_DOWN},
1411 {ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_ALT_DOWN},
1412 {ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1413 // F6 -> Brightness down
1414 {ui::ET_KEY_PRESSED,
1415 {ui::VKEY_F6, ui::EF_NONE},
1416 {ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE},
1417 {ui::VKEY_BRIGHTNESS_DOWN, ui::EF_FUNCTION_KEY}},
1418 {ui::ET_KEY_PRESSED,
1419 {ui::VKEY_F6, ui::EF_CONTROL_DOWN},
1420 {ui::VKEY_BRIGHTNESS_DOWN, ui::EF_CONTROL_DOWN},
1421 {ui::VKEY_BRIGHTNESS_DOWN, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1422 {ui::ET_KEY_PRESSED,
1423 {ui::VKEY_F6, ui::EF_ALT_DOWN},
1424 {ui::VKEY_BRIGHTNESS_DOWN, ui::EF_ALT_DOWN},
1425 {ui::VKEY_BRIGHTNESS_DOWN, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1426 // F7 -> Brightness up
1427 {ui::ET_KEY_PRESSED,
1428 {ui::VKEY_F7, ui::EF_NONE},
1429 {ui::VKEY_BRIGHTNESS_UP, ui::EF_NONE},
1430 {ui::VKEY_BRIGHTNESS_UP, ui::EF_FUNCTION_KEY}},
1431 {ui::ET_KEY_PRESSED,
1432 {ui::VKEY_F7, ui::EF_CONTROL_DOWN},
1433 {ui::VKEY_BRIGHTNESS_UP, ui::EF_CONTROL_DOWN},
1434 {ui::VKEY_BRIGHTNESS_UP, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1435 {ui::ET_KEY_PRESSED,
1436 {ui::VKEY_F7, ui::EF_ALT_DOWN},
1437 {ui::VKEY_BRIGHTNESS_UP, ui::EF_ALT_DOWN},
1438 {ui::VKEY_BRIGHTNESS_UP, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1439 // F8 -> Volume Mute
1440 {ui::ET_KEY_PRESSED,
1441 {ui::VKEY_F8, ui::EF_NONE},
1442 {ui::VKEY_VOLUME_MUTE, ui::EF_NONE},
1443 {ui::VKEY_VOLUME_MUTE, ui::EF_FUNCTION_KEY}},
1444 {ui::ET_KEY_PRESSED,
1445 {ui::VKEY_F8, ui::EF_CONTROL_DOWN},
1446 {ui::VKEY_VOLUME_MUTE, ui::EF_CONTROL_DOWN},
1447 {ui::VKEY_VOLUME_MUTE, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1448 {ui::ET_KEY_PRESSED,
1449 {ui::VKEY_F8, ui::EF_ALT_DOWN},
1450 {ui::VKEY_VOLUME_MUTE, ui::EF_ALT_DOWN},
1451 {ui::VKEY_VOLUME_MUTE, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1452 // F9 -> Volume Down
1453 {ui::ET_KEY_PRESSED,
1454 {ui::VKEY_F9, ui::EF_NONE},
1455 {ui::VKEY_VOLUME_DOWN, ui::EF_NONE},
1456 {ui::VKEY_VOLUME_DOWN, ui::EF_FUNCTION_KEY}},
1457 {ui::ET_KEY_PRESSED,
1458 {ui::VKEY_F9, ui::EF_CONTROL_DOWN},
1459 {ui::VKEY_VOLUME_DOWN, ui::EF_CONTROL_DOWN},
1460 {ui::VKEY_VOLUME_DOWN, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1461 {ui::ET_KEY_PRESSED,
1462 {ui::VKEY_F9, ui::EF_ALT_DOWN},
1463 {ui::VKEY_VOLUME_DOWN, ui::EF_ALT_DOWN},
1464 {ui::VKEY_VOLUME_DOWN, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1465 // F10 -> Volume Up
1466 {ui::ET_KEY_PRESSED,
1467 {ui::VKEY_F10, ui::EF_NONE},
1468 {ui::VKEY_VOLUME_UP, ui::EF_NONE},
1469 {ui::VKEY_VOLUME_UP, ui::EF_FUNCTION_KEY}},
1470 {ui::ET_KEY_PRESSED,
1471 {ui::VKEY_F10, ui::EF_CONTROL_DOWN},
1472 {ui::VKEY_VOLUME_UP, ui::EF_CONTROL_DOWN},
1473 {ui::VKEY_VOLUME_UP, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1474 {ui::ET_KEY_PRESSED,
1475 {ui::VKEY_F10, ui::EF_ALT_DOWN},
1476 {ui::VKEY_VOLUME_UP, ui::EF_ALT_DOWN},
1477 {ui::VKEY_VOLUME_UP, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1478 // F11 -> F11
1479 {ui::ET_KEY_PRESSED,
1480 {ui::VKEY_F11, ui::EF_NONE},
1481 {ui::VKEY_F11, ui::EF_NONE},
1482 {ui::VKEY_F11, ui::EF_FUNCTION_KEY}},
1483 {ui::ET_KEY_PRESSED,
1484 {ui::VKEY_F11, ui::EF_CONTROL_DOWN},
1485 {ui::VKEY_F11, ui::EF_CONTROL_DOWN},
1486 {ui::VKEY_F11, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1487 {ui::ET_KEY_PRESSED,
1488 {ui::VKEY_F11, ui::EF_ALT_DOWN},
1489 {ui::VKEY_F11, ui::EF_ALT_DOWN},
1490 {ui::VKEY_F11, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1491 // F12 -> F12
1492 {ui::ET_KEY_PRESSED,
1493 {ui::VKEY_F12, ui::EF_NONE},
1494 {ui::VKEY_F12, ui::EF_NONE},
1495 {ui::VKEY_F12, ui::EF_FUNCTION_KEY}},
1496 {ui::ET_KEY_PRESSED,
1497 {ui::VKEY_F12, ui::EF_CONTROL_DOWN},
1498 {ui::VKEY_F12, ui::EF_CONTROL_DOWN},
1499 {ui::VKEY_F12, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1500 {ui::ET_KEY_PRESSED,
1501 {ui::VKEY_F12, ui::EF_ALT_DOWN},
1502 {ui::VKEY_F12, ui::EF_ALT_DOWN},
1503 {ui::VKEY_F12, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1505 // The number row should not be rewritten without Search key.
1506 {ui::ET_KEY_PRESSED,
1507 {ui::VKEY_1, ui::EF_NONE},
1508 {ui::VKEY_1, ui::EF_NONE},
1509 {ui::VKEY_1, ui::EF_NONE}},
1510 {ui::ET_KEY_PRESSED,
1511 {ui::VKEY_2, ui::EF_NONE},
1512 {ui::VKEY_2, ui::EF_NONE},
1513 {ui::VKEY_2, ui::EF_NONE}},
1514 {ui::ET_KEY_PRESSED,
1515 {ui::VKEY_3, ui::EF_NONE},
1516 {ui::VKEY_3, ui::EF_NONE},
1517 {ui::VKEY_3, ui::EF_NONE}},
1518 {ui::ET_KEY_PRESSED,
1519 {ui::VKEY_4, ui::EF_NONE},
1520 {ui::VKEY_4, ui::EF_NONE},
1521 {ui::VKEY_4, ui::EF_NONE}},
1522 {ui::ET_KEY_PRESSED,
1523 {ui::VKEY_5, ui::EF_NONE},
1524 {ui::VKEY_5, ui::EF_NONE},
1525 {ui::VKEY_5, ui::EF_NONE}},
1526 {ui::ET_KEY_PRESSED,
1527 {ui::VKEY_6, ui::EF_NONE},
1528 {ui::VKEY_6, ui::EF_NONE},
1529 {ui::VKEY_6, ui::EF_NONE}},
1530 {ui::ET_KEY_PRESSED,
1531 {ui::VKEY_7, ui::EF_NONE},
1532 {ui::VKEY_7, ui::EF_NONE},
1533 {ui::VKEY_7, ui::EF_NONE}},
1534 {ui::ET_KEY_PRESSED,
1535 {ui::VKEY_8, ui::EF_NONE},
1536 {ui::VKEY_8, ui::EF_NONE},
1537 {ui::VKEY_8, ui::EF_NONE}},
1538 {ui::ET_KEY_PRESSED,
1539 {ui::VKEY_9, ui::EF_NONE},
1540 {ui::VKEY_9, ui::EF_NONE},
1541 {ui::VKEY_9, ui::EF_NONE}},
1542 {ui::ET_KEY_PRESSED,
1543 {ui::VKEY_0, ui::EF_NONE},
1544 {ui::VKEY_0, ui::EF_NONE},
1545 {ui::VKEY_0, ui::EF_NONE}},
1546 {ui::ET_KEY_PRESSED,
1547 {ui::VKEY_OEM_MINUS, ui::EF_NONE},
1548 {ui::VKEY_OEM_MINUS, ui::EF_NONE},
1549 {ui::VKEY_OEM_MINUS, ui::EF_NONE}},
1550 {ui::ET_KEY_PRESSED,
1551 {ui::VKEY_OEM_PLUS, ui::EF_NONE},
1552 {ui::VKEY_OEM_PLUS, ui::EF_NONE},
1553 {ui::VKEY_OEM_PLUS, ui::EF_NONE}},
1555 // The number row should be rewritten as the F<number> row with Search
1556 // key.
1557 {ui::ET_KEY_PRESSED,
1558 {ui::VKEY_1, ui::EF_COMMAND_DOWN},
1559 {ui::VKEY_F1, ui::EF_NONE},
1560 {ui::VKEY_F1, ui::EF_NONE}},
1561 {ui::ET_KEY_PRESSED,
1562 {ui::VKEY_2, ui::EF_COMMAND_DOWN},
1563 {ui::VKEY_F2, ui::EF_NONE},
1564 {ui::VKEY_F2, ui::EF_NONE}},
1565 {ui::ET_KEY_PRESSED,
1566 {ui::VKEY_3, ui::EF_COMMAND_DOWN},
1567 {ui::VKEY_F3, ui::EF_NONE},
1568 {ui::VKEY_F3, ui::EF_NONE}},
1569 {ui::ET_KEY_PRESSED,
1570 {ui::VKEY_4, ui::EF_COMMAND_DOWN},
1571 {ui::VKEY_F4, ui::EF_NONE},
1572 {ui::VKEY_F4, ui::EF_NONE}},
1573 {ui::ET_KEY_PRESSED,
1574 {ui::VKEY_5, ui::EF_COMMAND_DOWN},
1575 {ui::VKEY_F5, ui::EF_NONE},
1576 {ui::VKEY_F5, ui::EF_NONE}},
1577 {ui::ET_KEY_PRESSED,
1578 {ui::VKEY_6, ui::EF_COMMAND_DOWN},
1579 {ui::VKEY_F6, ui::EF_NONE},
1580 {ui::VKEY_F6, ui::EF_NONE}},
1581 {ui::ET_KEY_PRESSED,
1582 {ui::VKEY_7, ui::EF_COMMAND_DOWN},
1583 {ui::VKEY_F7, ui::EF_NONE},
1584 {ui::VKEY_F7, ui::EF_NONE}},
1585 {ui::ET_KEY_PRESSED,
1586 {ui::VKEY_8, ui::EF_COMMAND_DOWN},
1587 {ui::VKEY_F8, ui::EF_NONE},
1588 {ui::VKEY_F8, ui::EF_NONE}},
1589 {ui::ET_KEY_PRESSED,
1590 {ui::VKEY_9, ui::EF_COMMAND_DOWN},
1591 {ui::VKEY_F9, ui::EF_NONE},
1592 {ui::VKEY_F9, ui::EF_NONE}},
1593 {ui::ET_KEY_PRESSED,
1594 {ui::VKEY_0, ui::EF_COMMAND_DOWN},
1595 {ui::VKEY_F10, ui::EF_NONE},
1596 {ui::VKEY_F10, ui::EF_NONE}},
1597 {ui::ET_KEY_PRESSED,
1598 {ui::VKEY_OEM_MINUS, ui::EF_COMMAND_DOWN},
1599 {ui::VKEY_F11, ui::EF_NONE},
1600 {ui::VKEY_F11, ui::EF_NONE}},
1601 {ui::ET_KEY_PRESSED,
1602 {ui::VKEY_OEM_PLUS, ui::EF_COMMAND_DOWN},
1603 {ui::VKEY_F12, ui::EF_NONE},
1604 {ui::VKEY_F12, ui::EF_NONE}},
1606 // The function keys should not be rewritten with Search key pressed.
1607 {ui::ET_KEY_PRESSED,
1608 {ui::VKEY_F1, ui::EF_COMMAND_DOWN},
1609 {ui::VKEY_F1, ui::EF_NONE},
1610 {ui::VKEY_F1, ui::EF_FUNCTION_KEY}},
1611 {ui::ET_KEY_PRESSED,
1612 {ui::VKEY_F2, ui::EF_COMMAND_DOWN},
1613 {ui::VKEY_F2, ui::EF_NONE},
1614 {ui::VKEY_F2, ui::EF_FUNCTION_KEY}},
1615 {ui::ET_KEY_PRESSED,
1616 {ui::VKEY_F3, ui::EF_COMMAND_DOWN},
1617 {ui::VKEY_F3, ui::EF_NONE},
1618 {ui::VKEY_F3, ui::EF_FUNCTION_KEY}},
1619 {ui::ET_KEY_PRESSED,
1620 {ui::VKEY_F4, ui::EF_COMMAND_DOWN},
1621 {ui::VKEY_F4, ui::EF_NONE},
1622 {ui::VKEY_F4, ui::EF_FUNCTION_KEY}},
1623 {ui::ET_KEY_PRESSED,
1624 {ui::VKEY_F5, ui::EF_COMMAND_DOWN},
1625 {ui::VKEY_F5, ui::EF_NONE},
1626 {ui::VKEY_F5, ui::EF_FUNCTION_KEY}},
1627 {ui::ET_KEY_PRESSED,
1628 {ui::VKEY_F6, ui::EF_COMMAND_DOWN},
1629 {ui::VKEY_F6, ui::EF_NONE},
1630 {ui::VKEY_F6, ui::EF_FUNCTION_KEY}},
1631 {ui::ET_KEY_PRESSED,
1632 {ui::VKEY_F7, ui::EF_COMMAND_DOWN},
1633 {ui::VKEY_F7, ui::EF_NONE},
1634 {ui::VKEY_F7, ui::EF_FUNCTION_KEY}},
1635 {ui::ET_KEY_PRESSED,
1636 {ui::VKEY_F8, ui::EF_COMMAND_DOWN},
1637 {ui::VKEY_F8, ui::EF_NONE},
1638 {ui::VKEY_F8, ui::EF_FUNCTION_KEY}},
1639 {ui::ET_KEY_PRESSED,
1640 {ui::VKEY_F9, ui::EF_COMMAND_DOWN},
1641 {ui::VKEY_F9, ui::EF_NONE},
1642 {ui::VKEY_F9, ui::EF_FUNCTION_KEY}},
1643 {ui::ET_KEY_PRESSED,
1644 {ui::VKEY_F10, ui::EF_COMMAND_DOWN},
1645 {ui::VKEY_F10, ui::EF_NONE},
1646 {ui::VKEY_F10, ui::EF_FUNCTION_KEY}},
1647 {ui::ET_KEY_PRESSED,
1648 {ui::VKEY_F11, ui::EF_COMMAND_DOWN},
1649 {ui::VKEY_F11, ui::EF_NONE},
1650 {ui::VKEY_F11, ui::EF_FUNCTION_KEY}},
1651 {ui::ET_KEY_PRESSED,
1652 {ui::VKEY_F12, ui::EF_COMMAND_DOWN},
1653 {ui::VKEY_F12, ui::EF_NONE},
1654 {ui::VKEY_F12, ui::EF_FUNCTION_KEY}},
1657 for (size_t i = 0; i < arraysize(tests); ++i) {
1658 SCOPED_TRACE(i);
1659 CheckFunctionKeyTestCase(&rewriter, tests[i]);
1663 TEST_F(EventRewriterTest, TestRewriteExtendedKeysWithSearchRemapped) {
1664 const base::CommandLine original_cl(*base::CommandLine::ForCurrentProcess());
1666 // Remap Search to Control.
1667 TestingPrefServiceSyncable prefs;
1668 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1669 IntegerPrefMember search;
1670 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
1671 search.SetValue(chromeos::input_method::kControlKey);
1673 EventRewriter rewriter(NULL);
1674 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
1675 rewriter.set_pref_service_for_testing(&prefs);
1677 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1678 chromeos::switches::kHasChromeOSKeyboard, "");
1680 KeyTestCase tests[] = {
1681 // Alt+Search+Down -> End
1682 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1683 {ui::VKEY_DOWN, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN},
1684 {ui::VKEY_END, ui::EF_NONE}},
1686 // Shift+Alt+Search+Down -> Shift+End
1687 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1688 {ui::VKEY_DOWN,
1689 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN},
1690 {ui::VKEY_END, ui::EF_SHIFT_DOWN}},
1693 for (size_t i = 0; i < arraysize(tests); ++i) {
1694 SCOPED_TRACE(i);
1695 CheckKeyTestCase(&rewriter, tests[i]);
1698 *base::CommandLine::ForCurrentProcess() = original_cl;
1701 TEST_F(EventRewriterTest, TestRewriteKeyEventSentByXSendEvent) {
1702 // Remap Control to Alt.
1703 TestingPrefServiceSyncable prefs;
1704 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1705 IntegerPrefMember control;
1706 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
1707 control.SetValue(chromeos::input_method::kAltKey);
1709 EventRewriter rewriter(NULL);
1710 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
1711 rewriter.set_pref_service_for_testing(&prefs);
1713 // Send left control press.
1715 ui::KeyEvent keyevent(
1716 ui::ET_KEY_PRESSED, ui::VKEY_CONTROL, ui::EF_FINAL);
1717 scoped_ptr<ui::Event> new_event;
1718 // Control should NOT be remapped to Alt if EF_FINAL is set.
1719 EXPECT_EQ(ui::EVENT_REWRITE_CONTINUE,
1720 rewriter.RewriteEvent(keyevent, &new_event));
1721 EXPECT_FALSE(new_event);
1723 #if defined(USE_X11)
1724 // Send left control press, using XI2 native events.
1726 ui::ScopedXI2Event xev;
1727 xev.InitKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_CONTROL, 0);
1728 XEvent* xevent = xev;
1729 xevent->xkey.keycode = XKeysymToKeycode(gfx::GetXDisplay(), XK_Control_L);
1730 xevent->xkey.send_event = True; // XSendEvent() always does this.
1731 ui::KeyEvent keyevent(xev);
1732 scoped_ptr<ui::Event> new_event;
1733 // Control should NOT be remapped to Alt if send_event
1734 // flag in the event is True.
1735 EXPECT_EQ(ui::EVENT_REWRITE_CONTINUE,
1736 rewriter.RewriteEvent(keyevent, &new_event));
1737 EXPECT_FALSE(new_event);
1739 #endif
1742 TEST_F(EventRewriterTest, TestRewriteNonNativeEvent) {
1743 // Remap Control to Alt.
1744 TestingPrefServiceSyncable prefs;
1745 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1746 IntegerPrefMember control;
1747 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
1748 control.SetValue(chromeos::input_method::kAltKey);
1750 EventRewriter rewriter(NULL);
1751 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
1752 rewriter.set_pref_service_for_testing(&prefs);
1754 const int kTouchId = 2;
1755 gfx::Point location(0, 0);
1756 ui::TouchEvent press(
1757 ui::ET_TOUCH_PRESSED, location, kTouchId, base::TimeDelta());
1758 press.set_flags(ui::EF_CONTROL_DOWN);
1759 #if defined(USE_X11)
1760 ui::UpdateX11EventForFlags(&press);
1761 #endif
1763 scoped_ptr<ui::Event> new_event;
1764 rewriter.RewriteEvent(press, &new_event);
1765 EXPECT_TRUE(new_event);
1766 // Control should be remapped to Alt.
1767 EXPECT_EQ(ui::EF_ALT_DOWN,
1768 new_event->flags() & (ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN));
1771 // Keeps a buffer of handled events.
1772 class EventBuffer : public ui::test::TestEventProcessor {
1773 public:
1774 EventBuffer() {}
1775 ~EventBuffer() override {}
1777 void PopEvents(ScopedVector<ui::Event>* events) {
1778 events->clear();
1779 events->swap(events_);
1782 private:
1783 // ui::EventProcessor overrides:
1784 ui::EventDispatchDetails OnEventFromSource(ui::Event* event) override {
1785 if (event->IsKeyEvent()) {
1786 events_.push_back(new ui::KeyEvent(*static_cast<ui::KeyEvent*>(event)));
1787 } else if (event->IsMouseWheelEvent()) {
1788 events_.push_back(
1789 new ui::MouseWheelEvent(*static_cast<ui::MouseWheelEvent*>(event)));
1790 } else if (event->IsMouseEvent()) {
1791 events_.push_back(
1792 new ui::MouseEvent(*static_cast<ui::MouseEvent*>(event)));
1794 return ui::EventDispatchDetails();
1797 ScopedVector<ui::Event> events_;
1799 DISALLOW_COPY_AND_ASSIGN(EventBuffer);
1802 // Trivial EventSource that does nothing but send events.
1803 class TestEventSource : public ui::EventSource {
1804 public:
1805 explicit TestEventSource(ui::EventProcessor* processor)
1806 : processor_(processor) {}
1807 ui::EventProcessor* GetEventProcessor() override { return processor_; }
1808 ui::EventDispatchDetails Send(ui::Event* event) {
1809 return SendEventToProcessor(event);
1812 private:
1813 ui::EventProcessor* processor_;
1816 // Tests of event rewriting that depend on the Ash window manager.
1817 class EventRewriterAshTest : public ash::test::AshTestBase {
1818 public:
1819 EventRewriterAshTest()
1820 : source_(&buffer_),
1821 fake_user_manager_(new user_manager::FakeUserManager),
1822 user_manager_enabler_(fake_user_manager_) {}
1823 ~EventRewriterAshTest() override {}
1825 bool RewriteFunctionKeys(const ui::Event& event,
1826 scoped_ptr<ui::Event>* rewritten_event) {
1827 return rewriter_->RewriteEvent(event, rewritten_event);
1830 ui::EventDispatchDetails Send(ui::Event* event) {
1831 return source_.Send(event);
1834 void SendKeyEvent(ui::EventType type, ui::KeyboardCode key_code) {
1835 ui::KeyEvent press(type, key_code, ui::EF_NONE);
1836 ui::EventDispatchDetails details = Send(&press);
1837 CHECK(!details.dispatcher_destroyed);
1840 void SendActivateStickyKeyPattern(ui::KeyboardCode key_code) {
1841 SendKeyEvent(ui::ET_KEY_PRESSED, key_code);
1842 SendKeyEvent(ui::ET_KEY_RELEASED, key_code);
1845 protected:
1846 TestingPrefServiceSyncable* prefs() { return &prefs_; }
1848 void PopEvents(ScopedVector<ui::Event>* events) {
1849 buffer_.PopEvents(events);
1852 void SetUp() override {
1853 AshTestBase::SetUp();
1854 sticky_keys_controller_ =
1855 ash::Shell::GetInstance()->sticky_keys_controller();
1856 rewriter_.reset(new EventRewriter(sticky_keys_controller_));
1857 chromeos::Preferences::RegisterProfilePrefs(prefs_.registry());
1858 rewriter_->set_pref_service_for_testing(&prefs_);
1859 #if defined(USE_X11)
1860 ui::SetUpTouchPadForTest(kTouchPadDeviceId);
1861 #endif
1862 source_.AddEventRewriter(rewriter_.get());
1863 sticky_keys_controller_->Enable(true);
1866 void TearDown() override {
1867 rewriter_.reset();
1868 AshTestBase::TearDown();
1871 protected:
1872 ash::StickyKeysController* sticky_keys_controller_;
1874 private:
1875 scoped_ptr<EventRewriter> rewriter_;
1877 EventBuffer buffer_;
1878 TestEventSource source_;
1880 user_manager::FakeUserManager* fake_user_manager_; // Not owned.
1881 chromeos::ScopedUserManagerEnabler user_manager_enabler_;
1882 TestingPrefServiceSyncable prefs_;
1884 DISALLOW_COPY_AND_ASSIGN(EventRewriterAshTest);
1887 TEST_F(EventRewriterAshTest, TopRowKeysAreFunctionKeys) {
1888 scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(1));
1889 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window.get());
1890 window_state->Activate();
1891 ScopedVector<ui::Event> events;
1893 // Create a simulated keypress of F1 targetted at the window.
1894 ui::KeyEvent press_f1(ui::ET_KEY_PRESSED, ui::VKEY_F1, ui::EF_NONE);
1896 // Simulate an apps v2 window that has requested top row keys as function
1897 // keys. The event should not be rewritten.
1898 window_state->set_top_row_keys_are_function_keys(true);
1899 ui::EventDispatchDetails details = Send(&press_f1);
1900 ASSERT_FALSE(details.dispatcher_destroyed);
1901 PopEvents(&events);
1902 EXPECT_EQ(1u, events.size());
1903 EXPECT_EQ(
1904 GetExpectedResultAsString(ui::VKEY_F1, ui::EF_NONE, ui::ET_KEY_PRESSED),
1905 GetKeyEventAsString(*static_cast<ui::KeyEvent*>(events[0])));
1907 // The event should also not be rewritten if the send-function-keys pref is
1908 // additionally set, for both apps v2 and regular windows.
1909 BooleanPrefMember send_function_keys_pref;
1910 send_function_keys_pref.Init(prefs::kLanguageSendFunctionKeys, prefs());
1911 send_function_keys_pref.SetValue(true);
1912 window_state->set_top_row_keys_are_function_keys(false);
1913 details = Send(&press_f1);
1914 ASSERT_FALSE(details.dispatcher_destroyed);
1915 PopEvents(&events);
1916 EXPECT_EQ(1u, events.size());
1917 EXPECT_EQ(
1918 GetExpectedResultAsString(ui::VKEY_F1, ui::EF_NONE, ui::ET_KEY_PRESSED),
1919 GetKeyEventAsString(*static_cast<ui::KeyEvent*>(events[0])));
1921 // If the pref isn't set when an event is sent to a regular window, F1 is
1922 // rewritten to the back key.
1923 send_function_keys_pref.SetValue(false);
1924 details = Send(&press_f1);
1925 ASSERT_FALSE(details.dispatcher_destroyed);
1926 PopEvents(&events);
1927 EXPECT_EQ(1u, events.size());
1928 EXPECT_EQ(GetExpectedResultAsString(
1929 ui::VKEY_BROWSER_BACK, ui::EF_NONE, ui::ET_KEY_PRESSED),
1930 GetKeyEventAsString(*static_cast<ui::KeyEvent*>(events[0])));
1933 TEST_F(EventRewriterTest, TestRewrittenModifierClick) {
1934 std::vector<unsigned int> device_list;
1935 device_list.push_back(10);
1936 ui::TouchFactory::GetInstance()->SetPointerDeviceForTest(device_list);
1938 // Remap Control to Alt.
1939 TestingPrefServiceSyncable prefs;
1940 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1941 IntegerPrefMember control;
1942 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
1943 control.SetValue(chromeos::input_method::kAltKey);
1945 EventRewriter rewriter(NULL);
1946 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
1947 rewriter.set_pref_service_for_testing(&prefs);
1949 // Check that Control + Left Button is converted (via Alt + Left Button)
1950 // to Right Button.
1951 ui::ScopedXI2Event xev;
1952 xev.InitGenericButtonEvent(10,
1953 ui::ET_MOUSE_PRESSED,
1954 gfx::Point(),
1955 ui::EF_LEFT_MOUSE_BUTTON | ui::EF_CONTROL_DOWN);
1956 ui::MouseEvent press(xev);
1957 // Sanity check.
1958 EXPECT_EQ(ui::ET_MOUSE_PRESSED, press.type());
1959 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON | ui::EF_CONTROL_DOWN, press.flags());
1960 scoped_ptr<ui::Event> new_event;
1961 const ui::MouseEvent* result =
1962 RewriteMouseButtonEvent(&rewriter, press, &new_event);
1963 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & result->flags());
1964 EXPECT_FALSE(ui::EF_LEFT_MOUSE_BUTTON & result->flags());
1965 EXPECT_FALSE(ui::EF_CONTROL_DOWN & result->flags());
1966 EXPECT_FALSE(ui::EF_ALT_DOWN & result->flags());
1967 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & result->flags());
1970 TEST_F(EventRewriterTest, DontRewriteIfNotRewritten) {
1971 // TODO(kpschoedel): pending changes for crbug.com/360377
1972 // to |chromeos::EventRewriter::RewriteLocatedEvent()
1973 std::vector<unsigned int> device_list;
1974 device_list.push_back(10);
1975 device_list.push_back(11);
1976 ui::TouchFactory::GetInstance()->SetPointerDeviceForTest(device_list);
1977 TestingPrefServiceSyncable prefs;
1978 EventRewriter rewriter(NULL);
1979 rewriter.set_pref_service_for_testing(&prefs);
1980 const int kLeftAndAltFlag = ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN;
1982 // Test Alt + Left click.
1984 ui::MouseEvent press(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
1985 ui::EventTimeForNow(), kLeftAndAltFlag,
1986 ui::EF_LEFT_MOUSE_BUTTON);
1987 ui::EventTestApi test_press(&press);
1988 test_press.set_source_device_id(10);
1989 // Sanity check.
1990 EXPECT_EQ(ui::ET_MOUSE_PRESSED, press.type());
1991 EXPECT_EQ(kLeftAndAltFlag, press.flags());
1992 scoped_ptr<ui::Event> new_event;
1993 const ui::MouseEvent* result =
1994 RewriteMouseButtonEvent(&rewriter, press, &new_event);
1995 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & result->flags());
1996 EXPECT_FALSE(kLeftAndAltFlag & result->flags());
1997 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, result->changed_button_flags());
2000 ui::MouseEvent release(ui::ET_MOUSE_RELEASED, gfx::Point(), gfx::Point(),
2001 ui::EventTimeForNow(), kLeftAndAltFlag,
2002 ui::EF_LEFT_MOUSE_BUTTON);
2003 ui::EventTestApi test_release(&release);
2004 test_release.set_source_device_id(10);
2005 scoped_ptr<ui::Event> new_event;
2006 const ui::MouseEvent* result =
2007 RewriteMouseButtonEvent(&rewriter, release, &new_event);
2008 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & result->flags());
2009 EXPECT_FALSE(kLeftAndAltFlag & result->flags());
2010 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, result->changed_button_flags());
2012 #if defined(USE_X11)
2013 // Test Alt + Left click, using XI2 native events.
2015 ui::ScopedXI2Event xev;
2016 xev.InitGenericButtonEvent(
2017 10, ui::ET_MOUSE_PRESSED, gfx::Point(), kLeftAndAltFlag);
2018 ui::MouseEvent press(xev);
2019 // Sanity check.
2020 EXPECT_EQ(ui::ET_MOUSE_PRESSED, press.type());
2021 EXPECT_EQ(kLeftAndAltFlag, press.flags());
2022 scoped_ptr<ui::Event> new_event;
2023 const ui::MouseEvent* result =
2024 RewriteMouseButtonEvent(&rewriter, press, &new_event);
2025 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & result->flags());
2026 EXPECT_FALSE(kLeftAndAltFlag & result->flags());
2027 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, result->changed_button_flags());
2030 ui::ScopedXI2Event xev;
2031 xev.InitGenericButtonEvent(
2032 10, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
2033 ui::MouseEvent release(xev);
2034 scoped_ptr<ui::Event> new_event;
2035 const ui::MouseEvent* result =
2036 RewriteMouseButtonEvent(&rewriter, release, &new_event);
2037 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & result->flags());
2038 EXPECT_FALSE(kLeftAndAltFlag & result->flags());
2039 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, result->changed_button_flags());
2041 #endif
2043 // No ALT in frst click.
2045 ui::MouseEvent press(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
2046 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
2047 ui::EF_LEFT_MOUSE_BUTTON);
2048 ui::EventTestApi test_press(&press);
2049 test_press.set_source_device_id(10);
2050 scoped_ptr<ui::Event> new_event;
2051 const ui::MouseEvent* result =
2052 RewriteMouseButtonEvent(&rewriter, press, &new_event);
2053 EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & result->flags());
2054 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, result->changed_button_flags());
2057 ui::MouseEvent release(ui::ET_MOUSE_RELEASED, gfx::Point(), gfx::Point(),
2058 ui::EventTimeForNow(), kLeftAndAltFlag,
2059 ui::EF_LEFT_MOUSE_BUTTON);
2060 ui::EventTestApi test_release(&release);
2061 test_release.set_source_device_id(10);
2062 scoped_ptr<ui::Event> new_event;
2063 const ui::MouseEvent* result =
2064 RewriteMouseButtonEvent(&rewriter, release, &new_event);
2065 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN) & result->flags());
2066 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, result->changed_button_flags());
2068 #if defined(USE_X11)
2069 // No ALT in frst click, using XI2 native events.
2071 ui::ScopedXI2Event xev;
2072 xev.InitGenericButtonEvent(
2073 10, ui::ET_MOUSE_PRESSED, gfx::Point(), ui::EF_LEFT_MOUSE_BUTTON);
2074 ui::MouseEvent press(xev);
2075 scoped_ptr<ui::Event> new_event;
2076 const ui::MouseEvent* result =
2077 RewriteMouseButtonEvent(&rewriter, press, &new_event);
2078 EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & result->flags());
2079 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, result->changed_button_flags());
2082 ui::ScopedXI2Event xev;
2083 xev.InitGenericButtonEvent(
2084 10, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
2085 ui::MouseEvent release(xev);
2086 scoped_ptr<ui::Event> new_event;
2087 const ui::MouseEvent* result =
2088 RewriteMouseButtonEvent(&rewriter, release, &new_event);
2089 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN) & result->flags());
2090 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, result->changed_button_flags());
2092 #endif
2094 // ALT on different device.
2096 ui::MouseEvent press(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
2097 ui::EventTimeForNow(), kLeftAndAltFlag,
2098 ui::EF_LEFT_MOUSE_BUTTON);
2099 ui::EventTestApi test_press(&press);
2100 test_press.set_source_device_id(11);
2101 scoped_ptr<ui::Event> new_event;
2102 const ui::MouseEvent* result =
2103 RewriteMouseButtonEvent(&rewriter, press, &new_event);
2104 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & result->flags());
2105 EXPECT_FALSE(kLeftAndAltFlag & result->flags());
2106 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, result->changed_button_flags());
2109 ui::MouseEvent release(ui::ET_MOUSE_RELEASED, gfx::Point(), gfx::Point(),
2110 ui::EventTimeForNow(), kLeftAndAltFlag,
2111 ui::EF_LEFT_MOUSE_BUTTON);
2112 ui::EventTestApi test_release(&release);
2113 test_release.set_source_device_id(10);
2114 scoped_ptr<ui::Event> new_event;
2115 const ui::MouseEvent* result =
2116 RewriteMouseButtonEvent(&rewriter, release, &new_event);
2117 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN) & result->flags());
2118 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, result->changed_button_flags());
2121 ui::MouseEvent release(ui::ET_MOUSE_RELEASED, gfx::Point(), gfx::Point(),
2122 ui::EventTimeForNow(), kLeftAndAltFlag,
2123 ui::EF_LEFT_MOUSE_BUTTON);
2124 ui::EventTestApi test_release(&release);
2125 test_release.set_source_device_id(11);
2126 scoped_ptr<ui::Event> new_event;
2127 const ui::MouseEvent* result =
2128 RewriteMouseButtonEvent(&rewriter, release, &new_event);
2129 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & result->flags());
2130 EXPECT_FALSE(kLeftAndAltFlag & result->flags());
2131 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, result->changed_button_flags());
2133 #if defined(USE_X11)
2134 // ALT on different device, using XI2 native events.
2136 ui::ScopedXI2Event xev;
2137 xev.InitGenericButtonEvent(
2138 11, ui::ET_MOUSE_PRESSED, gfx::Point(), kLeftAndAltFlag);
2139 ui::MouseEvent press(xev);
2140 scoped_ptr<ui::Event> new_event;
2141 const ui::MouseEvent* result =
2142 RewriteMouseButtonEvent(&rewriter, press, &new_event);
2143 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & result->flags());
2144 EXPECT_FALSE(kLeftAndAltFlag & result->flags());
2145 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, result->changed_button_flags());
2148 ui::ScopedXI2Event xev;
2149 xev.InitGenericButtonEvent(
2150 10, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
2151 ui::MouseEvent release(xev);
2152 scoped_ptr<ui::Event> new_event;
2153 const ui::MouseEvent* result =
2154 RewriteMouseButtonEvent(&rewriter, release, &new_event);
2155 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN) & result->flags());
2156 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, result->changed_button_flags());
2159 ui::ScopedXI2Event xev;
2160 xev.InitGenericButtonEvent(
2161 11, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
2162 ui::MouseEvent release(xev);
2163 scoped_ptr<ui::Event> new_event;
2164 const ui::MouseEvent* result =
2165 RewriteMouseButtonEvent(&rewriter, release, &new_event);
2166 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & result->flags());
2167 EXPECT_FALSE(kLeftAndAltFlag & result->flags());
2168 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, result->changed_button_flags());
2170 #endif
2173 TEST_F(EventRewriterAshTest, StickyKeyEventDispatchImpl) {
2174 // Test the actual key event dispatch implementation.
2175 ScopedVector<ui::Event> events;
2177 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2178 PopEvents(&events);
2179 EXPECT_EQ(1u, events.size());
2180 EXPECT_EQ(ui::ET_KEY_PRESSED, events[0]->type());
2181 EXPECT_EQ(ui::VKEY_CONTROL,
2182 static_cast<ui::KeyEvent*>(events[0])->key_code());
2184 // Test key press event is correctly modified and modifier release
2185 // event is sent.
2186 ui::KeyEvent press(ui::ET_KEY_PRESSED, ui::VKEY_C, ui::EF_NONE);
2187 ui::EventDispatchDetails details = Send(&press);
2188 PopEvents(&events);
2189 EXPECT_EQ(2u, events.size());
2190 EXPECT_EQ(ui::ET_KEY_PRESSED, events[0]->type());
2191 EXPECT_EQ(ui::VKEY_C, static_cast<ui::KeyEvent*>(events[0])->key_code());
2192 EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
2193 EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type());
2194 EXPECT_EQ(ui::VKEY_CONTROL,
2195 static_cast<ui::KeyEvent*>(events[1])->key_code());
2197 // Test key release event is not modified.
2198 ui::KeyEvent release(ui::ET_KEY_RELEASED, ui::VKEY_C, ui::EF_NONE);
2199 details = Send(&release);
2200 ASSERT_FALSE(details.dispatcher_destroyed);
2201 PopEvents(&events);
2202 EXPECT_EQ(1u, events.size());
2203 EXPECT_EQ(ui::ET_KEY_RELEASED, events[0]->type());
2204 EXPECT_EQ(ui::VKEY_C, static_cast<ui::KeyEvent*>(events[0])->key_code());
2205 EXPECT_FALSE(events[0]->flags() & ui::EF_CONTROL_DOWN);
2208 TEST_F(EventRewriterAshTest, MouseEventDispatchImpl) {
2209 ScopedVector<ui::Event> events;
2211 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2212 PopEvents(&events);
2214 // Test mouse press event is correctly modified.
2215 gfx::Point location(0, 0);
2216 ui::MouseEvent press(ui::ET_MOUSE_PRESSED, location, location,
2217 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
2218 ui::EF_LEFT_MOUSE_BUTTON);
2219 ui::EventDispatchDetails details = Send(&press);
2220 ASSERT_FALSE(details.dispatcher_destroyed);
2221 PopEvents(&events);
2222 EXPECT_EQ(1u, events.size());
2223 EXPECT_EQ(ui::ET_MOUSE_PRESSED, events[0]->type());
2224 EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
2226 // Test mouse release event is correctly modified and modifier release
2227 // event is sent. The mouse event should have the correct DIP location.
2228 ui::MouseEvent release(ui::ET_MOUSE_RELEASED, location, location,
2229 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
2230 ui::EF_LEFT_MOUSE_BUTTON);
2231 details = Send(&release);
2232 ASSERT_FALSE(details.dispatcher_destroyed);
2233 PopEvents(&events);
2234 EXPECT_EQ(2u, events.size());
2235 EXPECT_EQ(ui::ET_MOUSE_RELEASED, events[0]->type());
2236 EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
2237 EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type());
2238 EXPECT_EQ(ui::VKEY_CONTROL,
2239 static_cast<ui::KeyEvent*>(events[1])->key_code());
2242 TEST_F(EventRewriterAshTest, MouseWheelEventDispatchImpl) {
2243 ScopedVector<ui::Event> events;
2245 // Test positive mouse wheel event is correctly modified and modifier release
2246 // event is sent.
2247 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2248 PopEvents(&events);
2249 gfx::Point location(0, 0);
2250 ui::MouseEvent mev(ui::ET_MOUSEWHEEL, location, location,
2251 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
2252 ui::EF_LEFT_MOUSE_BUTTON);
2253 ui::MouseWheelEvent positive(mev, 0, ui::MouseWheelEvent::kWheelDelta);
2254 ui::EventDispatchDetails details = Send(&positive);
2255 ASSERT_FALSE(details.dispatcher_destroyed);
2256 PopEvents(&events);
2257 EXPECT_EQ(2u, events.size());
2258 EXPECT_TRUE(events[0]->IsMouseWheelEvent());
2259 EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
2260 EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type());
2261 EXPECT_EQ(ui::VKEY_CONTROL,
2262 static_cast<ui::KeyEvent*>(events[1])->key_code());
2264 // Test negative mouse wheel event is correctly modified and modifier release
2265 // event is sent.
2266 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2267 PopEvents(&events);
2268 ui::MouseWheelEvent negative(mev, 0, -ui::MouseWheelEvent::kWheelDelta);
2269 details = Send(&negative);
2270 ASSERT_FALSE(details.dispatcher_destroyed);
2271 PopEvents(&events);
2272 EXPECT_EQ(2u, events.size());
2273 EXPECT_TRUE(events[0]->IsMouseWheelEvent());
2274 EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
2275 EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type());
2276 EXPECT_EQ(ui::VKEY_CONTROL,
2277 static_cast<ui::KeyEvent*>(events[1])->key_code());
2280 class StickyKeysOverlayTest : public EventRewriterAshTest {
2281 public:
2282 StickyKeysOverlayTest() : overlay_(NULL) {}
2284 ~StickyKeysOverlayTest() override {}
2286 void SetUp() override {
2287 EventRewriterAshTest::SetUp();
2288 overlay_ = sticky_keys_controller_->GetOverlayForTest();
2289 ASSERT_TRUE(overlay_);
2292 ash::StickyKeysOverlay* overlay_;
2295 TEST_F(StickyKeysOverlayTest, OneModifierEnabled) {
2296 EXPECT_FALSE(overlay_->is_visible());
2297 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2298 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2300 // Pressing modifier key should show overlay.
2301 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2302 EXPECT_TRUE(overlay_->is_visible());
2303 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED,
2304 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2306 // Pressing a normal key should hide overlay.
2307 SendActivateStickyKeyPattern(ui::VKEY_T);
2308 EXPECT_FALSE(overlay_->is_visible());
2309 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2310 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2313 TEST_F(StickyKeysOverlayTest, TwoModifiersEnabled) {
2314 EXPECT_FALSE(overlay_->is_visible());
2315 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2316 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2317 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2318 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
2320 // Pressing two modifiers should show overlay.
2321 SendActivateStickyKeyPattern(ui::VKEY_SHIFT);
2322 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2323 EXPECT_TRUE(overlay_->is_visible());
2324 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED,
2325 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
2326 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED,
2327 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2329 // Pressing a normal key should hide overlay.
2330 SendActivateStickyKeyPattern(ui::VKEY_N);
2331 EXPECT_FALSE(overlay_->is_visible());
2332 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2333 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2334 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2335 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
2338 TEST_F(StickyKeysOverlayTest, LockedModifier) {
2339 EXPECT_FALSE(overlay_->is_visible());
2340 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2341 overlay_->GetModifierKeyState(ui::EF_ALT_DOWN));
2343 // Pressing a modifier key twice should lock modifier and show overlay.
2344 SendActivateStickyKeyPattern(ui::VKEY_LMENU);
2345 SendActivateStickyKeyPattern(ui::VKEY_LMENU);
2346 EXPECT_TRUE(overlay_->is_visible());
2347 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED,
2348 overlay_->GetModifierKeyState(ui::EF_ALT_DOWN));
2350 // Pressing a normal key should not hide overlay.
2351 SendActivateStickyKeyPattern(ui::VKEY_D);
2352 EXPECT_TRUE(overlay_->is_visible());
2353 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED,
2354 overlay_->GetModifierKeyState(ui::EF_ALT_DOWN));
2357 TEST_F(StickyKeysOverlayTest, LockedAndNormalModifier) {
2358 EXPECT_FALSE(overlay_->is_visible());
2359 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2360 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2361 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2362 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
2364 // Pressing a modifier key twice should lock modifier and show overlay.
2365 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2366 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2367 EXPECT_TRUE(overlay_->is_visible());
2368 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED,
2369 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2371 // Pressing another modifier key should still show overlay.
2372 SendActivateStickyKeyPattern(ui::VKEY_SHIFT);
2373 EXPECT_TRUE(overlay_->is_visible());
2374 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED,
2375 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2376 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED,
2377 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
2379 // Pressing a normal key should not hide overlay but disable normal modifier.
2380 SendActivateStickyKeyPattern(ui::VKEY_D);
2381 EXPECT_TRUE(overlay_->is_visible());
2382 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED,
2383 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2384 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2385 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
2388 TEST_F(StickyKeysOverlayTest, ModifiersDisabled) {
2389 EXPECT_FALSE(overlay_->is_visible());
2390 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2391 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2392 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2393 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
2394 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2395 overlay_->GetModifierKeyState(ui::EF_ALT_DOWN));
2396 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2397 overlay_->GetModifierKeyState(ui::EF_COMMAND_DOWN));
2399 // Enable modifiers.
2400 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2401 SendActivateStickyKeyPattern(ui::VKEY_SHIFT);
2402 SendActivateStickyKeyPattern(ui::VKEY_SHIFT);
2403 SendActivateStickyKeyPattern(ui::VKEY_LMENU);
2404 SendActivateStickyKeyPattern(ui::VKEY_COMMAND);
2405 SendActivateStickyKeyPattern(ui::VKEY_COMMAND);
2407 EXPECT_TRUE(overlay_->is_visible());
2408 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED,
2409 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2410 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED,
2411 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
2412 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED,
2413 overlay_->GetModifierKeyState(ui::EF_ALT_DOWN));
2414 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED,
2415 overlay_->GetModifierKeyState(ui::EF_COMMAND_DOWN));
2417 // Disable modifiers and overlay should be hidden.
2418 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2419 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2420 SendActivateStickyKeyPattern(ui::VKEY_SHIFT);
2421 SendActivateStickyKeyPattern(ui::VKEY_LMENU);
2422 SendActivateStickyKeyPattern(ui::VKEY_LMENU);
2423 SendActivateStickyKeyPattern(ui::VKEY_COMMAND);
2425 EXPECT_FALSE(overlay_->is_visible());
2426 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2427 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2428 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2429 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
2430 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2431 overlay_->GetModifierKeyState(ui::EF_ALT_DOWN));
2432 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2433 overlay_->GetModifierKeyState(ui::EF_COMMAND_DOWN));
2436 TEST_F(StickyKeysOverlayTest, ModifierVisibility) {
2437 // All but AltGr and Mod3 should initially be visible.
2438 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_CONTROL_DOWN));
2439 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_SHIFT_DOWN));
2440 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_ALT_DOWN));
2441 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_COMMAND_DOWN));
2442 EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_ALTGR_DOWN));
2443 EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_MOD3_DOWN));
2445 // Turn all modifiers on.
2446 sticky_keys_controller_->SetModifiersEnabled(true, true);
2447 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_CONTROL_DOWN));
2448 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_SHIFT_DOWN));
2449 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_ALT_DOWN));
2450 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_COMMAND_DOWN));
2451 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_ALTGR_DOWN));
2452 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_MOD3_DOWN));
2454 // Turn off Mod3.
2455 sticky_keys_controller_->SetModifiersEnabled(false, true);
2456 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_ALTGR_DOWN));
2457 EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_MOD3_DOWN));
2459 // Turn off AltGr.
2460 sticky_keys_controller_->SetModifiersEnabled(true, false);
2461 EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_ALTGR_DOWN));
2462 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_MOD3_DOWN));
2464 // Turn off AltGr and Mod3.
2465 sticky_keys_controller_->SetModifiersEnabled(false, false);
2466 EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_ALTGR_DOWN));
2467 EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_MOD3_DOWN));
2470 } // namespace chromeos