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"
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/fake_user_manager.h"
21 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
22 #include "chrome/browser/chromeos/preferences.h"
23 #include "chrome/common/pref_names.h"
24 #include "chrome/test/base/testing_pref_service_syncable.h"
25 #include "chromeos/chromeos_switches.h"
26 #include "chromeos/ime/fake_ime_keyboard.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "ui/aura/window.h"
29 #include "ui/aura/window_tree_host.h"
30 #include "ui/events/event.h"
31 #include "ui/events/event_rewriter.h"
32 #include "ui/events/test/events_test_utils.h"
33 #include "ui/events/test/test_event_processor.h"
36 #include <X11/keysym.h>
38 #include "ui/events/devices/x11/touch_factory_x11.h"
39 #include "ui/events/event_utils.h"
40 #include "ui/events/test/events_test_utils_x11.h"
41 #include "ui/gfx/x/x11_types.h"
46 // The device id of the test touchpad device.
47 const unsigned int kTouchPadDeviceId = 1;
48 const int kKeyboardDeviceId = 2;
49 const int kMasterKeyboardDeviceId = 3;
51 std::string GetExpectedResultAsString(ui::KeyboardCode ui_keycode,
53 ui::EventType ui_type) {
54 return base::StringPrintf("ui_keycode=0x%X ui_flags=0x%X ui_type=%d",
56 ui_flags & ~ui::EF_IS_REPEAT,
60 std::string GetKeyEventAsString(const ui::KeyEvent& keyevent) {
61 return GetExpectedResultAsString(
62 keyevent.key_code(), keyevent.flags(), keyevent.type());
65 std::string GetRewrittenEventAsString(chromeos::EventRewriter* rewriter,
66 ui::KeyboardCode ui_keycode,
68 ui::EventType ui_type) {
69 const ui::KeyEvent event(ui_type, ui_keycode, ui_flags);
70 scoped_ptr<ui::Event> new_event;
71 rewriter->RewriteEvent(event, &new_event);
73 return GetKeyEventAsString(
74 static_cast<const ui::KeyEvent&>(*new_event.get()));
75 return GetKeyEventAsString(event);
78 // Table entry for simple single key event rewriting tests.
82 TEST_VKEY = 1 << 0, // Test ui::KeyEvent with no native event
83 TEST_X11 = 1 << 1, // Test ui::KeyEvent with native XKeyEvent
84 TEST_ALL = TEST_VKEY|TEST_X11,
85 // Special test flags:
86 NUMPAD = 1 << 8, // Set EF_NUMPAD_KEY on native-based event, because
87 // |XKeysymForWindowsKeyCode()| can not distinguish
88 // between pairs like XK_Insert and XK_KP_Insert.
93 ui::KeyboardCode key_code;
99 // Check rewriting of an X11-based key event.
100 void CheckX11KeyTestCase(const std::string& expected,
101 chromeos::EventRewriter* rewriter,
102 const KeyTestCase& test,
104 ui::KeyEvent xkey_event(xevent);
105 if (test.test & KeyTestCase::NUMPAD)
106 xkey_event.set_flags(xkey_event.flags() | ui::EF_NUMPAD_KEY);
107 // Verify that the X11-based key event is as expected.
108 EXPECT_EQ(GetExpectedResultAsString(
109 test.input.key_code, test.input.flags, test.type),
110 GetKeyEventAsString(xkey_event));
111 // Rewrite the event and check the result.
112 scoped_ptr<ui::Event> new_event;
113 rewriter->RewriteEvent(xkey_event, &new_event);
114 ui::KeyEvent& rewritten_key_event =
115 new_event ? *static_cast<ui::KeyEvent*>(new_event.get()) : xkey_event;
116 EXPECT_EQ(expected, GetKeyEventAsString(rewritten_key_event));
117 if ((rewritten_key_event.key_code() != ui::VKEY_UNKNOWN) &&
118 (rewritten_key_event.native_event()->xkey.keycode != 0)) {
119 // Build a new ui::KeyEvent from the rewritten native component,
120 // and check that it also matches the rewritten event.
121 EXPECT_TRUE(rewritten_key_event.native_event());
122 ui::KeyEvent from_native_event(rewritten_key_event.native_event());
123 EXPECT_EQ(expected, GetKeyEventAsString(from_native_event));
128 // Tests a single stateless key rewrite operation.
129 // |i| is a an identifying number to locate failing tests in the tables.
130 void CheckKeyTestCase(chromeos::EventRewriter* rewriter,
131 const KeyTestCase& test) {
132 std::string expected =
133 GetExpectedResultAsString(
134 test.expected.key_code, test.expected.flags, test.type);
136 if (test.test & KeyTestCase::TEST_VKEY) {
137 // Check rewriting of a non-native-based key event.
140 GetRewrittenEventAsString(
141 rewriter, test.input.key_code, test.input.flags, test.type));
145 if (test.test & KeyTestCase::TEST_X11) {
146 ui::ScopedXI2Event xev;
147 // Test an XKeyEvent.
148 xev.InitKeyEvent(test.type, test.input.key_code, test.input.flags);
149 XEvent* xevent = xev;
150 DCHECK((xevent->type == KeyPress) || (xevent->type == KeyRelease));
151 if (xevent->xkey.keycode)
152 CheckX11KeyTestCase(expected, rewriter, test, xevent);
153 // Test an XI2 GenericEvent.
154 xev.InitGenericKeyEvent(kMasterKeyboardDeviceId,
160 DCHECK(xevent->type == GenericEvent);
161 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xevent->xcookie.data);
162 DCHECK((xievent->evtype == XI_KeyPress) ||
163 (xievent->evtype == XI_KeyRelease));
165 CheckX11KeyTestCase(expected, rewriter, test, xevent);
170 // Table entry for simple single function key event rewriting tests.
171 struct FunctionKeyTestCase {
174 ui::KeyboardCode key_code;
176 } input, vkey_expected, native_expected;
179 // Tests a single stateless function key rewrite operation.
180 // |i| is a an identifying number to locate failing tests in the tables.
181 // Function key mapping differs from the other key mappings because the
182 // EF_FUNCTION_KEY flag is set during ui::KeyEvent construction when passing in
183 // a native X11 event and the flag is not set when using other constructors.
184 void CheckFunctionKeyTestCase(chromeos::EventRewriter* rewriter,
185 const FunctionKeyTestCase& test) {
186 std::string vkey_expected =
187 GetExpectedResultAsString(
188 test.vkey_expected.key_code,
189 test.vkey_expected.flags,
191 // Check rewriting of a non-native-based key event.
194 GetRewrittenEventAsString(
195 rewriter, test.input.key_code, test.input.flags, test.type));
198 ui::ScopedXI2Event xev;
199 xev.InitKeyEvent(test.type, test.input.key_code, test.input.flags);
200 XEvent* xevent = xev;
201 if (xevent->xkey.keycode) {
202 ui::KeyEvent xkey_event(xevent);
203 // Rewrite the event and check the result.
204 scoped_ptr<ui::Event> new_event;
205 rewriter->RewriteEvent(xkey_event, &new_event);
206 ui::KeyEvent& rewritten_key_event =
207 new_event ? *static_cast<ui::KeyEvent*>(new_event.get()) : xkey_event;
208 std::string native_expected =
209 GetExpectedResultAsString(
210 test.native_expected.key_code,
211 test.native_expected.flags,
213 EXPECT_EQ(native_expected, GetKeyEventAsString(rewritten_key_event));
222 class EventRewriterTest : public ash::test::AshTestBase {
225 : fake_user_manager_(new chromeos::FakeUserManager),
226 user_manager_enabler_(fake_user_manager_),
227 input_method_manager_mock_(NULL) {}
228 virtual ~EventRewriterTest() {}
230 virtual void SetUp() {
231 input_method_manager_mock_ =
232 new chromeos::input_method::MockInputMethodManager;
233 chromeos::input_method::InitializeForTesting(
234 input_method_manager_mock_); // pass ownership
236 AshTestBase::SetUp();
239 virtual void TearDown() {
240 AshTestBase::TearDown();
241 // Shutdown() deletes the IME mock object.
242 chromeos::input_method::Shutdown();
246 void TestRewriteNumPadKeys();
247 void TestRewriteNumPadKeysOnAppleKeyboard();
249 const ui::MouseEvent* RewriteMouseButtonEvent(
250 chromeos::EventRewriter* rewriter,
251 const ui::MouseEvent& event,
252 scoped_ptr<ui::Event>* new_event) {
253 rewriter->RewriteMouseButtonEventForTesting(event, new_event);
254 return *new_event ? static_cast<const ui::MouseEvent*>(new_event->get())
258 chromeos::FakeUserManager* fake_user_manager_; // Not owned.
259 chromeos::ScopedUserManagerEnabler user_manager_enabler_;
260 chromeos::input_method::MockInputMethodManager* input_method_manager_mock_;
263 TEST_F(EventRewriterTest, TestRewriteCommandToControl) {
264 // First, test with a PC keyboard.
265 TestingPrefServiceSyncable prefs;
266 EventRewriter rewriter(NULL);
267 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
268 rewriter.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId);
269 rewriter.set_pref_service_for_testing(&prefs);
271 KeyTestCase pc_keyboard_tests[] = {
272 // VKEY_A, Alt modifier.
273 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
274 {ui::VKEY_A, ui::EF_ALT_DOWN},
275 {ui::VKEY_A, ui::EF_ALT_DOWN}},
277 // VKEY_A, Win modifier.
278 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
279 {ui::VKEY_A, ui::EF_COMMAND_DOWN},
280 {ui::VKEY_A, ui::EF_COMMAND_DOWN}},
282 // VKEY_A, Alt+Win modifier.
283 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
284 {ui::VKEY_A, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN},
285 {ui::VKEY_A, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN}},
287 // VKEY_LWIN (left Windows key), Alt modifier.
288 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
289 {ui::VKEY_LWIN, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN},
290 {ui::VKEY_LWIN, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN}},
292 // VKEY_RWIN (right Windows key), Alt modifier.
293 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
294 {ui::VKEY_RWIN, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN},
295 {ui::VKEY_RWIN, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN}},
298 for (size_t i = 0; i < arraysize(pc_keyboard_tests); ++i) {
300 CheckKeyTestCase(&rewriter, pc_keyboard_tests[i]);
303 // An Apple keyboard reusing the ID, zero.
304 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "Apple Keyboard");
305 rewriter.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId);
307 KeyTestCase apple_keyboard_tests[] = {
308 // VKEY_A, Alt modifier.
309 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
310 {ui::VKEY_A, ui::EF_ALT_DOWN},
311 {ui::VKEY_A, ui::EF_ALT_DOWN}},
313 // VKEY_A, Win modifier.
314 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
315 {ui::VKEY_A, ui::EF_COMMAND_DOWN},
316 {ui::VKEY_A, ui::EF_CONTROL_DOWN}},
318 // VKEY_A, Alt+Win modifier.
319 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
320 {ui::VKEY_A, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN},
321 {ui::VKEY_A, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN}},
323 // VKEY_LWIN (left Windows key), Alt modifier.
324 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
325 {ui::VKEY_LWIN, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN},
326 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN}},
328 // VKEY_RWIN (right Windows key), Alt modifier.
329 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
330 {ui::VKEY_RWIN, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN},
331 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN}},
334 for (size_t i = 0; i < arraysize(apple_keyboard_tests); ++i) {
336 CheckKeyTestCase(&rewriter, apple_keyboard_tests[i]);
340 // For crbug.com/133896.
341 TEST_F(EventRewriterTest, TestRewriteCommandToControlWithControlRemapped) {
342 // Remap Control to Alt.
343 TestingPrefServiceSyncable prefs;
344 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
345 IntegerPrefMember control;
346 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
347 control.SetValue(chromeos::input_method::kAltKey);
349 EventRewriter rewriter(NULL);
350 rewriter.set_pref_service_for_testing(&prefs);
351 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
352 rewriter.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId);
354 KeyTestCase pc_keyboard_tests[] = {// Control should be remapped to Alt.
355 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
356 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN},
357 {ui::VKEY_MENU, ui::EF_ALT_DOWN}},
360 for (size_t i = 0; i < arraysize(pc_keyboard_tests); ++i) {
362 CheckKeyTestCase(&rewriter, pc_keyboard_tests[i]);
365 // An Apple keyboard reusing the ID, zero.
366 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "Apple Keyboard");
367 rewriter.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId);
369 KeyTestCase apple_keyboard_tests[] = {
370 // VKEY_LWIN (left Command key) with Alt modifier. The remapped Command
371 // key should never be re-remapped to Alt.
372 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
373 {ui::VKEY_LWIN, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN},
374 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN}},
376 // VKEY_RWIN (right Command key) with Alt modifier. The remapped Command
377 // key should never be re-remapped to Alt.
378 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
379 {ui::VKEY_RWIN, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN},
380 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN}},
383 for (size_t i = 0; i < arraysize(apple_keyboard_tests); ++i) {
385 CheckKeyTestCase(&rewriter, apple_keyboard_tests[i]);
389 void EventRewriterTest::TestRewriteNumPadKeys() {
390 TestingPrefServiceSyncable prefs;
391 EventRewriter rewriter(NULL);
392 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
393 rewriter.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId);
394 rewriter.set_pref_service_for_testing(&prefs);
396 KeyTestCase tests[] = {
397 // XK_KP_Insert (= NumPad 0 without Num Lock), no modifier.
398 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
399 {ui::VKEY_INSERT, ui::EF_NUMPAD_KEY},
400 {ui::VKEY_NUMPAD0, ui::EF_NUMPAD_KEY}},
402 // XK_KP_Insert (= NumPad 0 without Num Lock), Alt modifier.
403 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
404 {ui::VKEY_INSERT, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY},
405 {ui::VKEY_NUMPAD0, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY}},
407 // XK_KP_Delete (= NumPad . without Num Lock), Alt modifier.
408 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
409 {ui::VKEY_DELETE, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY},
410 {ui::VKEY_DECIMAL, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY}},
412 // XK_KP_End (= NumPad 1 without Num Lock), Alt modifier.
413 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
414 {ui::VKEY_END, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY},
415 {ui::VKEY_NUMPAD1, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY}},
417 // XK_KP_Down (= NumPad 2 without Num Lock), Alt modifier.
418 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
419 {ui::VKEY_DOWN, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY},
420 {ui::VKEY_NUMPAD2, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY}},
422 // XK_KP_Next (= NumPad 3 without Num Lock), Alt modifier.
423 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
424 {ui::VKEY_NEXT, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY},
425 {ui::VKEY_NUMPAD3, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY}},
427 // XK_KP_Left (= NumPad 4 without Num Lock), Alt modifier.
428 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
429 {ui::VKEY_LEFT, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY},
430 {ui::VKEY_NUMPAD4, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY}},
432 // XK_KP_Begin (= NumPad 5 without Num Lock), Alt modifier.
433 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
434 {ui::VKEY_CLEAR, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY},
435 {ui::VKEY_NUMPAD5, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY}},
437 // XK_KP_Right (= NumPad 6 without Num Lock), Alt modifier.
438 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
439 {ui::VKEY_RIGHT, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY},
440 {ui::VKEY_NUMPAD6, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY}},
442 // XK_KP_Home (= NumPad 7 without Num Lock), Alt modifier.
443 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
444 {ui::VKEY_HOME, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY},
445 {ui::VKEY_NUMPAD7, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY}},
447 // XK_KP_Up (= NumPad 8 without Num Lock), Alt modifier.
448 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
449 {ui::VKEY_UP, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY},
450 {ui::VKEY_NUMPAD8, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY}},
452 // XK_KP_Prior (= NumPad 9 without Num Lock), Alt modifier.
453 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
454 {ui::VKEY_PRIOR, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY},
455 {ui::VKEY_NUMPAD9, ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY}},
457 // XK_KP_0 (= NumPad 0 with Num Lock), Num Lock modifier.
458 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
459 {ui::VKEY_NUMPAD0, ui::EF_NUMPAD_KEY},
460 {ui::VKEY_NUMPAD0, ui::EF_NUMPAD_KEY}},
462 // XK_KP_DECIMAL (= NumPad . with Num Lock), Num Lock modifier.
463 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
464 {ui::VKEY_DECIMAL, ui::EF_NUMPAD_KEY},
465 {ui::VKEY_DECIMAL, ui::EF_NUMPAD_KEY}},
467 // XK_KP_1 (= NumPad 1 with Num Lock), Num Lock modifier.
468 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
469 {ui::VKEY_NUMPAD1, ui::EF_NUMPAD_KEY},
470 {ui::VKEY_NUMPAD1, ui::EF_NUMPAD_KEY}},
472 // XK_KP_2 (= NumPad 2 with Num Lock), Num Lock modifier.
473 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
474 {ui::VKEY_NUMPAD2, ui::EF_NUMPAD_KEY},
475 {ui::VKEY_NUMPAD2, ui::EF_NUMPAD_KEY}},
477 // XK_KP_3 (= NumPad 3 with Num Lock), Num Lock modifier.
478 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
479 {ui::VKEY_NUMPAD3, ui::EF_NUMPAD_KEY},
480 {ui::VKEY_NUMPAD3, ui::EF_NUMPAD_KEY}},
482 // XK_KP_4 (= NumPad 4 with Num Lock), Num Lock modifier.
483 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
484 {ui::VKEY_NUMPAD4, ui::EF_NUMPAD_KEY},
485 {ui::VKEY_NUMPAD4, ui::EF_NUMPAD_KEY}},
487 // XK_KP_5 (= NumPad 5 with Num Lock), Num Lock modifier.
488 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
489 {ui::VKEY_NUMPAD5, ui::EF_NUMPAD_KEY},
490 {ui::VKEY_NUMPAD5, ui::EF_NUMPAD_KEY}},
492 // XK_KP_6 (= NumPad 6 with Num Lock), Num Lock modifier.
493 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
494 {ui::VKEY_NUMPAD6, ui::EF_NUMPAD_KEY},
495 {ui::VKEY_NUMPAD6, ui::EF_NUMPAD_KEY}},
497 // XK_KP_7 (= NumPad 7 with Num Lock), Num Lock modifier.
498 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
499 {ui::VKEY_NUMPAD7, ui::EF_NUMPAD_KEY},
500 {ui::VKEY_NUMPAD7, ui::EF_NUMPAD_KEY}},
502 // XK_KP_8 (= NumPad 8 with Num Lock), Num Lock modifier.
503 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
504 {ui::VKEY_NUMPAD8, ui::EF_NUMPAD_KEY},
505 {ui::VKEY_NUMPAD8, ui::EF_NUMPAD_KEY}},
507 // XK_KP_9 (= NumPad 9 with Num Lock), Num Lock modifier.
508 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
509 {ui::VKEY_NUMPAD9, ui::EF_NUMPAD_KEY},
510 {ui::VKEY_NUMPAD9, ui::EF_NUMPAD_KEY}},
513 for (size_t i = 0; i < arraysize(tests); ++i) {
515 CheckKeyTestCase(&rewriter, tests[i]);
519 TEST_F(EventRewriterTest, TestRewriteNumPadKeys) {
520 TestRewriteNumPadKeys();
523 TEST_F(EventRewriterTest, TestRewriteNumPadKeysWithDiamondKeyFlag) {
524 // Make sure the num lock works correctly even when Diamond key exists.
525 const CommandLine original_cl(*CommandLine::ForCurrentProcess());
526 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
527 chromeos::switches::kHasChromeOSDiamondKey, "");
529 TestRewriteNumPadKeys();
530 *CommandLine::ForCurrentProcess() = original_cl;
533 // Tests if the rewriter can handle a Command + Num Pad event.
534 void EventRewriterTest::TestRewriteNumPadKeysOnAppleKeyboard() {
535 TestingPrefServiceSyncable prefs;
536 EventRewriter rewriter(NULL);
537 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "Apple Keyboard");
538 rewriter.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId);
539 rewriter.set_pref_service_for_testing(&prefs);
541 KeyTestCase tests[] = {
542 // XK_KP_End (= NumPad 1 without Num Lock), Win modifier.
543 // The result should be "Num Pad 1 with Control + Num Lock modifiers".
544 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
545 {ui::VKEY_END, ui::EF_COMMAND_DOWN | ui::EF_NUMPAD_KEY},
546 {ui::VKEY_NUMPAD1, ui::EF_CONTROL_DOWN | ui::EF_NUMPAD_KEY}},
548 // XK_KP_1 (= NumPad 1 with Num Lock), Win modifier.
549 // The result should also be "Num Pad 1 with Control + Num Lock
551 {KeyTestCase::TEST_ALL|KeyTestCase::NUMPAD, ui::ET_KEY_PRESSED,
552 {ui::VKEY_NUMPAD1, ui::EF_COMMAND_DOWN | ui::EF_NUMPAD_KEY},
553 {ui::VKEY_NUMPAD1, ui::EF_CONTROL_DOWN | ui::EF_NUMPAD_KEY}},
556 for (size_t i = 0; i < arraysize(tests); ++i) {
558 CheckKeyTestCase(&rewriter, tests[i]);
562 TEST_F(EventRewriterTest, TestRewriteNumPadKeysOnAppleKeyboard) {
563 TestRewriteNumPadKeysOnAppleKeyboard();
566 TEST_F(EventRewriterTest,
567 TestRewriteNumPadKeysOnAppleKeyboardWithDiamondKeyFlag) {
568 // Makes sure the num lock works correctly even when Diamond key exists.
569 const CommandLine original_cl(*CommandLine::ForCurrentProcess());
570 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
571 chromeos::switches::kHasChromeOSDiamondKey, "");
573 TestRewriteNumPadKeysOnAppleKeyboard();
574 *CommandLine::ForCurrentProcess() = original_cl;
577 TEST_F(EventRewriterTest, TestRewriteModifiersNoRemap) {
578 TestingPrefServiceSyncable prefs;
579 EventRewriter rewriter(NULL);
580 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
581 rewriter.set_pref_service_for_testing(&prefs);
583 KeyTestCase tests[] = {
584 // Press Search. Confirm the event is not rewritten.
585 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
586 {ui::VKEY_LWIN, ui::EF_NONE},
587 {ui::VKEY_LWIN, ui::EF_COMMAND_DOWN}},
589 // Press left Control. Confirm the event is not rewritten.
590 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
591 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN},
592 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN}},
594 // Press right Control. Confirm the event is not rewritten.
595 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
596 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN},
597 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN}},
599 // Press left Alt. Confirm the event is not rewritten.
600 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
601 {ui::VKEY_MENU, ui::EF_ALT_DOWN},
602 {ui::VKEY_MENU, ui::EF_ALT_DOWN}},
604 // Press right Alt. Confirm the event is not rewritten.
605 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
606 {ui::VKEY_MENU, ui::EF_ALT_DOWN},
607 {ui::VKEY_MENU, ui::EF_ALT_DOWN}},
609 // Test KeyRelease event, just in case.
610 // Release Search. Confirm the release event is not rewritten.
611 {KeyTestCase::TEST_ALL, ui::ET_KEY_RELEASED,
612 {ui::VKEY_LWIN, ui::EF_NONE},
613 {ui::VKEY_LWIN, ui::EF_NONE}},
616 for (size_t i = 0; i < arraysize(tests); ++i) {
618 CheckKeyTestCase(&rewriter, tests[i]);
622 TEST_F(EventRewriterTest, TestRewriteModifiersNoRemapMultipleKeys) {
623 TestingPrefServiceSyncable prefs;
624 EventRewriter rewriter(NULL);
625 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
626 rewriter.set_pref_service_for_testing(&prefs);
628 KeyTestCase tests[] = {
629 // Press Alt with Shift. Confirm the event is not rewritten.
630 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
631 {ui::VKEY_MENU, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN},
632 {ui::VKEY_MENU, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN}},
634 // Press Search with Caps Lock mask. Confirm the event is not rewritten.
635 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
636 {ui::VKEY_LWIN, ui::EF_CAPS_LOCK_DOWN | ui::EF_COMMAND_DOWN},
637 {ui::VKEY_LWIN, ui::EF_CAPS_LOCK_DOWN | ui::EF_COMMAND_DOWN}},
639 // Release Search with Caps Lock mask. Confirm the event is not rewritten.
640 {KeyTestCase::TEST_ALL, ui::ET_KEY_RELEASED,
641 {ui::VKEY_LWIN, ui::EF_CAPS_LOCK_DOWN},
642 {ui::VKEY_LWIN, ui::EF_CAPS_LOCK_DOWN}},
644 // Press Shift+Ctrl+Alt+Search+A. Confirm the event is not rewritten.
645 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
646 {ui::VKEY_B, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN |
647 ui::EF_COMMAND_DOWN},
648 {ui::VKEY_B, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN |
649 ui::EF_COMMAND_DOWN}},
652 for (size_t i = 0; i < arraysize(tests); ++i) {
654 CheckKeyTestCase(&rewriter, tests[i]);
658 TEST_F(EventRewriterTest, TestRewriteModifiersDisableSome) {
659 // Disable Search and Control keys.
660 TestingPrefServiceSyncable prefs;
661 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
662 IntegerPrefMember search;
663 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
664 search.SetValue(chromeos::input_method::kVoidKey);
665 IntegerPrefMember control;
666 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
667 control.SetValue(chromeos::input_method::kVoidKey);
669 EventRewriter rewriter(NULL);
670 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
671 rewriter.set_pref_service_for_testing(&prefs);
673 KeyTestCase disabled_modifier_tests[] = {
674 // Press Alt with Shift. This key press shouldn't be affected by the
675 // pref. Confirm the event is not rewritten.
676 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
677 {ui::VKEY_MENU, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN},
678 {ui::VKEY_MENU, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN}},
680 // Press Search. Confirm the event is now VKEY_UNKNOWN.
681 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
682 {ui::VKEY_LWIN, ui::EF_NONE},
683 {ui::VKEY_UNKNOWN, ui::EF_NONE}},
685 // Press Control. Confirm the event is now VKEY_UNKNOWN.
686 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
687 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN},
688 {ui::VKEY_UNKNOWN, ui::EF_NONE}},
690 // Press Control+Search. Confirm the event is now VKEY_UNKNOWN
691 // without any modifiers.
692 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
693 {ui::VKEY_LWIN, ui::EF_CONTROL_DOWN},
694 {ui::VKEY_UNKNOWN, ui::EF_NONE}},
696 // Press Control+Search+a. Confirm the event is now VKEY_A without any
698 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
699 {ui::VKEY_A, ui::EF_CONTROL_DOWN},
700 {ui::VKEY_A, ui::EF_NONE}},
702 // Press Control+Search+Alt+a. Confirm the event is now VKEY_A only with
704 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
705 {ui::VKEY_A, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN},
706 {ui::VKEY_A, ui::EF_ALT_DOWN}},
709 for (size_t i = 0; i < arraysize(disabled_modifier_tests); ++i) {
711 CheckKeyTestCase(&rewriter, disabled_modifier_tests[i]);
714 // Remap Alt to Control.
715 IntegerPrefMember alt;
716 alt.Init(prefs::kLanguageRemapAltKeyTo, &prefs);
717 alt.SetValue(chromeos::input_method::kControlKey);
719 KeyTestCase tests[] = {
720 // Press left Alt. Confirm the event is now VKEY_CONTROL
721 // even though the Control key itself is disabled.
722 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
723 {ui::VKEY_MENU, ui::EF_ALT_DOWN},
724 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN}},
726 // Press Alt+a. Confirm the event is now Control+a even though the Control
727 // key itself is disabled.
728 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
729 {ui::VKEY_A, ui::EF_ALT_DOWN},
730 {ui::VKEY_A, ui::EF_CONTROL_DOWN}},
733 for (size_t i = 0; i < arraysize(tests); ++i) {
735 CheckKeyTestCase(&rewriter, tests[i]);
739 TEST_F(EventRewriterTest, TestRewriteModifiersRemapToControl) {
740 // Remap Search to Control.
741 TestingPrefServiceSyncable prefs;
742 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
743 IntegerPrefMember search;
744 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
745 search.SetValue(chromeos::input_method::kControlKey);
747 EventRewriter rewriter(NULL);
748 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
749 rewriter.set_pref_service_for_testing(&prefs);
751 KeyTestCase s_tests[] = {
752 // Press Search. Confirm the event is now VKEY_CONTROL.
753 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
754 {ui::VKEY_LWIN, ui::EF_COMMAND_DOWN},
755 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN}},
758 for (size_t i = 0; i < arraysize(s_tests); ++i) {
760 CheckKeyTestCase(&rewriter, s_tests[i]);
763 // Remap Alt to Control too.
764 IntegerPrefMember alt;
765 alt.Init(prefs::kLanguageRemapAltKeyTo, &prefs);
766 alt.SetValue(chromeos::input_method::kControlKey);
768 KeyTestCase sa_tests[] = {
769 // Press Alt. Confirm the event is now VKEY_CONTROL.
770 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
771 {ui::VKEY_MENU, ui::EF_ALT_DOWN},
772 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN}},
774 // Press Alt+Search. Confirm the event is now VKEY_CONTROL.
775 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
776 {ui::VKEY_LWIN, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN},
777 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN}},
779 // Press Control+Alt+Search. Confirm the event is now VKEY_CONTROL.
780 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
782 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN},
783 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN}},
785 // Press Shift+Control+Alt+Search. Confirm the event is now Control with
786 // Shift and Control modifiers.
787 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
788 {ui::VKEY_LWIN, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
789 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN},
790 {ui::VKEY_CONTROL, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN}},
792 // Press Shift+Control+Alt+Search+B. Confirm the event is now B with Shift
793 // and Control modifiers.
794 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
795 {ui::VKEY_B, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN |
796 ui::EF_COMMAND_DOWN},
797 {ui::VKEY_B, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN}},
800 for (size_t i = 0; i < arraysize(sa_tests); ++i) {
802 CheckKeyTestCase(&rewriter, sa_tests[i]);
806 TEST_F(EventRewriterTest, TestRewriteModifiersRemapToEscape) {
807 // Remap Search to ESC.
808 TestingPrefServiceSyncable prefs;
809 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
810 IntegerPrefMember search;
811 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
812 search.SetValue(chromeos::input_method::kEscapeKey);
814 EventRewriter rewriter(NULL);
815 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
816 rewriter.set_pref_service_for_testing(&prefs);
818 KeyTestCase tests[] = {// Press Search. Confirm the event is now VKEY_ESCAPE.
819 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
820 {ui::VKEY_LWIN, ui::EF_COMMAND_DOWN},
821 {ui::VKEY_ESCAPE, ui::EF_NONE}},
824 for (size_t i = 0; i < arraysize(tests); ++i) {
826 CheckKeyTestCase(&rewriter, tests[i]);
830 TEST_F(EventRewriterTest, TestRewriteModifiersRemapMany) {
831 // Remap Search to Alt.
832 TestingPrefServiceSyncable prefs;
833 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
834 IntegerPrefMember search;
835 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
836 search.SetValue(chromeos::input_method::kAltKey);
838 EventRewriter rewriter(NULL);
839 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
840 rewriter.set_pref_service_for_testing(&prefs);
842 KeyTestCase s2a_tests[] = {
843 // Press Search. Confirm the event is now VKEY_MENU.
844 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
845 {ui::VKEY_LWIN, ui::EF_COMMAND_DOWN},
846 {ui::VKEY_MENU, ui::EF_ALT_DOWN}},
849 for (size_t i = 0; i < arraysize(s2a_tests); ++i) {
851 CheckKeyTestCase(&rewriter, s2a_tests[i]);
854 // Remap Alt to Control.
855 IntegerPrefMember alt;
856 alt.Init(prefs::kLanguageRemapAltKeyTo, &prefs);
857 alt.SetValue(chromeos::input_method::kControlKey);
859 KeyTestCase a2c_tests[] = {
860 // Press left Alt. Confirm the event is now VKEY_CONTROL.
861 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
862 {ui::VKEY_MENU, ui::EF_ALT_DOWN},
863 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN}},
864 // Press Shift+comma. Verify that only the flags are changed.
865 // The X11 portion of the test addresses crbug.com/390263 by verifying
866 // that the X keycode remains that for ',<' and not for 105-key '<>'.
867 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
868 {ui::VKEY_OEM_COMMA, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN},
869 {ui::VKEY_OEM_COMMA, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN}},
870 // Press Shift+9. Verify that only the flags are changed.
871 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
872 {ui::VKEY_9, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN},
873 {ui::VKEY_9, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN}},
876 for (size_t i = 0; i < arraysize(a2c_tests); ++i) {
878 CheckKeyTestCase(&rewriter, a2c_tests[i]);
881 // Remap Control to Search.
882 IntegerPrefMember control;
883 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
884 control.SetValue(chromeos::input_method::kSearchKey);
886 KeyTestCase c2s_tests[] = {
887 // Press left Control. Confirm the event is now VKEY_LWIN.
888 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
889 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN},
890 {ui::VKEY_LWIN, ui::EF_COMMAND_DOWN}},
892 // Then, press all of the three, Control+Alt+Search.
893 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
895 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN},
897 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN}},
899 // Press Shift+Control+Alt+Search.
900 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
901 {ui::VKEY_LWIN, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
902 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN},
903 {ui::VKEY_MENU, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
904 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN}},
906 // Press Shift+Control+Alt+Search+B
907 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
908 {ui::VKEY_B, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN |
909 ui::EF_COMMAND_DOWN},
910 {ui::VKEY_B, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN |
911 ui::EF_COMMAND_DOWN}},
914 for (size_t i = 0; i < arraysize(c2s_tests); ++i) {
916 CheckKeyTestCase(&rewriter, c2s_tests[i]);
920 TEST_F(EventRewriterTest, TestRewriteModifiersRemapToCapsLock) {
921 // Remap Search to Caps Lock.
922 TestingPrefServiceSyncable prefs;
923 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
924 IntegerPrefMember search;
925 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
926 search.SetValue(chromeos::input_method::kCapsLockKey);
928 chromeos::input_method::FakeImeKeyboard ime_keyboard;
929 EventRewriter rewriter(NULL);
930 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
931 rewriter.set_pref_service_for_testing(&prefs);
932 rewriter.set_ime_keyboard_for_testing(&ime_keyboard);
933 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
937 GetExpectedResultAsString(ui::VKEY_CAPITAL,
938 ui::EF_CAPS_LOCK_DOWN | ui::EF_MOD3_DOWN,
940 GetRewrittenEventAsString(
941 &rewriter, ui::VKEY_LWIN, ui::EF_COMMAND_DOWN, ui::ET_KEY_PRESSED));
942 // Confirm that the Caps Lock status is changed.
943 EXPECT_TRUE(ime_keyboard.caps_lock_is_enabled_);
946 EXPECT_EQ(GetExpectedResultAsString(
947 ui::VKEY_CAPITAL, ui::EF_NONE, ui::ET_KEY_RELEASED),
948 GetRewrittenEventAsString(
949 &rewriter, ui::VKEY_LWIN, ui::EF_NONE, ui::ET_KEY_RELEASED));
950 // Confirm that the Caps Lock status is not changed.
951 EXPECT_TRUE(ime_keyboard.caps_lock_is_enabled_);
955 GetExpectedResultAsString(ui::VKEY_CAPITAL,
956 ui::EF_CAPS_LOCK_DOWN | ui::EF_MOD3_DOWN,
958 GetRewrittenEventAsString(&rewriter,
960 ui::EF_COMMAND_DOWN | ui::EF_CAPS_LOCK_DOWN,
961 ui::ET_KEY_PRESSED));
962 // Confirm that the Caps Lock status is changed.
963 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
966 EXPECT_EQ(GetExpectedResultAsString(
967 ui::VKEY_CAPITAL, ui::EF_NONE, ui::ET_KEY_RELEASED),
968 GetRewrittenEventAsString(
969 &rewriter, ui::VKEY_LWIN, ui::EF_NONE, ui::ET_KEY_RELEASED));
970 // Confirm that the Caps Lock status is not changed.
971 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
973 // Press Caps Lock (on an external keyboard).
974 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
975 ui::EF_CAPS_LOCK_DOWN | ui::EF_MOD3_DOWN,
977 GetRewrittenEventAsString(&rewriter,
979 ui::EF_CAPS_LOCK_DOWN | ui::EF_MOD3_DOWN,
980 ui::ET_KEY_PRESSED));
982 // Confirm that calling RewriteForTesting() does not change the state of
983 // |ime_keyboard|. In this case, X Window system itself should change the
984 // Caps Lock state, not ash::EventRewriter.
985 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
987 // Release Caps Lock (on an external keyboard).
988 EXPECT_EQ(GetExpectedResultAsString(
989 ui::VKEY_CAPITAL, ui::EF_NONE, ui::ET_KEY_RELEASED),
990 GetRewrittenEventAsString(
991 &rewriter, ui::VKEY_CAPITAL, ui::EF_NONE, ui::ET_KEY_RELEASED));
992 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
995 TEST_F(EventRewriterTest, TestRewriteCapsLock) {
996 TestingPrefServiceSyncable prefs;
997 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
999 chromeos::input_method::FakeImeKeyboard ime_keyboard;
1000 EventRewriter rewriter(NULL);
1001 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
1002 rewriter.set_pref_service_for_testing(&prefs);
1003 rewriter.set_ime_keyboard_for_testing(&ime_keyboard);
1004 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
1006 // On Chrome OS, CapsLock is mapped to F16 with Mod3Mask.
1007 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
1008 ui::EF_CAPS_LOCK_DOWN | ui::EF_MOD3_DOWN,
1009 ui::ET_KEY_PRESSED),
1010 GetRewrittenEventAsString(
1011 &rewriter, ui::VKEY_F16, ui::EF_MOD3_DOWN, ui::ET_KEY_PRESSED));
1012 EXPECT_TRUE(ime_keyboard.caps_lock_is_enabled_);
1015 TEST_F(EventRewriterTest, TestRewriteDiamondKey) {
1016 TestingPrefServiceSyncable prefs;
1017 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1019 chromeos::input_method::FakeImeKeyboard ime_keyboard;
1020 EventRewriter rewriter(NULL);
1021 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
1022 rewriter.set_pref_service_for_testing(&prefs);
1023 rewriter.set_ime_keyboard_for_testing(&ime_keyboard);
1025 KeyTestCase tests[] = {
1026 // F15 should work as Ctrl when --has-chromeos-diamond-key is not
1028 {KeyTestCase::TEST_VKEY,
1030 {ui::VKEY_F15, ui::EF_NONE},
1031 {ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN}},
1033 {KeyTestCase::TEST_VKEY,
1034 ui::ET_KEY_RELEASED,
1035 {ui::VKEY_F15, ui::EF_NONE},
1036 {ui::VKEY_CONTROL, ui::EF_NONE}},
1038 // However, Mod2Mask should not be rewritten to CtrlMask when
1039 // --has-chromeos-diamond-key is not specified.
1040 {KeyTestCase::TEST_VKEY,
1042 {ui::VKEY_A, ui::EF_NONE},
1043 {ui::VKEY_A, ui::EF_NONE}},
1046 for (size_t i = 0; i < arraysize(tests); ++i) {
1048 CheckKeyTestCase(&rewriter, tests[i]);
1052 TEST_F(EventRewriterTest, TestRewriteDiamondKeyWithFlag) {
1053 const CommandLine original_cl(*CommandLine::ForCurrentProcess());
1054 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1055 chromeos::switches::kHasChromeOSDiamondKey, "");
1057 TestingPrefServiceSyncable prefs;
1058 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1060 chromeos::input_method::FakeImeKeyboard ime_keyboard;
1061 EventRewriter rewriter(NULL);
1062 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
1063 rewriter.set_pref_service_for_testing(&prefs);
1064 rewriter.set_ime_keyboard_for_testing(&ime_keyboard);
1066 // By default, F15 should work as Control.
1067 EXPECT_EQ(GetExpectedResultAsString(
1068 ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
1069 GetRewrittenEventAsString(
1070 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_PRESSED));
1071 // Check that Control is applied to a subsequent key press.
1072 EXPECT_EQ(GetExpectedResultAsString(
1073 ui::VKEY_A, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
1074 GetRewrittenEventAsString(
1075 &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
1077 EXPECT_EQ(GetExpectedResultAsString(
1078 ui::VKEY_CONTROL, ui::EF_NONE, ui::ET_KEY_RELEASED),
1079 GetRewrittenEventAsString(
1080 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_RELEASED));
1081 // Check that Control is no longer applied to a subsequent key press.
1083 GetExpectedResultAsString(ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED),
1084 GetRewrittenEventAsString(
1085 &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
1087 IntegerPrefMember diamond;
1088 diamond.Init(prefs::kLanguageRemapDiamondKeyTo, &prefs);
1089 diamond.SetValue(chromeos::input_method::kVoidKey);
1091 EXPECT_EQ(GetExpectedResultAsString(
1092 ui::VKEY_UNKNOWN, ui::EF_NONE, ui::ET_KEY_PRESSED),
1093 GetRewrittenEventAsString(
1094 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_PRESSED));
1095 // Check that no modifier is applied to another key.
1097 GetExpectedResultAsString(ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED),
1098 GetRewrittenEventAsString(
1099 &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
1101 diamond.SetValue(chromeos::input_method::kControlKey);
1103 EXPECT_EQ(GetExpectedResultAsString(
1104 ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
1105 GetRewrittenEventAsString(
1106 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_PRESSED));
1107 // Check that Control is applied to a subsequent key press.
1108 EXPECT_EQ(GetExpectedResultAsString(
1109 ui::VKEY_A, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
1110 GetRewrittenEventAsString(
1111 &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
1113 EXPECT_EQ(GetExpectedResultAsString(
1114 ui::VKEY_CONTROL, ui::EF_NONE, ui::ET_KEY_RELEASED),
1115 GetRewrittenEventAsString(
1116 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_RELEASED));
1117 // Check that Control is no longer applied to a subsequent key press.
1119 GetExpectedResultAsString(ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED),
1120 GetRewrittenEventAsString(
1121 &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
1123 diamond.SetValue(chromeos::input_method::kAltKey);
1125 EXPECT_EQ(GetExpectedResultAsString(
1126 ui::VKEY_MENU, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED),
1127 GetRewrittenEventAsString(
1128 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_PRESSED));
1129 // Check that Alt is applied to a subsequent key press.
1130 EXPECT_EQ(GetExpectedResultAsString(
1131 ui::VKEY_A, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED),
1132 GetRewrittenEventAsString(
1133 &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
1135 EXPECT_EQ(GetExpectedResultAsString(
1136 ui::VKEY_MENU, ui::EF_NONE, ui::ET_KEY_RELEASED),
1137 GetRewrittenEventAsString(
1138 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_RELEASED));
1139 // Check that Alt is no longer applied to a subsequent key press.
1141 GetExpectedResultAsString(ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED),
1142 GetRewrittenEventAsString(
1143 &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
1145 diamond.SetValue(chromeos::input_method::kCapsLockKey);
1147 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
1148 ui::EF_CAPS_LOCK_DOWN | ui::EF_MOD3_DOWN,
1149 ui::ET_KEY_PRESSED),
1150 GetRewrittenEventAsString(
1151 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_PRESSED));
1152 // Check that Caps is applied to a subsequent key press.
1153 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
1154 ui::EF_CAPS_LOCK_DOWN | ui::EF_MOD3_DOWN,
1155 ui::ET_KEY_PRESSED),
1156 GetRewrittenEventAsString(
1157 &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
1159 EXPECT_EQ(GetExpectedResultAsString(
1160 ui::VKEY_CAPITAL, ui::EF_NONE, ui::ET_KEY_RELEASED),
1161 GetRewrittenEventAsString(
1162 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_RELEASED));
1163 // Check that Control is no longer applied to a subsequent key press.
1165 GetExpectedResultAsString(ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED),
1166 GetRewrittenEventAsString(
1167 &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
1169 *CommandLine::ForCurrentProcess() = original_cl;
1172 TEST_F(EventRewriterTest, TestRewriteCapsLockToControl) {
1173 // Remap CapsLock to Control.
1174 TestingPrefServiceSyncable prefs;
1175 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1176 IntegerPrefMember control;
1177 control.Init(prefs::kLanguageRemapCapsLockKeyTo, &prefs);
1178 control.SetValue(chromeos::input_method::kControlKey);
1180 EventRewriter rewriter(NULL);
1181 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
1182 rewriter.set_pref_service_for_testing(&prefs);
1184 KeyTestCase tests[] = {
1185 // Press CapsLock+a. Confirm that Mod3Mask is rewritten to ControlMask.
1186 // On Chrome OS, CapsLock works as a Mod3 modifier.
1187 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1188 {ui::VKEY_A, ui::EF_MOD3_DOWN},
1189 {ui::VKEY_A, ui::EF_CONTROL_DOWN}},
1191 // Press Control+CapsLock+a. Confirm that Mod3Mask is rewritten to
1193 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1194 {ui::VKEY_A, ui::EF_CONTROL_DOWN | ui::EF_MOD3_DOWN},
1195 {ui::VKEY_A, ui::EF_CONTROL_DOWN}},
1197 // Press Alt+CapsLock+a. Confirm that Mod3Mask is rewritten to
1199 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1200 {ui::VKEY_A, ui::EF_ALT_DOWN | ui::EF_MOD3_DOWN},
1201 {ui::VKEY_A, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN}},
1204 for (size_t i = 0; i < arraysize(tests); ++i) {
1206 CheckKeyTestCase(&rewriter, tests[i]);
1210 TEST_F(EventRewriterTest, TestRewriteCapsLockMod3InUse) {
1211 // Remap CapsLock to Control.
1212 TestingPrefServiceSyncable prefs;
1213 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1214 IntegerPrefMember control;
1215 control.Init(prefs::kLanguageRemapCapsLockKeyTo, &prefs);
1216 control.SetValue(chromeos::input_method::kControlKey);
1218 EventRewriter rewriter(NULL);
1219 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
1220 rewriter.set_pref_service_for_testing(&prefs);
1221 input_method_manager_mock_->set_mod3_used(true);
1223 // Press CapsLock+a. Confirm that Mod3Mask is NOT rewritten to ControlMask
1224 // when Mod3Mask is already in use by the current XKB layout.
1226 GetExpectedResultAsString(ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED),
1227 GetRewrittenEventAsString(
1228 &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
1230 input_method_manager_mock_->set_mod3_used(false);
1233 TEST_F(EventRewriterTest, TestRewriteExtendedKeys) {
1234 TestingPrefServiceSyncable prefs;
1235 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1236 EventRewriter rewriter(NULL);
1237 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
1238 rewriter.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId);
1239 rewriter.set_pref_service_for_testing(&prefs);
1241 KeyTestCase tests[] = {
1242 // Alt+Backspace -> Delete
1243 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1244 {ui::VKEY_BACK, ui::EF_ALT_DOWN},
1245 {ui::VKEY_DELETE, ui::EF_NONE}},
1246 // Control+Alt+Backspace -> Control+Delete
1247 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1248 {ui::VKEY_BACK, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN},
1249 {ui::VKEY_DELETE, ui::EF_CONTROL_DOWN}},
1250 // Search+Alt+Backspace -> Alt+Backspace
1251 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1252 {ui::VKEY_BACK, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN},
1253 {ui::VKEY_BACK, ui::EF_ALT_DOWN}},
1254 // Search+Control+Alt+Backspace -> Control+Alt+Backspace
1255 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1257 ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN},
1258 {ui::VKEY_BACK, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN}},
1260 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1261 {ui::VKEY_UP, ui::EF_ALT_DOWN},
1262 {ui::VKEY_PRIOR, ui::EF_NONE}},
1264 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1265 {ui::VKEY_DOWN, ui::EF_ALT_DOWN},
1266 {ui::VKEY_NEXT, ui::EF_NONE}},
1267 // Ctrl+Alt+Up -> Home
1268 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1269 {ui::VKEY_UP, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN},
1270 {ui::VKEY_HOME, ui::EF_NONE}},
1271 // Ctrl+Alt+Down -> End
1272 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1273 {ui::VKEY_DOWN, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN},
1274 {ui::VKEY_END, ui::EF_NONE}},
1276 // Search+Alt+Up -> Alt+Up
1277 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1278 {ui::VKEY_UP, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN},
1279 {ui::VKEY_UP, ui::EF_ALT_DOWN}},
1280 // Search+Alt+Down -> Alt+Down
1281 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1282 {ui::VKEY_DOWN, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN},
1283 {ui::VKEY_DOWN, ui::EF_ALT_DOWN}},
1284 // Search+Ctrl+Alt+Up -> Search+Ctrl+Alt+Up
1285 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1287 ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN},
1288 {ui::VKEY_UP, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN}},
1289 // Search+Ctrl+Alt+Down -> Ctrl+Alt+Down
1290 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1292 ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN},
1293 {ui::VKEY_DOWN, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN}},
1296 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1297 {ui::VKEY_OEM_PERIOD, ui::EF_NONE},
1298 {ui::VKEY_OEM_PERIOD, ui::EF_NONE}},
1300 // Search+Backspace -> Delete
1301 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1302 {ui::VKEY_BACK, ui::EF_COMMAND_DOWN},
1303 {ui::VKEY_DELETE, ui::EF_NONE}},
1304 // Search+Up -> Prior
1305 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1306 {ui::VKEY_UP, ui::EF_COMMAND_DOWN},
1307 {ui::VKEY_PRIOR, ui::EF_NONE}},
1308 // Search+Down -> Next
1309 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1310 {ui::VKEY_DOWN, ui::EF_COMMAND_DOWN},
1311 {ui::VKEY_NEXT, ui::EF_NONE}},
1312 // Search+Left -> Home
1313 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1314 {ui::VKEY_LEFT, ui::EF_COMMAND_DOWN},
1315 {ui::VKEY_HOME, ui::EF_NONE}},
1316 // Control+Search+Left -> Home
1317 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1318 {ui::VKEY_LEFT, ui::EF_COMMAND_DOWN | ui::EF_CONTROL_DOWN},
1319 {ui::VKEY_HOME, ui::EF_CONTROL_DOWN}},
1320 // Search+Right -> End
1321 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1322 {ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN},
1323 {ui::VKEY_END, ui::EF_NONE}},
1324 // Control+Search+Right -> End
1325 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1326 {ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN | ui::EF_CONTROL_DOWN},
1327 {ui::VKEY_END, ui::EF_CONTROL_DOWN}},
1328 // Search+Period -> Insert
1329 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1330 {ui::VKEY_OEM_PERIOD, ui::EF_COMMAND_DOWN},
1331 {ui::VKEY_INSERT, ui::EF_NONE}},
1332 // Control+Search+Period -> Control+Insert
1333 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1334 {ui::VKEY_OEM_PERIOD, ui::EF_COMMAND_DOWN | ui::EF_CONTROL_DOWN},
1335 {ui::VKEY_INSERT, ui::EF_CONTROL_DOWN}}};
1337 for (size_t i = 0; i < arraysize(tests); ++i) {
1339 CheckKeyTestCase(&rewriter, tests[i]);
1343 TEST_F(EventRewriterTest, TestRewriteFunctionKeys) {
1344 TestingPrefServiceSyncable prefs;
1345 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1346 EventRewriter rewriter(NULL);
1347 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
1348 rewriter.set_pref_service_for_testing(&prefs);
1350 FunctionKeyTestCase tests[] = {
1352 {ui::ET_KEY_PRESSED,
1353 {ui::VKEY_F1, ui::EF_NONE},
1354 {ui::VKEY_BROWSER_BACK, ui::EF_NONE},
1355 {ui::VKEY_BROWSER_BACK, ui::EF_FUNCTION_KEY}},
1356 {ui::ET_KEY_PRESSED,
1357 {ui::VKEY_F1, ui::EF_CONTROL_DOWN},
1358 {ui::VKEY_BROWSER_BACK, ui::EF_CONTROL_DOWN},
1359 {ui::VKEY_BROWSER_BACK, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1360 {ui::ET_KEY_PRESSED,
1361 {ui::VKEY_F1, ui::EF_ALT_DOWN},
1362 {ui::VKEY_BROWSER_BACK, ui::EF_ALT_DOWN},
1363 {ui::VKEY_BROWSER_BACK, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1365 {ui::ET_KEY_PRESSED,
1366 {ui::VKEY_F2, ui::EF_NONE},
1367 {ui::VKEY_BROWSER_FORWARD, ui::EF_NONE},
1368 {ui::VKEY_BROWSER_FORWARD, ui::EF_FUNCTION_KEY}},
1369 {ui::ET_KEY_PRESSED,
1370 {ui::VKEY_F2, ui::EF_CONTROL_DOWN},
1371 {ui::VKEY_BROWSER_FORWARD, ui::EF_CONTROL_DOWN},
1372 {ui::VKEY_BROWSER_FORWARD, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1373 {ui::ET_KEY_PRESSED,
1374 {ui::VKEY_F2, ui::EF_ALT_DOWN},
1375 {ui::VKEY_BROWSER_FORWARD, ui::EF_ALT_DOWN},
1376 {ui::VKEY_BROWSER_FORWARD, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1378 {ui::ET_KEY_PRESSED,
1379 {ui::VKEY_F3, ui::EF_NONE},
1380 {ui::VKEY_BROWSER_REFRESH, ui::EF_NONE},
1381 {ui::VKEY_BROWSER_REFRESH, ui::EF_FUNCTION_KEY}},
1382 {ui::ET_KEY_PRESSED,
1383 {ui::VKEY_F3, ui::EF_CONTROL_DOWN},
1384 {ui::VKEY_BROWSER_REFRESH, ui::EF_CONTROL_DOWN},
1385 {ui::VKEY_BROWSER_REFRESH, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1386 {ui::ET_KEY_PRESSED,
1387 {ui::VKEY_F3, ui::EF_ALT_DOWN},
1388 {ui::VKEY_BROWSER_REFRESH, ui::EF_ALT_DOWN},
1389 {ui::VKEY_BROWSER_REFRESH, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1390 // F4 -> Launch App 2
1391 {ui::ET_KEY_PRESSED,
1392 {ui::VKEY_F4, ui::EF_NONE},
1393 {ui::VKEY_MEDIA_LAUNCH_APP2, ui::EF_NONE},
1394 {ui::VKEY_MEDIA_LAUNCH_APP2, ui::EF_FUNCTION_KEY}},
1395 {ui::ET_KEY_PRESSED,
1396 {ui::VKEY_F4, ui::EF_CONTROL_DOWN},
1397 {ui::VKEY_MEDIA_LAUNCH_APP2, ui::EF_CONTROL_DOWN},
1398 {ui::VKEY_MEDIA_LAUNCH_APP2, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1399 {ui::ET_KEY_PRESSED,
1400 {ui::VKEY_F4, ui::EF_ALT_DOWN},
1401 {ui::VKEY_MEDIA_LAUNCH_APP2, ui::EF_ALT_DOWN},
1402 {ui::VKEY_MEDIA_LAUNCH_APP2, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1403 // F5 -> Launch App 1
1404 {ui::ET_KEY_PRESSED,
1405 {ui::VKEY_F5, ui::EF_NONE},
1406 {ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_NONE},
1407 {ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_FUNCTION_KEY}},
1408 {ui::ET_KEY_PRESSED,
1409 {ui::VKEY_F5, ui::EF_CONTROL_DOWN},
1410 {ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN},
1411 {ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1412 {ui::ET_KEY_PRESSED,
1413 {ui::VKEY_F5, ui::EF_ALT_DOWN},
1414 {ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_ALT_DOWN},
1415 {ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1416 // F6 -> Brightness down
1417 {ui::ET_KEY_PRESSED,
1418 {ui::VKEY_F6, ui::EF_NONE},
1419 {ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE},
1420 {ui::VKEY_BRIGHTNESS_DOWN, ui::EF_FUNCTION_KEY}},
1421 {ui::ET_KEY_PRESSED,
1422 {ui::VKEY_F6, ui::EF_CONTROL_DOWN},
1423 {ui::VKEY_BRIGHTNESS_DOWN, ui::EF_CONTROL_DOWN},
1424 {ui::VKEY_BRIGHTNESS_DOWN, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1425 {ui::ET_KEY_PRESSED,
1426 {ui::VKEY_F6, ui::EF_ALT_DOWN},
1427 {ui::VKEY_BRIGHTNESS_DOWN, ui::EF_ALT_DOWN},
1428 {ui::VKEY_BRIGHTNESS_DOWN, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1429 // F7 -> Brightness up
1430 {ui::ET_KEY_PRESSED,
1431 {ui::VKEY_F7, ui::EF_NONE},
1432 {ui::VKEY_BRIGHTNESS_UP, ui::EF_NONE},
1433 {ui::VKEY_BRIGHTNESS_UP, ui::EF_FUNCTION_KEY}},
1434 {ui::ET_KEY_PRESSED,
1435 {ui::VKEY_F7, ui::EF_CONTROL_DOWN},
1436 {ui::VKEY_BRIGHTNESS_UP, ui::EF_CONTROL_DOWN},
1437 {ui::VKEY_BRIGHTNESS_UP, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1438 {ui::ET_KEY_PRESSED,
1439 {ui::VKEY_F7, ui::EF_ALT_DOWN},
1440 {ui::VKEY_BRIGHTNESS_UP, ui::EF_ALT_DOWN},
1441 {ui::VKEY_BRIGHTNESS_UP, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1442 // F8 -> Volume Mute
1443 {ui::ET_KEY_PRESSED,
1444 {ui::VKEY_F8, ui::EF_NONE},
1445 {ui::VKEY_VOLUME_MUTE, ui::EF_NONE},
1446 {ui::VKEY_VOLUME_MUTE, ui::EF_FUNCTION_KEY}},
1447 {ui::ET_KEY_PRESSED,
1448 {ui::VKEY_F8, ui::EF_CONTROL_DOWN},
1449 {ui::VKEY_VOLUME_MUTE, ui::EF_CONTROL_DOWN},
1450 {ui::VKEY_VOLUME_MUTE, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1451 {ui::ET_KEY_PRESSED,
1452 {ui::VKEY_F8, ui::EF_ALT_DOWN},
1453 {ui::VKEY_VOLUME_MUTE, ui::EF_ALT_DOWN},
1454 {ui::VKEY_VOLUME_MUTE, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1455 // F9 -> Volume Down
1456 {ui::ET_KEY_PRESSED,
1457 {ui::VKEY_F9, ui::EF_NONE},
1458 {ui::VKEY_VOLUME_DOWN, ui::EF_NONE},
1459 {ui::VKEY_VOLUME_DOWN, ui::EF_FUNCTION_KEY}},
1460 {ui::ET_KEY_PRESSED,
1461 {ui::VKEY_F9, ui::EF_CONTROL_DOWN},
1462 {ui::VKEY_VOLUME_DOWN, ui::EF_CONTROL_DOWN},
1463 {ui::VKEY_VOLUME_DOWN, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1464 {ui::ET_KEY_PRESSED,
1465 {ui::VKEY_F9, ui::EF_ALT_DOWN},
1466 {ui::VKEY_VOLUME_DOWN, ui::EF_ALT_DOWN},
1467 {ui::VKEY_VOLUME_DOWN, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1469 {ui::ET_KEY_PRESSED,
1470 {ui::VKEY_F10, ui::EF_NONE},
1471 {ui::VKEY_VOLUME_UP, ui::EF_NONE},
1472 {ui::VKEY_VOLUME_UP, ui::EF_FUNCTION_KEY}},
1473 {ui::ET_KEY_PRESSED,
1474 {ui::VKEY_F10, ui::EF_CONTROL_DOWN},
1475 {ui::VKEY_VOLUME_UP, ui::EF_CONTROL_DOWN},
1476 {ui::VKEY_VOLUME_UP, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1477 {ui::ET_KEY_PRESSED,
1478 {ui::VKEY_F10, ui::EF_ALT_DOWN},
1479 {ui::VKEY_VOLUME_UP, ui::EF_ALT_DOWN},
1480 {ui::VKEY_VOLUME_UP, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1482 {ui::ET_KEY_PRESSED,
1483 {ui::VKEY_F11, ui::EF_NONE},
1484 {ui::VKEY_F11, ui::EF_NONE},
1485 {ui::VKEY_F11, ui::EF_FUNCTION_KEY}},
1486 {ui::ET_KEY_PRESSED,
1487 {ui::VKEY_F11, ui::EF_CONTROL_DOWN},
1488 {ui::VKEY_F11, ui::EF_CONTROL_DOWN},
1489 {ui::VKEY_F11, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1490 {ui::ET_KEY_PRESSED,
1491 {ui::VKEY_F11, ui::EF_ALT_DOWN},
1492 {ui::VKEY_F11, ui::EF_ALT_DOWN},
1493 {ui::VKEY_F11, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1495 {ui::ET_KEY_PRESSED,
1496 {ui::VKEY_F12, ui::EF_NONE},
1497 {ui::VKEY_F12, ui::EF_NONE},
1498 {ui::VKEY_F12, ui::EF_FUNCTION_KEY}},
1499 {ui::ET_KEY_PRESSED,
1500 {ui::VKEY_F12, ui::EF_CONTROL_DOWN},
1501 {ui::VKEY_F12, ui::EF_CONTROL_DOWN},
1502 {ui::VKEY_F12, ui::EF_CONTROL_DOWN | ui::EF_FUNCTION_KEY}},
1503 {ui::ET_KEY_PRESSED,
1504 {ui::VKEY_F12, ui::EF_ALT_DOWN},
1505 {ui::VKEY_F12, ui::EF_ALT_DOWN},
1506 {ui::VKEY_F12, ui::EF_ALT_DOWN | ui::EF_FUNCTION_KEY}},
1508 // The number row should not be rewritten without Search key.
1509 {ui::ET_KEY_PRESSED,
1510 {ui::VKEY_1, ui::EF_NONE},
1511 {ui::VKEY_1, ui::EF_NONE},
1512 {ui::VKEY_1, ui::EF_NONE}},
1513 {ui::ET_KEY_PRESSED,
1514 {ui::VKEY_2, ui::EF_NONE},
1515 {ui::VKEY_2, ui::EF_NONE},
1516 {ui::VKEY_2, ui::EF_NONE}},
1517 {ui::ET_KEY_PRESSED,
1518 {ui::VKEY_3, ui::EF_NONE},
1519 {ui::VKEY_3, ui::EF_NONE},
1520 {ui::VKEY_3, ui::EF_NONE}},
1521 {ui::ET_KEY_PRESSED,
1522 {ui::VKEY_4, ui::EF_NONE},
1523 {ui::VKEY_4, ui::EF_NONE},
1524 {ui::VKEY_4, ui::EF_NONE}},
1525 {ui::ET_KEY_PRESSED,
1526 {ui::VKEY_5, ui::EF_NONE},
1527 {ui::VKEY_5, ui::EF_NONE},
1528 {ui::VKEY_5, ui::EF_NONE}},
1529 {ui::ET_KEY_PRESSED,
1530 {ui::VKEY_6, ui::EF_NONE},
1531 {ui::VKEY_6, ui::EF_NONE},
1532 {ui::VKEY_6, ui::EF_NONE}},
1533 {ui::ET_KEY_PRESSED,
1534 {ui::VKEY_7, ui::EF_NONE},
1535 {ui::VKEY_7, ui::EF_NONE},
1536 {ui::VKEY_7, ui::EF_NONE}},
1537 {ui::ET_KEY_PRESSED,
1538 {ui::VKEY_8, ui::EF_NONE},
1539 {ui::VKEY_8, ui::EF_NONE},
1540 {ui::VKEY_8, ui::EF_NONE}},
1541 {ui::ET_KEY_PRESSED,
1542 {ui::VKEY_9, ui::EF_NONE},
1543 {ui::VKEY_9, ui::EF_NONE},
1544 {ui::VKEY_9, ui::EF_NONE}},
1545 {ui::ET_KEY_PRESSED,
1546 {ui::VKEY_0, ui::EF_NONE},
1547 {ui::VKEY_0, ui::EF_NONE},
1548 {ui::VKEY_0, ui::EF_NONE}},
1549 {ui::ET_KEY_PRESSED,
1550 {ui::VKEY_OEM_MINUS, ui::EF_NONE},
1551 {ui::VKEY_OEM_MINUS, ui::EF_NONE},
1552 {ui::VKEY_OEM_MINUS, ui::EF_NONE}},
1553 {ui::ET_KEY_PRESSED,
1554 {ui::VKEY_OEM_PLUS, ui::EF_NONE},
1555 {ui::VKEY_OEM_PLUS, ui::EF_NONE},
1556 {ui::VKEY_OEM_PLUS, ui::EF_NONE}},
1558 // The number row should be rewritten as the F<number> row with Search
1560 {ui::ET_KEY_PRESSED,
1561 {ui::VKEY_1, ui::EF_COMMAND_DOWN},
1562 {ui::VKEY_F1, ui::EF_NONE},
1563 {ui::VKEY_F1, ui::EF_NONE}},
1564 {ui::ET_KEY_PRESSED,
1565 {ui::VKEY_2, ui::EF_COMMAND_DOWN},
1566 {ui::VKEY_F2, ui::EF_NONE},
1567 {ui::VKEY_F2, ui::EF_NONE}},
1568 {ui::ET_KEY_PRESSED,
1569 {ui::VKEY_3, ui::EF_COMMAND_DOWN},
1570 {ui::VKEY_F3, ui::EF_NONE},
1571 {ui::VKEY_F3, ui::EF_NONE}},
1572 {ui::ET_KEY_PRESSED,
1573 {ui::VKEY_4, ui::EF_COMMAND_DOWN},
1574 {ui::VKEY_F4, ui::EF_NONE},
1575 {ui::VKEY_F4, ui::EF_NONE}},
1576 {ui::ET_KEY_PRESSED,
1577 {ui::VKEY_5, ui::EF_COMMAND_DOWN},
1578 {ui::VKEY_F5, ui::EF_NONE},
1579 {ui::VKEY_F5, ui::EF_NONE}},
1580 {ui::ET_KEY_PRESSED,
1581 {ui::VKEY_6, ui::EF_COMMAND_DOWN},
1582 {ui::VKEY_F6, ui::EF_NONE},
1583 {ui::VKEY_F6, ui::EF_NONE}},
1584 {ui::ET_KEY_PRESSED,
1585 {ui::VKEY_7, ui::EF_COMMAND_DOWN},
1586 {ui::VKEY_F7, ui::EF_NONE},
1587 {ui::VKEY_F7, ui::EF_NONE}},
1588 {ui::ET_KEY_PRESSED,
1589 {ui::VKEY_8, ui::EF_COMMAND_DOWN},
1590 {ui::VKEY_F8, ui::EF_NONE},
1591 {ui::VKEY_F8, ui::EF_NONE}},
1592 {ui::ET_KEY_PRESSED,
1593 {ui::VKEY_9, ui::EF_COMMAND_DOWN},
1594 {ui::VKEY_F9, ui::EF_NONE},
1595 {ui::VKEY_F9, ui::EF_NONE}},
1596 {ui::ET_KEY_PRESSED,
1597 {ui::VKEY_0, ui::EF_COMMAND_DOWN},
1598 {ui::VKEY_F10, ui::EF_NONE},
1599 {ui::VKEY_F10, ui::EF_NONE}},
1600 {ui::ET_KEY_PRESSED,
1601 {ui::VKEY_OEM_MINUS, ui::EF_COMMAND_DOWN},
1602 {ui::VKEY_F11, ui::EF_NONE},
1603 {ui::VKEY_F11, ui::EF_NONE}},
1604 {ui::ET_KEY_PRESSED,
1605 {ui::VKEY_OEM_PLUS, ui::EF_COMMAND_DOWN},
1606 {ui::VKEY_F12, ui::EF_NONE},
1607 {ui::VKEY_F12, ui::EF_NONE}},
1609 // The function keys should not be rewritten with Search key pressed.
1610 {ui::ET_KEY_PRESSED,
1611 {ui::VKEY_F1, ui::EF_COMMAND_DOWN},
1612 {ui::VKEY_F1, ui::EF_NONE},
1613 {ui::VKEY_F1, ui::EF_FUNCTION_KEY}},
1614 {ui::ET_KEY_PRESSED,
1615 {ui::VKEY_F2, ui::EF_COMMAND_DOWN},
1616 {ui::VKEY_F2, ui::EF_NONE},
1617 {ui::VKEY_F2, ui::EF_FUNCTION_KEY}},
1618 {ui::ET_KEY_PRESSED,
1619 {ui::VKEY_F3, ui::EF_COMMAND_DOWN},
1620 {ui::VKEY_F3, ui::EF_NONE},
1621 {ui::VKEY_F3, ui::EF_FUNCTION_KEY}},
1622 {ui::ET_KEY_PRESSED,
1623 {ui::VKEY_F4, ui::EF_COMMAND_DOWN},
1624 {ui::VKEY_F4, ui::EF_NONE},
1625 {ui::VKEY_F4, ui::EF_FUNCTION_KEY}},
1626 {ui::ET_KEY_PRESSED,
1627 {ui::VKEY_F5, ui::EF_COMMAND_DOWN},
1628 {ui::VKEY_F5, ui::EF_NONE},
1629 {ui::VKEY_F5, ui::EF_FUNCTION_KEY}},
1630 {ui::ET_KEY_PRESSED,
1631 {ui::VKEY_F6, ui::EF_COMMAND_DOWN},
1632 {ui::VKEY_F6, ui::EF_NONE},
1633 {ui::VKEY_F6, ui::EF_FUNCTION_KEY}},
1634 {ui::ET_KEY_PRESSED,
1635 {ui::VKEY_F7, ui::EF_COMMAND_DOWN},
1636 {ui::VKEY_F7, ui::EF_NONE},
1637 {ui::VKEY_F7, ui::EF_FUNCTION_KEY}},
1638 {ui::ET_KEY_PRESSED,
1639 {ui::VKEY_F8, ui::EF_COMMAND_DOWN},
1640 {ui::VKEY_F8, ui::EF_NONE},
1641 {ui::VKEY_F8, ui::EF_FUNCTION_KEY}},
1642 {ui::ET_KEY_PRESSED,
1643 {ui::VKEY_F9, ui::EF_COMMAND_DOWN},
1644 {ui::VKEY_F9, ui::EF_NONE},
1645 {ui::VKEY_F9, ui::EF_FUNCTION_KEY}},
1646 {ui::ET_KEY_PRESSED,
1647 {ui::VKEY_F10, ui::EF_COMMAND_DOWN},
1648 {ui::VKEY_F10, ui::EF_NONE},
1649 {ui::VKEY_F10, ui::EF_FUNCTION_KEY}},
1650 {ui::ET_KEY_PRESSED,
1651 {ui::VKEY_F11, ui::EF_COMMAND_DOWN},
1652 {ui::VKEY_F11, ui::EF_NONE},
1653 {ui::VKEY_F11, ui::EF_FUNCTION_KEY}},
1654 {ui::ET_KEY_PRESSED,
1655 {ui::VKEY_F12, ui::EF_COMMAND_DOWN},
1656 {ui::VKEY_F12, ui::EF_NONE},
1657 {ui::VKEY_F12, ui::EF_FUNCTION_KEY}},
1660 for (size_t i = 0; i < arraysize(tests); ++i) {
1662 CheckFunctionKeyTestCase(&rewriter, tests[i]);
1666 TEST_F(EventRewriterTest, TestRewriteExtendedKeysWithSearchRemapped) {
1667 const CommandLine original_cl(*CommandLine::ForCurrentProcess());
1669 // Remap Search to Control.
1670 TestingPrefServiceSyncable prefs;
1671 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1672 IntegerPrefMember search;
1673 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
1674 search.SetValue(chromeos::input_method::kControlKey);
1676 EventRewriter rewriter(NULL);
1677 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
1678 rewriter.set_pref_service_for_testing(&prefs);
1680 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1681 chromeos::switches::kHasChromeOSKeyboard, "");
1683 KeyTestCase tests[] = {
1684 // Alt+Search+Down -> End
1685 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1686 {ui::VKEY_DOWN, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN},
1687 {ui::VKEY_END, ui::EF_NONE}},
1689 // Shift+Alt+Search+Down -> Shift+End
1690 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1692 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN},
1693 {ui::VKEY_END, ui::EF_SHIFT_DOWN}},
1696 for (size_t i = 0; i < arraysize(tests); ++i) {
1698 CheckKeyTestCase(&rewriter, tests[i]);
1701 *CommandLine::ForCurrentProcess() = original_cl;
1704 TEST_F(EventRewriterTest, TestRewriteKeyEventSentByXSendEvent) {
1705 // Remap Control to Alt.
1706 TestingPrefServiceSyncable prefs;
1707 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1708 IntegerPrefMember control;
1709 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
1710 control.SetValue(chromeos::input_method::kAltKey);
1712 EventRewriter rewriter(NULL);
1713 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
1714 rewriter.set_pref_service_for_testing(&prefs);
1716 // Send left control press.
1718 ui::KeyEvent keyevent(
1719 ui::ET_KEY_PRESSED, ui::VKEY_CONTROL, ui::EF_FINAL);
1720 scoped_ptr<ui::Event> new_event;
1721 // Control should NOT be remapped to Alt if EF_FINAL is set.
1722 EXPECT_EQ(ui::EVENT_REWRITE_CONTINUE,
1723 rewriter.RewriteEvent(keyevent, &new_event));
1724 EXPECT_FALSE(new_event);
1726 #if defined(USE_X11)
1727 // Send left control press, using XI2 native events.
1729 ui::ScopedXI2Event xev;
1730 xev.InitKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_CONTROL, 0);
1731 XEvent* xevent = xev;
1732 xevent->xkey.keycode = XKeysymToKeycode(gfx::GetXDisplay(), XK_Control_L);
1733 xevent->xkey.send_event = True; // XSendEvent() always does this.
1734 ui::KeyEvent keyevent(xev);
1735 scoped_ptr<ui::Event> new_event;
1736 // Control should NOT be remapped to Alt if send_event
1737 // flag in the event is True.
1738 EXPECT_EQ(ui::EVENT_REWRITE_CONTINUE,
1739 rewriter.RewriteEvent(keyevent, &new_event));
1740 EXPECT_FALSE(new_event);
1745 TEST_F(EventRewriterTest, TestRewriteNonNativeEvent) {
1746 // Remap Control to Alt.
1747 TestingPrefServiceSyncable prefs;
1748 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1749 IntegerPrefMember control;
1750 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
1751 control.SetValue(chromeos::input_method::kAltKey);
1753 EventRewriter rewriter(NULL);
1754 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
1755 rewriter.set_pref_service_for_testing(&prefs);
1757 const int kTouchId = 2;
1758 gfx::Point location(0, 0);
1759 ui::TouchEvent press(
1760 ui::ET_TOUCH_PRESSED, location, kTouchId, base::TimeDelta());
1761 press.set_flags(ui::EF_CONTROL_DOWN);
1762 #if defined(USE_X11)
1763 ui::UpdateX11EventForFlags(&press);
1766 scoped_ptr<ui::Event> new_event;
1767 rewriter.RewriteEvent(press, &new_event);
1768 EXPECT_TRUE(new_event);
1769 // Control should be remapped to Alt.
1770 EXPECT_EQ(ui::EF_ALT_DOWN,
1771 new_event->flags() & (ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN));
1774 // Keeps a buffer of handled events.
1775 class EventBuffer : public ui::test::TestEventProcessor {
1778 virtual ~EventBuffer() {}
1780 void PopEvents(ScopedVector<ui::Event>* events) {
1782 events->swap(events_);
1786 // ui::EventProcessor overrides:
1787 virtual ui::EventDispatchDetails OnEventFromSource(
1788 ui::Event* event) override {
1789 if (event->IsKeyEvent()) {
1790 events_.push_back(new ui::KeyEvent(*static_cast<ui::KeyEvent*>(event)));
1791 } else if (event->IsMouseWheelEvent()) {
1793 new ui::MouseWheelEvent(*static_cast<ui::MouseWheelEvent*>(event)));
1794 } else if (event->IsMouseEvent()) {
1796 new ui::MouseEvent(*static_cast<ui::MouseEvent*>(event)));
1798 return ui::EventDispatchDetails();
1801 ScopedVector<ui::Event> events_;
1803 DISALLOW_COPY_AND_ASSIGN(EventBuffer);
1806 // Trivial EventSource that does nothing but send events.
1807 class TestEventSource : public ui::EventSource {
1809 explicit TestEventSource(ui::EventProcessor* processor)
1810 : processor_(processor) {}
1811 virtual ui::EventProcessor* GetEventProcessor() override {
1814 ui::EventDispatchDetails Send(ui::Event* event) {
1815 return SendEventToProcessor(event);
1819 ui::EventProcessor* processor_;
1822 // Tests of event rewriting that depend on the Ash window manager.
1823 class EventRewriterAshTest : public ash::test::AshTestBase {
1825 EventRewriterAshTest()
1826 : source_(&buffer_),
1827 fake_user_manager_(new chromeos::FakeUserManager),
1828 user_manager_enabler_(fake_user_manager_) {}
1829 virtual ~EventRewriterAshTest() {}
1831 bool RewriteFunctionKeys(const ui::Event& event,
1832 scoped_ptr<ui::Event>* rewritten_event) {
1833 return rewriter_->RewriteEvent(event, rewritten_event);
1836 ui::EventDispatchDetails Send(ui::Event* event) {
1837 return source_.Send(event);
1840 void SendKeyEvent(ui::EventType type, ui::KeyboardCode key_code) {
1841 ui::KeyEvent press(type, key_code, ui::EF_NONE);
1842 ui::EventDispatchDetails details = Send(&press);
1843 CHECK(!details.dispatcher_destroyed);
1846 void SendActivateStickyKeyPattern(ui::KeyboardCode key_code) {
1847 SendKeyEvent(ui::ET_KEY_PRESSED, key_code);
1848 SendKeyEvent(ui::ET_KEY_RELEASED, key_code);
1852 TestingPrefServiceSyncable* prefs() { return &prefs_; }
1854 void PopEvents(ScopedVector<ui::Event>* events) {
1855 buffer_.PopEvents(events);
1858 virtual void SetUp() override {
1859 AshTestBase::SetUp();
1860 sticky_keys_controller_ =
1861 ash::Shell::GetInstance()->sticky_keys_controller();
1862 rewriter_.reset(new EventRewriter(sticky_keys_controller_));
1863 chromeos::Preferences::RegisterProfilePrefs(prefs_.registry());
1864 rewriter_->set_pref_service_for_testing(&prefs_);
1865 #if defined(USE_X11)
1866 ui::SetUpTouchPadForTest(kTouchPadDeviceId);
1868 source_.AddEventRewriter(rewriter_.get());
1869 sticky_keys_controller_->Enable(true);
1872 virtual void TearDown() override {
1874 AshTestBase::TearDown();
1878 ash::StickyKeysController* sticky_keys_controller_;
1881 scoped_ptr<EventRewriter> rewriter_;
1883 EventBuffer buffer_;
1884 TestEventSource source_;
1886 chromeos::FakeUserManager* fake_user_manager_; // Not owned.
1887 chromeos::ScopedUserManagerEnabler user_manager_enabler_;
1888 TestingPrefServiceSyncable prefs_;
1890 DISALLOW_COPY_AND_ASSIGN(EventRewriterAshTest);
1893 TEST_F(EventRewriterAshTest, TopRowKeysAreFunctionKeys) {
1894 scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(1));
1895 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window.get());
1896 window_state->Activate();
1897 ScopedVector<ui::Event> events;
1899 // Create a simulated keypress of F1 targetted at the window.
1900 ui::KeyEvent press_f1(ui::ET_KEY_PRESSED, ui::VKEY_F1, ui::EF_NONE);
1902 // Simulate an apps v2 window that has requested top row keys as function
1903 // keys. The event should not be rewritten.
1904 window_state->set_top_row_keys_are_function_keys(true);
1905 ui::EventDispatchDetails details = Send(&press_f1);
1906 ASSERT_FALSE(details.dispatcher_destroyed);
1908 EXPECT_EQ(1u, events.size());
1910 GetExpectedResultAsString(ui::VKEY_F1, ui::EF_NONE, ui::ET_KEY_PRESSED),
1911 GetKeyEventAsString(*static_cast<ui::KeyEvent*>(events[0])));
1913 // The event should also not be rewritten if the send-function-keys pref is
1914 // additionally set, for both apps v2 and regular windows.
1915 BooleanPrefMember send_function_keys_pref;
1916 send_function_keys_pref.Init(prefs::kLanguageSendFunctionKeys, prefs());
1917 send_function_keys_pref.SetValue(true);
1918 window_state->set_top_row_keys_are_function_keys(false);
1919 details = Send(&press_f1);
1920 ASSERT_FALSE(details.dispatcher_destroyed);
1922 EXPECT_EQ(1u, events.size());
1924 GetExpectedResultAsString(ui::VKEY_F1, ui::EF_NONE, ui::ET_KEY_PRESSED),
1925 GetKeyEventAsString(*static_cast<ui::KeyEvent*>(events[0])));
1927 // If the pref isn't set when an event is sent to a regular window, F1 is
1928 // rewritten to the back key.
1929 send_function_keys_pref.SetValue(false);
1930 details = Send(&press_f1);
1931 ASSERT_FALSE(details.dispatcher_destroyed);
1933 EXPECT_EQ(1u, events.size());
1934 EXPECT_EQ(GetExpectedResultAsString(
1935 ui::VKEY_BROWSER_BACK, ui::EF_NONE, ui::ET_KEY_PRESSED),
1936 GetKeyEventAsString(*static_cast<ui::KeyEvent*>(events[0])));
1939 TEST_F(EventRewriterTest, TestRewrittenModifierClick) {
1940 std::vector<unsigned int> device_list;
1941 device_list.push_back(10);
1942 ui::TouchFactory::GetInstance()->SetPointerDeviceForTest(device_list);
1944 // Remap Control to Alt.
1945 TestingPrefServiceSyncable prefs;
1946 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1947 IntegerPrefMember control;
1948 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
1949 control.SetValue(chromeos::input_method::kAltKey);
1951 EventRewriter rewriter(NULL);
1952 rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
1953 rewriter.set_pref_service_for_testing(&prefs);
1955 // Check that Control + Left Button is converted (via Alt + Left Button)
1957 ui::ScopedXI2Event xev;
1958 xev.InitGenericButtonEvent(10,
1959 ui::ET_MOUSE_PRESSED,
1961 ui::EF_LEFT_MOUSE_BUTTON | ui::EF_CONTROL_DOWN);
1962 ui::MouseEvent press(xev);
1964 EXPECT_EQ(ui::ET_MOUSE_PRESSED, press.type());
1965 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON | ui::EF_CONTROL_DOWN, press.flags());
1966 scoped_ptr<ui::Event> new_event;
1967 const ui::MouseEvent* result =
1968 RewriteMouseButtonEvent(&rewriter, press, &new_event);
1969 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & result->flags());
1970 EXPECT_FALSE(ui::EF_LEFT_MOUSE_BUTTON & result->flags());
1971 EXPECT_FALSE(ui::EF_CONTROL_DOWN & result->flags());
1972 EXPECT_FALSE(ui::EF_ALT_DOWN & result->flags());
1973 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & result->flags());
1976 TEST_F(EventRewriterTest, DontRewriteIfNotRewritten) {
1977 // TODO(kpschoedel): pending changes for crbug.com/360377
1978 // to |chromeos::EventRewriter::RewriteLocatedEvent()
1979 std::vector<unsigned int> device_list;
1980 device_list.push_back(10);
1981 device_list.push_back(11);
1982 ui::TouchFactory::GetInstance()->SetPointerDeviceForTest(device_list);
1983 TestingPrefServiceSyncable prefs;
1984 EventRewriter rewriter(NULL);
1985 rewriter.set_pref_service_for_testing(&prefs);
1986 const int kLeftAndAltFlag = ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN;
1988 // Test Alt + Left click.
1990 ui::MouseEvent press(ui::ET_MOUSE_PRESSED,
1994 ui::EF_LEFT_MOUSE_BUTTON);
1995 ui::EventTestApi test_press(&press);
1996 test_press.set_source_device_id(10);
1998 EXPECT_EQ(ui::ET_MOUSE_PRESSED, press.type());
1999 EXPECT_EQ(kLeftAndAltFlag, press.flags());
2000 scoped_ptr<ui::Event> new_event;
2001 const ui::MouseEvent* result =
2002 RewriteMouseButtonEvent(&rewriter, press, &new_event);
2003 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & result->flags());
2004 EXPECT_FALSE(kLeftAndAltFlag & result->flags());
2005 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, result->changed_button_flags());
2008 ui::MouseEvent release(ui::ET_MOUSE_RELEASED,
2012 ui::EF_LEFT_MOUSE_BUTTON);
2013 ui::EventTestApi test_release(&release);
2014 test_release.set_source_device_id(10);
2015 scoped_ptr<ui::Event> new_event;
2016 const ui::MouseEvent* result =
2017 RewriteMouseButtonEvent(&rewriter, release, &new_event);
2018 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & result->flags());
2019 EXPECT_FALSE(kLeftAndAltFlag & result->flags());
2020 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, result->changed_button_flags());
2022 #if defined(USE_X11)
2023 // Test Alt + Left click, using XI2 native events.
2025 ui::ScopedXI2Event xev;
2026 xev.InitGenericButtonEvent(
2027 10, ui::ET_MOUSE_PRESSED, gfx::Point(), kLeftAndAltFlag);
2028 ui::MouseEvent press(xev);
2030 EXPECT_EQ(ui::ET_MOUSE_PRESSED, press.type());
2031 EXPECT_EQ(kLeftAndAltFlag, press.flags());
2032 scoped_ptr<ui::Event> new_event;
2033 const ui::MouseEvent* result =
2034 RewriteMouseButtonEvent(&rewriter, press, &new_event);
2035 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & result->flags());
2036 EXPECT_FALSE(kLeftAndAltFlag & result->flags());
2037 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, result->changed_button_flags());
2040 ui::ScopedXI2Event xev;
2041 xev.InitGenericButtonEvent(
2042 10, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
2043 ui::MouseEvent release(xev);
2044 scoped_ptr<ui::Event> new_event;
2045 const ui::MouseEvent* result =
2046 RewriteMouseButtonEvent(&rewriter, release, &new_event);
2047 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & result->flags());
2048 EXPECT_FALSE(kLeftAndAltFlag & result->flags());
2049 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, result->changed_button_flags());
2053 // No ALT in frst click.
2055 ui::MouseEvent press(ui::ET_MOUSE_PRESSED,
2058 ui::EF_LEFT_MOUSE_BUTTON,
2059 ui::EF_LEFT_MOUSE_BUTTON);
2060 ui::EventTestApi test_press(&press);
2061 test_press.set_source_device_id(10);
2062 scoped_ptr<ui::Event> new_event;
2063 const ui::MouseEvent* result =
2064 RewriteMouseButtonEvent(&rewriter, press, &new_event);
2065 EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & result->flags());
2066 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, result->changed_button_flags());
2069 ui::MouseEvent release(ui::ET_MOUSE_RELEASED,
2073 ui::EF_LEFT_MOUSE_BUTTON);
2074 ui::EventTestApi test_release(&release);
2075 test_release.set_source_device_id(10);
2076 scoped_ptr<ui::Event> new_event;
2077 const ui::MouseEvent* result =
2078 RewriteMouseButtonEvent(&rewriter, release, &new_event);
2079 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN) & result->flags());
2080 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, result->changed_button_flags());
2082 #if defined(USE_X11)
2083 // No ALT in frst click, using XI2 native events.
2085 ui::ScopedXI2Event xev;
2086 xev.InitGenericButtonEvent(
2087 10, ui::ET_MOUSE_PRESSED, gfx::Point(), ui::EF_LEFT_MOUSE_BUTTON);
2088 ui::MouseEvent press(xev);
2089 scoped_ptr<ui::Event> new_event;
2090 const ui::MouseEvent* result =
2091 RewriteMouseButtonEvent(&rewriter, press, &new_event);
2092 EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & result->flags());
2093 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, result->changed_button_flags());
2096 ui::ScopedXI2Event xev;
2097 xev.InitGenericButtonEvent(
2098 10, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
2099 ui::MouseEvent release(xev);
2100 scoped_ptr<ui::Event> new_event;
2101 const ui::MouseEvent* result =
2102 RewriteMouseButtonEvent(&rewriter, release, &new_event);
2103 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN) & result->flags());
2104 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, result->changed_button_flags());
2108 // ALT on different device.
2110 ui::MouseEvent press(ui::ET_MOUSE_PRESSED,
2114 ui::EF_LEFT_MOUSE_BUTTON);
2115 ui::EventTestApi test_press(&press);
2116 test_press.set_source_device_id(11);
2117 scoped_ptr<ui::Event> new_event;
2118 const ui::MouseEvent* result =
2119 RewriteMouseButtonEvent(&rewriter, press, &new_event);
2120 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & result->flags());
2121 EXPECT_FALSE(kLeftAndAltFlag & result->flags());
2122 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, result->changed_button_flags());
2125 ui::MouseEvent release(ui::ET_MOUSE_RELEASED,
2129 ui::EF_LEFT_MOUSE_BUTTON);
2130 ui::EventTestApi test_release(&release);
2131 test_release.set_source_device_id(10);
2132 scoped_ptr<ui::Event> new_event;
2133 const ui::MouseEvent* result =
2134 RewriteMouseButtonEvent(&rewriter, release, &new_event);
2135 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN) & result->flags());
2136 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, result->changed_button_flags());
2139 ui::MouseEvent release(ui::ET_MOUSE_RELEASED,
2143 ui::EF_LEFT_MOUSE_BUTTON);
2144 ui::EventTestApi test_release(&release);
2145 test_release.set_source_device_id(11);
2146 scoped_ptr<ui::Event> new_event;
2147 const ui::MouseEvent* result =
2148 RewriteMouseButtonEvent(&rewriter, release, &new_event);
2149 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & result->flags());
2150 EXPECT_FALSE(kLeftAndAltFlag & result->flags());
2151 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, result->changed_button_flags());
2153 #if defined(USE_X11)
2154 // ALT on different device, using XI2 native events.
2156 ui::ScopedXI2Event xev;
2157 xev.InitGenericButtonEvent(
2158 11, ui::ET_MOUSE_PRESSED, gfx::Point(), kLeftAndAltFlag);
2159 ui::MouseEvent press(xev);
2160 scoped_ptr<ui::Event> new_event;
2161 const ui::MouseEvent* result =
2162 RewriteMouseButtonEvent(&rewriter, press, &new_event);
2163 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & result->flags());
2164 EXPECT_FALSE(kLeftAndAltFlag & result->flags());
2165 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, result->changed_button_flags());
2168 ui::ScopedXI2Event xev;
2169 xev.InitGenericButtonEvent(
2170 10, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
2171 ui::MouseEvent release(xev);
2172 scoped_ptr<ui::Event> new_event;
2173 const ui::MouseEvent* result =
2174 RewriteMouseButtonEvent(&rewriter, release, &new_event);
2175 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN) & result->flags());
2176 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, result->changed_button_flags());
2179 ui::ScopedXI2Event xev;
2180 xev.InitGenericButtonEvent(
2181 11, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
2182 ui::MouseEvent release(xev);
2183 scoped_ptr<ui::Event> new_event;
2184 const ui::MouseEvent* result =
2185 RewriteMouseButtonEvent(&rewriter, release, &new_event);
2186 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & result->flags());
2187 EXPECT_FALSE(kLeftAndAltFlag & result->flags());
2188 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, result->changed_button_flags());
2193 TEST_F(EventRewriterAshTest, StickyKeyEventDispatchImpl) {
2194 // Test the actual key event dispatch implementation.
2195 ScopedVector<ui::Event> events;
2197 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2199 EXPECT_EQ(1u, events.size());
2200 EXPECT_EQ(ui::ET_KEY_PRESSED, events[0]->type());
2201 EXPECT_EQ(ui::VKEY_CONTROL,
2202 static_cast<ui::KeyEvent*>(events[0])->key_code());
2204 // Test key press event is correctly modified and modifier release
2206 ui::KeyEvent press(ui::ET_KEY_PRESSED, ui::VKEY_C, ui::EF_NONE);
2207 ui::EventDispatchDetails details = Send(&press);
2209 EXPECT_EQ(2u, events.size());
2210 EXPECT_EQ(ui::ET_KEY_PRESSED, events[0]->type());
2211 EXPECT_EQ(ui::VKEY_C, static_cast<ui::KeyEvent*>(events[0])->key_code());
2212 EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
2213 EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type());
2214 EXPECT_EQ(ui::VKEY_CONTROL,
2215 static_cast<ui::KeyEvent*>(events[1])->key_code());
2217 // Test key release event is not modified.
2218 ui::KeyEvent release(ui::ET_KEY_RELEASED, ui::VKEY_C, ui::EF_NONE);
2219 details = Send(&release);
2220 ASSERT_FALSE(details.dispatcher_destroyed);
2222 EXPECT_EQ(1u, events.size());
2223 EXPECT_EQ(ui::ET_KEY_RELEASED, events[0]->type());
2224 EXPECT_EQ(ui::VKEY_C, static_cast<ui::KeyEvent*>(events[0])->key_code());
2225 EXPECT_FALSE(events[0]->flags() & ui::EF_CONTROL_DOWN);
2228 TEST_F(EventRewriterAshTest, MouseEventDispatchImpl) {
2229 ScopedVector<ui::Event> events;
2231 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2234 // Test mouse press event is correctly modified.
2235 gfx::Point location(0, 0);
2236 ui::MouseEvent press(ui::ET_MOUSE_PRESSED,
2239 ui::EF_LEFT_MOUSE_BUTTON,
2240 ui::EF_LEFT_MOUSE_BUTTON);
2241 ui::EventDispatchDetails details = Send(&press);
2242 ASSERT_FALSE(details.dispatcher_destroyed);
2244 EXPECT_EQ(1u, events.size());
2245 EXPECT_EQ(ui::ET_MOUSE_PRESSED, events[0]->type());
2246 EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
2248 // Test mouse release event is correctly modified and modifier release
2249 // event is sent. The mouse event should have the correct DIP location.
2250 ui::MouseEvent release(ui::ET_MOUSE_RELEASED,
2253 ui::EF_LEFT_MOUSE_BUTTON,
2254 ui::EF_LEFT_MOUSE_BUTTON);
2255 details = Send(&release);
2256 ASSERT_FALSE(details.dispatcher_destroyed);
2258 EXPECT_EQ(2u, events.size());
2259 EXPECT_EQ(ui::ET_MOUSE_RELEASED, events[0]->type());
2260 EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
2261 EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type());
2262 EXPECT_EQ(ui::VKEY_CONTROL,
2263 static_cast<ui::KeyEvent*>(events[1])->key_code());
2266 TEST_F(EventRewriterAshTest, MouseWheelEventDispatchImpl) {
2267 ScopedVector<ui::Event> events;
2269 // Test positive mouse wheel event is correctly modified and modifier release
2271 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2273 gfx::Point location(0, 0);
2274 ui::MouseEvent mev(ui::ET_MOUSEWHEEL,
2277 ui::EF_LEFT_MOUSE_BUTTON,
2278 ui::EF_LEFT_MOUSE_BUTTON);
2279 ui::MouseWheelEvent positive(mev, 0, ui::MouseWheelEvent::kWheelDelta);
2280 ui::EventDispatchDetails details = Send(&positive);
2281 ASSERT_FALSE(details.dispatcher_destroyed);
2283 EXPECT_EQ(2u, events.size());
2284 EXPECT_TRUE(events[0]->IsMouseWheelEvent());
2285 EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
2286 EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type());
2287 EXPECT_EQ(ui::VKEY_CONTROL,
2288 static_cast<ui::KeyEvent*>(events[1])->key_code());
2290 // Test negative mouse wheel event is correctly modified and modifier release
2292 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2294 ui::MouseWheelEvent negative(mev, 0, -ui::MouseWheelEvent::kWheelDelta);
2295 details = Send(&negative);
2296 ASSERT_FALSE(details.dispatcher_destroyed);
2298 EXPECT_EQ(2u, events.size());
2299 EXPECT_TRUE(events[0]->IsMouseWheelEvent());
2300 EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
2301 EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type());
2302 EXPECT_EQ(ui::VKEY_CONTROL,
2303 static_cast<ui::KeyEvent*>(events[1])->key_code());
2306 class StickyKeysOverlayTest : public EventRewriterAshTest {
2308 StickyKeysOverlayTest() : overlay_(NULL) {}
2310 virtual ~StickyKeysOverlayTest() {}
2312 virtual void SetUp() override {
2313 EventRewriterAshTest::SetUp();
2314 overlay_ = sticky_keys_controller_->GetOverlayForTest();
2315 ASSERT_TRUE(overlay_);
2318 ash::StickyKeysOverlay* overlay_;
2321 TEST_F(StickyKeysOverlayTest, OneModifierEnabled) {
2322 EXPECT_FALSE(overlay_->is_visible());
2323 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2324 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2326 // Pressing modifier key should show overlay.
2327 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2328 EXPECT_TRUE(overlay_->is_visible());
2329 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED,
2330 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2332 // Pressing a normal key should hide overlay.
2333 SendActivateStickyKeyPattern(ui::VKEY_T);
2334 EXPECT_FALSE(overlay_->is_visible());
2335 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2336 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2339 TEST_F(StickyKeysOverlayTest, TwoModifiersEnabled) {
2340 EXPECT_FALSE(overlay_->is_visible());
2341 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2342 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2343 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2344 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
2346 // Pressing two modifiers should show overlay.
2347 SendActivateStickyKeyPattern(ui::VKEY_SHIFT);
2348 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2349 EXPECT_TRUE(overlay_->is_visible());
2350 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED,
2351 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
2352 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED,
2353 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2355 // Pressing a normal key should hide overlay.
2356 SendActivateStickyKeyPattern(ui::VKEY_N);
2357 EXPECT_FALSE(overlay_->is_visible());
2358 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2359 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2360 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2361 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
2364 TEST_F(StickyKeysOverlayTest, LockedModifier) {
2365 EXPECT_FALSE(overlay_->is_visible());
2366 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2367 overlay_->GetModifierKeyState(ui::EF_ALT_DOWN));
2369 // Pressing a modifier key twice should lock modifier and show overlay.
2370 SendActivateStickyKeyPattern(ui::VKEY_LMENU);
2371 SendActivateStickyKeyPattern(ui::VKEY_LMENU);
2372 EXPECT_TRUE(overlay_->is_visible());
2373 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED,
2374 overlay_->GetModifierKeyState(ui::EF_ALT_DOWN));
2376 // Pressing a normal key should not hide overlay.
2377 SendActivateStickyKeyPattern(ui::VKEY_D);
2378 EXPECT_TRUE(overlay_->is_visible());
2379 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED,
2380 overlay_->GetModifierKeyState(ui::EF_ALT_DOWN));
2383 TEST_F(StickyKeysOverlayTest, LockedAndNormalModifier) {
2384 EXPECT_FALSE(overlay_->is_visible());
2385 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2386 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2387 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2388 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
2390 // Pressing a modifier key twice should lock modifier and show overlay.
2391 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2392 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2393 EXPECT_TRUE(overlay_->is_visible());
2394 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED,
2395 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2397 // Pressing another modifier key should still show overlay.
2398 SendActivateStickyKeyPattern(ui::VKEY_SHIFT);
2399 EXPECT_TRUE(overlay_->is_visible());
2400 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED,
2401 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2402 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED,
2403 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
2405 // Pressing a normal key should not hide overlay but disable normal modifier.
2406 SendActivateStickyKeyPattern(ui::VKEY_D);
2407 EXPECT_TRUE(overlay_->is_visible());
2408 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED,
2409 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2410 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2411 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
2414 TEST_F(StickyKeysOverlayTest, ModifiersDisabled) {
2415 EXPECT_FALSE(overlay_->is_visible());
2416 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2417 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2418 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2419 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
2420 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2421 overlay_->GetModifierKeyState(ui::EF_ALT_DOWN));
2422 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2423 overlay_->GetModifierKeyState(ui::EF_COMMAND_DOWN));
2425 // Enable modifiers.
2426 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2427 SendActivateStickyKeyPattern(ui::VKEY_SHIFT);
2428 SendActivateStickyKeyPattern(ui::VKEY_SHIFT);
2429 SendActivateStickyKeyPattern(ui::VKEY_LMENU);
2430 SendActivateStickyKeyPattern(ui::VKEY_COMMAND);
2431 SendActivateStickyKeyPattern(ui::VKEY_COMMAND);
2433 EXPECT_TRUE(overlay_->is_visible());
2434 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED,
2435 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2436 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED,
2437 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
2438 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED,
2439 overlay_->GetModifierKeyState(ui::EF_ALT_DOWN));
2440 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED,
2441 overlay_->GetModifierKeyState(ui::EF_COMMAND_DOWN));
2443 // Disable modifiers and overlay should be hidden.
2444 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2445 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2446 SendActivateStickyKeyPattern(ui::VKEY_SHIFT);
2447 SendActivateStickyKeyPattern(ui::VKEY_LMENU);
2448 SendActivateStickyKeyPattern(ui::VKEY_LMENU);
2449 SendActivateStickyKeyPattern(ui::VKEY_COMMAND);
2451 EXPECT_FALSE(overlay_->is_visible());
2452 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2453 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
2454 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2455 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
2456 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2457 overlay_->GetModifierKeyState(ui::EF_ALT_DOWN));
2458 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED,
2459 overlay_->GetModifierKeyState(ui::EF_COMMAND_DOWN));
2462 TEST_F(StickyKeysOverlayTest, ModifierVisibility) {
2463 // All but AltGr and Mod3 should initially be visible.
2464 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_CONTROL_DOWN));
2465 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_SHIFT_DOWN));
2466 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_ALT_DOWN));
2467 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_COMMAND_DOWN));
2468 EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_ALTGR_DOWN));
2469 EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_MOD3_DOWN));
2471 // Turn all modifiers on.
2472 sticky_keys_controller_->SetModifiersEnabled(true, true);
2473 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_CONTROL_DOWN));
2474 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_SHIFT_DOWN));
2475 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_ALT_DOWN));
2476 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_COMMAND_DOWN));
2477 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_ALTGR_DOWN));
2478 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_MOD3_DOWN));
2481 sticky_keys_controller_->SetModifiersEnabled(false, true);
2482 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_ALTGR_DOWN));
2483 EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_MOD3_DOWN));
2486 sticky_keys_controller_->SetModifiersEnabled(true, false);
2487 EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_ALTGR_DOWN));
2488 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_MOD3_DOWN));
2490 // Turn off AltGr and Mod3.
2491 sticky_keys_controller_->SetModifiersEnabled(false, false);
2492 EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_ALTGR_DOWN));
2493 EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_MOD3_DOWN));
2496 } // namespace chromeos