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/scoped_user_manager_enabler.h"
21 #include "chrome/browser/chromeos/preferences.h"
22 #include "chrome/common/pref_names.h"
23 #include "chrome/test/base/testing_pref_service_syncable.h"
24 #include "chromeos/chromeos_switches.h"
25 #include "components/user_manager/fake_user_manager.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "ui/aura/window.h"
28 #include "ui/aura/window_tree_host.h"
29 #include "ui/base/ime/chromeos/fake_ime_keyboard.h"
30 #include "ui/events/event.h"
31 #include "ui/events/event_rewriter.h"
32 #include "ui/events/event_utils.h"
33 #include "ui/events/keycodes/dom/dom_code.h"
34 #include "ui/events/keycodes/dom/dom_key.h"
35 #include "ui/events/keycodes/dom/keycode_converter.h"
36 #include "ui/events/test/events_test_utils.h"
37 #include "ui/events/test/test_event_processor.h"
40 #include <X11/keysym.h>
42 #include "ui/events/devices/x11/touch_factory_x11.h"
43 #include "ui/events/event_utils.h"
44 #include "ui/events/test/events_test_utils_x11.h"
45 #include "ui/gfx/x/x11_types.h"
50 // The device id of the test touchpad device.
52 const int kTouchPadDeviceId
= 1;
53 const int kMasterKeyboardDeviceId
= 3;
55 const int kKeyboardDeviceId
= 2;
57 std::string
GetExpectedResultAsString(ui::EventType ui_type
,
58 ui::KeyboardCode ui_keycode
,
60 int ui_flags
, // ui::EventFlags
62 base::char16 character
) {
63 return base::StringPrintf("ui_keycode=0x%X ui_flags=0x%X ui_type=%d",
65 ui_flags
& ~ui::EF_IS_REPEAT
,
69 std::string
GetKeyEventAsString(const ui::KeyEvent
& keyevent
) {
70 return GetExpectedResultAsString(
71 keyevent
.type(), keyevent
.key_code(), keyevent
.code(), keyevent
.flags(),
72 keyevent
.GetDomKey(), keyevent
.GetCharacter());
75 std::string
GetRewrittenEventAsString(chromeos::EventRewriter
* rewriter
,
76 ui::EventType ui_type
,
77 ui::KeyboardCode ui_keycode
,
79 int ui_flags
, // ui::EventFlags
81 base::char16 character
) {
82 const ui::KeyEvent
event(ui_type
, ui_keycode
, code
, ui_flags
, key
, character
,
83 ui::EventTimeForNow());
84 scoped_ptr
<ui::Event
> new_event
;
85 rewriter
->RewriteEvent(event
, &new_event
);
87 return GetKeyEventAsString(
88 static_cast<const ui::KeyEvent
&>(*new_event
.get()));
89 return GetKeyEventAsString(event
);
92 // Table entry for simple single key event rewriting tests.
96 TEST_VKEY
= 1 << 0, // Test ui::KeyEvent with no native event
97 TEST_X11
= 1 << 1, // Test ui::KeyEvent with native XKeyEvent
98 TEST_ALL
= TEST_VKEY
| TEST_X11
,
99 // Special test flags:
100 NUMPAD
= 1 << 8, // Reset the XKB scan code on an X11 event based
101 // on the test DomCode, because
102 // |XKeysymForWindowsKeyCode()| can not distinguish
103 // between pairs like XK_Insert and XK_KP_Insert.
108 ui::KeyboardCode key_code
;
110 int flags
; // ui::EventFlags
112 base::char16 character
;
116 std::string
GetTestCaseAsString(ui::EventType ui_type
,
117 const KeyTestCase::Event
& test
) {
118 return GetExpectedResultAsString(ui_type
, test
.key_code
, test
.code
,
119 test
.flags
, test
.key
, test
.character
);
123 // Check rewriting of an X11-based key event.
124 void CheckX11KeyTestCase(const std::string
& expected
,
125 chromeos::EventRewriter
* rewriter
,
126 const KeyTestCase
& test
,
128 ui::KeyEvent
xkey_event(xevent
);
129 // Rewrite the event and check the result.
130 scoped_ptr
<ui::Event
> new_event
;
131 rewriter
->RewriteEvent(xkey_event
, &new_event
);
132 ui::KeyEvent
& rewritten_key_event
=
133 new_event
? *static_cast<ui::KeyEvent
*>(new_event
.get()) : xkey_event
;
134 EXPECT_EQ(expected
, GetKeyEventAsString(rewritten_key_event
));
135 if ((rewritten_key_event
.key_code() != ui::VKEY_UNKNOWN
) &&
136 (rewritten_key_event
.native_event()->xkey
.keycode
!= 0)) {
137 // Build a new ui::KeyEvent from the rewritten native component,
138 // and check that it also matches the rewritten event.
139 EXPECT_TRUE(rewritten_key_event
.native_event());
140 ui::KeyEvent
from_native_event(rewritten_key_event
.native_event());
141 EXPECT_EQ(expected
, GetKeyEventAsString(from_native_event
));
146 // Tests a single stateless key rewrite operation.
147 void CheckKeyTestCase(chromeos::EventRewriter
* rewriter
,
148 const KeyTestCase
& test
) {
149 std::string expected
= GetTestCaseAsString(test
.type
, test
.expected
);
151 if (test
.test
& KeyTestCase::TEST_VKEY
) {
152 // Check rewriting of a non-native-based key event.
154 GetRewrittenEventAsString(
155 rewriter
, test
.type
, test
.input
.key_code
, test
.input
.code
,
156 test
.input
.flags
, test
.input
.key
, test
.input
.character
));
160 if (test
.test
& KeyTestCase::TEST_X11
) {
161 ui::ScopedXI2Event xev
;
162 // Test an XKeyEvent.
163 xev
.InitKeyEvent(test
.type
, test
.input
.key_code
, test
.input
.flags
);
164 XEvent
* xevent
= xev
;
165 DCHECK((xevent
->type
== KeyPress
) || (xevent
->type
== KeyRelease
));
166 if (test
.test
& KeyTestCase::NUMPAD
) {
167 xevent
->xkey
.keycode
=
168 ui::KeycodeConverter::DomCodeToNativeKeycode(test
.input
.code
);
170 int keycode
= xevent
->xkey
.keycode
;
172 CheckX11KeyTestCase(expected
, rewriter
, test
, xevent
);
173 // Test an XI2 GenericEvent.
174 xev
.InitGenericKeyEvent(kMasterKeyboardDeviceId
, kKeyboardDeviceId
,
175 test
.type
, test
.input
.key_code
, test
.input
.flags
);
177 DCHECK(xevent
->type
== GenericEvent
);
178 XIDeviceEvent
* xievent
=
179 static_cast<XIDeviceEvent
*>(xevent
->xcookie
.data
);
180 DCHECK((xievent
->evtype
== XI_KeyPress
) ||
181 (xievent
->evtype
== XI_KeyRelease
));
182 xievent
->detail
= keycode
;
183 CheckX11KeyTestCase(expected
, rewriter
, test
, xevent
);
193 class EventRewriterTest
: public ash::test::AshTestBase
{
196 : fake_user_manager_(new user_manager::FakeUserManager
),
197 user_manager_enabler_(fake_user_manager_
),
198 input_method_manager_mock_(NULL
) {}
199 ~EventRewriterTest() override
{}
201 void SetUp() override
{
202 input_method_manager_mock_
=
203 new chromeos::input_method::MockInputMethodManager
;
204 chromeos::input_method::InitializeForTesting(
205 input_method_manager_mock_
); // pass ownership
207 AshTestBase::SetUp();
210 void TearDown() override
{
211 AshTestBase::TearDown();
212 // Shutdown() deletes the IME mock object.
213 chromeos::input_method::Shutdown();
217 void TestRewriteNumPadKeys();
218 void TestRewriteNumPadKeysOnAppleKeyboard();
220 const ui::MouseEvent
* RewriteMouseButtonEvent(
221 chromeos::EventRewriter
* rewriter
,
222 const ui::MouseEvent
& event
,
223 scoped_ptr
<ui::Event
>* new_event
) {
224 rewriter
->RewriteMouseButtonEventForTesting(event
, new_event
);
225 return *new_event
? static_cast<const ui::MouseEvent
*>(new_event
->get())
229 user_manager::FakeUserManager
* fake_user_manager_
; // Not owned.
230 chromeos::ScopedUserManagerEnabler user_manager_enabler_
;
231 chromeos::input_method::MockInputMethodManager
* input_method_manager_mock_
;
234 TEST_F(EventRewriterTest
, TestRewriteCommandToControl
) {
235 // First, test with a PC keyboard.
236 TestingPrefServiceSyncable prefs
;
237 EventRewriter
rewriter(NULL
);
238 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
239 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
240 rewriter
.set_pref_service_for_testing(&prefs
);
242 KeyTestCase pc_keyboard_tests
[] = {
243 // VKEY_A, Alt modifier.
244 {KeyTestCase::TEST_ALL
,
249 ui::DomKey::CHARACTER
,
254 ui::DomKey::CHARACTER
,
257 // VKEY_A, Win modifier.
258 {KeyTestCase::TEST_ALL
,
263 ui::DomKey::CHARACTER
,
268 ui::DomKey::CHARACTER
,
271 // VKEY_A, Alt+Win modifier.
272 {KeyTestCase::TEST_ALL
,
276 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
277 ui::DomKey::CHARACTER
,
281 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
282 ui::DomKey::CHARACTER
,
285 // VKEY_LWIN (left Windows key), Alt modifier.
286 {KeyTestCase::TEST_ALL
,
289 ui::DomCode::OS_LEFT
,
290 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
294 ui::DomCode::OS_LEFT
,
295 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
299 // VKEY_RWIN (right Windows key), Alt modifier.
300 {KeyTestCase::TEST_ALL
,
303 ui::DomCode::OS_RIGHT
,
304 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
308 ui::DomCode::OS_RIGHT
,
309 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
314 for (size_t i
= 0; i
< arraysize(pc_keyboard_tests
); ++i
) {
316 CheckKeyTestCase(&rewriter
, pc_keyboard_tests
[i
]);
319 // An Apple keyboard reusing the ID, zero.
320 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "Apple Keyboard");
321 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
323 KeyTestCase apple_keyboard_tests
[] = {
324 // VKEY_A, Alt modifier.
325 {KeyTestCase::TEST_ALL
,
330 ui::DomKey::CHARACTER
,
335 ui::DomKey::CHARACTER
,
338 // VKEY_A, Win modifier.
339 {KeyTestCase::TEST_ALL
,
344 ui::DomKey::CHARACTER
,
349 ui::DomKey::CHARACTER
,
352 // VKEY_A, Alt+Win modifier.
353 {KeyTestCase::TEST_ALL
,
357 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
358 ui::DomKey::CHARACTER
,
362 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
363 ui::DomKey::CHARACTER
,
366 // VKEY_LWIN (left Windows key), Alt modifier.
367 {KeyTestCase::TEST_ALL
,
370 ui::DomCode::OS_LEFT
,
371 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
,
375 ui::DomCode::CONTROL_LEFT
,
376 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
380 // VKEY_RWIN (right Windows key), Alt modifier.
381 {KeyTestCase::TEST_ALL
,
384 ui::DomCode::OS_RIGHT
,
385 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
,
389 ui::DomCode::CONTROL_LEFT
,
390 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
395 for (size_t i
= 0; i
< arraysize(apple_keyboard_tests
); ++i
) {
397 CheckKeyTestCase(&rewriter
, apple_keyboard_tests
[i
]);
401 // For crbug.com/133896.
402 TEST_F(EventRewriterTest
, TestRewriteCommandToControlWithControlRemapped
) {
403 // Remap Control to Alt.
404 TestingPrefServiceSyncable prefs
;
405 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
406 IntegerPrefMember control
;
407 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
408 control
.SetValue(chromeos::input_method::kAltKey
);
410 EventRewriter
rewriter(NULL
);
411 rewriter
.set_pref_service_for_testing(&prefs
);
412 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
413 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
415 KeyTestCase pc_keyboard_tests
[] = {
416 // Control should be remapped to Alt.
417 {KeyTestCase::TEST_ALL
,
420 ui::DomCode::CONTROL_LEFT
,
425 ui::DomCode::ALT_LEFT
,
431 for (size_t i
= 0; i
< arraysize(pc_keyboard_tests
); ++i
) {
433 CheckKeyTestCase(&rewriter
, pc_keyboard_tests
[i
]);
436 // An Apple keyboard reusing the ID, zero.
437 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "Apple Keyboard");
438 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
440 KeyTestCase apple_keyboard_tests
[] = {
441 // VKEY_LWIN (left Command key) with Alt modifier. The remapped Command
442 // key should never be re-remapped to Alt.
443 {KeyTestCase::TEST_ALL
,
446 ui::DomCode::OS_LEFT
,
447 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
,
451 ui::DomCode::CONTROL_LEFT
,
452 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
456 // VKEY_RWIN (right Command key) with Alt modifier. The remapped Command
457 // key should never be re-remapped to Alt.
458 {KeyTestCase::TEST_ALL
,
461 ui::DomCode::OS_RIGHT
,
462 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
,
466 ui::DomCode::CONTROL_LEFT
,
467 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
472 for (size_t i
= 0; i
< arraysize(apple_keyboard_tests
); ++i
) {
474 CheckKeyTestCase(&rewriter
, apple_keyboard_tests
[i
]);
478 void EventRewriterTest::TestRewriteNumPadKeys() {
479 TestingPrefServiceSyncable prefs
;
480 EventRewriter
rewriter(NULL
);
481 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
482 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
483 rewriter
.set_pref_service_for_testing(&prefs
);
485 KeyTestCase tests
[] = {
486 // XK_KP_Insert (= NumPad 0 without Num Lock), no modifier.
487 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
490 ui::DomCode::NUMPAD0
,
495 ui::DomCode::NUMPAD0
,
497 ui::DomKey::CHARACTER
,
500 // XK_KP_Insert (= NumPad 0 without Num Lock), Alt modifier.
501 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
504 ui::DomCode::NUMPAD0
,
509 ui::DomCode::NUMPAD0
,
511 ui::DomKey::CHARACTER
,
514 // XK_KP_Delete (= NumPad . without Num Lock), Alt modifier.
515 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
518 ui::DomCode::NUMPAD_DECIMAL
,
523 ui::DomCode::NUMPAD_DECIMAL
,
525 ui::DomKey::CHARACTER
,
528 // XK_KP_End (= NumPad 1 without Num Lock), Alt modifier.
529 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
532 ui::DomCode::NUMPAD1
,
537 ui::DomCode::NUMPAD1
,
539 ui::DomKey::CHARACTER
,
542 // XK_KP_Down (= NumPad 2 without Num Lock), Alt modifier.
543 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
546 ui::DomCode::NUMPAD2
,
548 ui::DomKey::ARROW_DOWN
,
551 ui::DomCode::NUMPAD2
,
553 ui::DomKey::CHARACTER
,
556 // XK_KP_Next (= NumPad 3 without Num Lock), Alt modifier.
557 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
560 ui::DomCode::NUMPAD3
,
562 ui::DomKey::PAGE_DOWN
,
565 ui::DomCode::NUMPAD3
,
567 ui::DomKey::CHARACTER
,
570 // XK_KP_Left (= NumPad 4 without Num Lock), Alt modifier.
571 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
574 ui::DomCode::NUMPAD4
,
576 ui::DomKey::ARROW_LEFT
,
579 ui::DomCode::NUMPAD4
,
581 ui::DomKey::CHARACTER
,
584 // XK_KP_Begin (= NumPad 5 without Num Lock), Alt modifier.
585 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
588 ui::DomCode::NUMPAD5
,
593 ui::DomCode::NUMPAD5
,
595 ui::DomKey::CHARACTER
,
598 // XK_KP_Right (= NumPad 6 without Num Lock), Alt modifier.
599 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
602 ui::DomCode::NUMPAD6
,
604 ui::DomKey::ARROW_RIGHT
,
607 ui::DomCode::NUMPAD6
,
609 ui::DomKey::CHARACTER
,
612 // XK_KP_Home (= NumPad 7 without Num Lock), Alt modifier.
613 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
616 ui::DomCode::NUMPAD7
,
621 ui::DomCode::NUMPAD7
,
623 ui::DomKey::CHARACTER
,
626 // XK_KP_Up (= NumPad 8 without Num Lock), Alt modifier.
627 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
630 ui::DomCode::NUMPAD8
,
632 ui::DomKey::ARROW_UP
,
635 ui::DomCode::NUMPAD8
,
637 ui::DomKey::CHARACTER
,
640 // XK_KP_Prior (= NumPad 9 without Num Lock), Alt modifier.
641 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
644 ui::DomCode::NUMPAD9
,
649 ui::DomCode::NUMPAD9
,
651 ui::DomKey::CHARACTER
,
654 // XK_KP_0 (= NumPad 0 with Num Lock), Num Lock modifier.
655 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
658 ui::DomCode::NUMPAD0
,
660 ui::DomKey::CHARACTER
,
663 ui::DomCode::NUMPAD0
,
665 ui::DomKey::CHARACTER
,
668 // XK_KP_DECIMAL (= NumPad . with Num Lock), Num Lock modifier.
669 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
672 ui::DomCode::NUMPAD_DECIMAL
,
674 ui::DomKey::CHARACTER
,
677 ui::DomCode::NUMPAD_DECIMAL
,
679 ui::DomKey::CHARACTER
,
682 // XK_KP_1 (= NumPad 1 with Num Lock), Num Lock modifier.
683 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
686 ui::DomCode::NUMPAD1
,
688 ui::DomKey::CHARACTER
,
691 ui::DomCode::NUMPAD1
,
693 ui::DomKey::CHARACTER
,
696 // XK_KP_2 (= NumPad 2 with Num Lock), Num Lock modifier.
697 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
700 ui::DomCode::NUMPAD2
,
702 ui::DomKey::CHARACTER
,
705 ui::DomCode::NUMPAD2
,
707 ui::DomKey::CHARACTER
,
710 // XK_KP_3 (= NumPad 3 with Num Lock), Num Lock modifier.
711 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
714 ui::DomCode::NUMPAD3
,
716 ui::DomKey::CHARACTER
,
719 ui::DomCode::NUMPAD3
,
721 ui::DomKey::CHARACTER
,
724 // XK_KP_4 (= NumPad 4 with Num Lock), Num Lock modifier.
725 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
728 ui::DomCode::NUMPAD4
,
730 ui::DomKey::CHARACTER
,
733 ui::DomCode::NUMPAD4
,
735 ui::DomKey::CHARACTER
,
738 // XK_KP_5 (= NumPad 5 with Num Lock), Num Lock
740 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
743 ui::DomCode::NUMPAD5
,
745 ui::DomKey::CHARACTER
,
748 ui::DomCode::NUMPAD5
,
750 ui::DomKey::CHARACTER
,
753 // XK_KP_6 (= NumPad 6 with Num Lock), Num Lock
755 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
758 ui::DomCode::NUMPAD6
,
760 ui::DomKey::CHARACTER
,
763 ui::DomCode::NUMPAD6
,
765 ui::DomKey::CHARACTER
,
768 // XK_KP_7 (= NumPad 7 with Num Lock), Num Lock
770 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
773 ui::DomCode::NUMPAD7
,
775 ui::DomKey::CHARACTER
,
778 ui::DomCode::NUMPAD7
,
780 ui::DomKey::CHARACTER
,
783 // XK_KP_8 (= NumPad 8 with Num Lock), Num Lock
785 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
788 ui::DomCode::NUMPAD8
,
790 ui::DomKey::CHARACTER
,
793 ui::DomCode::NUMPAD8
,
795 ui::DomKey::CHARACTER
,
798 // XK_KP_9 (= NumPad 9 with Num Lock), Num Lock
800 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
803 ui::DomCode::NUMPAD9
,
805 ui::DomKey::CHARACTER
,
808 ui::DomCode::NUMPAD9
,
810 ui::DomKey::CHARACTER
,
814 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
816 CheckKeyTestCase(&rewriter
, tests
[i
]);
820 TEST_F(EventRewriterTest
, TestRewriteNumPadKeys
) {
821 TestRewriteNumPadKeys();
824 TEST_F(EventRewriterTest
, TestRewriteNumPadKeysWithDiamondKeyFlag
) {
825 // Make sure the num lock works correctly even when Diamond key exists.
826 const base::CommandLine
original_cl(*base::CommandLine::ForCurrentProcess());
827 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
828 chromeos::switches::kHasChromeOSDiamondKey
, "");
830 TestRewriteNumPadKeys();
831 *base::CommandLine::ForCurrentProcess() = original_cl
;
834 // Tests if the rewriter can handle a Command + Num Pad event.
835 void EventRewriterTest::TestRewriteNumPadKeysOnAppleKeyboard() {
836 TestingPrefServiceSyncable prefs
;
837 EventRewriter
rewriter(NULL
);
838 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "Apple Keyboard");
839 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
840 rewriter
.set_pref_service_for_testing(&prefs
);
842 KeyTestCase tests
[] = {
843 // XK_KP_End (= NumPad 1 without Num Lock), Win modifier.
844 // The result should be "Num Pad 1 with Control + Num Lock modifiers".
845 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
848 ui::DomCode::NUMPAD1
,
853 ui::DomCode::NUMPAD1
,
855 ui::DomKey::CHARACTER
,
858 // XK_KP_1 (= NumPad 1 with Num Lock), Win modifier.
859 // The result should also be "Num Pad 1 with Control + Num Lock
861 {KeyTestCase::TEST_ALL
| KeyTestCase::NUMPAD
,
864 ui::DomCode::NUMPAD1
,
866 ui::DomKey::CHARACTER
,
869 ui::DomCode::NUMPAD1
,
871 ui::DomKey::CHARACTER
,
874 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
876 CheckKeyTestCase(&rewriter
, tests
[i
]);
880 TEST_F(EventRewriterTest
, TestRewriteNumPadKeysOnAppleKeyboard
) {
881 TestRewriteNumPadKeysOnAppleKeyboard();
884 TEST_F(EventRewriterTest
,
885 TestRewriteNumPadKeysOnAppleKeyboardWithDiamondKeyFlag
) {
886 // Makes sure the num lock works correctly even when Diamond key exists.
887 const base::CommandLine
original_cl(*base::CommandLine::ForCurrentProcess());
888 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
889 chromeos::switches::kHasChromeOSDiamondKey
, "");
891 TestRewriteNumPadKeysOnAppleKeyboard();
892 *base::CommandLine::ForCurrentProcess() = original_cl
;
895 TEST_F(EventRewriterTest
, TestRewriteModifiersNoRemap
) {
896 TestingPrefServiceSyncable prefs
;
897 EventRewriter
rewriter(NULL
);
898 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
899 rewriter
.set_pref_service_for_testing(&prefs
);
901 KeyTestCase tests
[] = {
902 // Press Search. Confirm the event is not rewritten.
903 {KeyTestCase::TEST_ALL
,
905 {ui::VKEY_LWIN
, ui::DomCode::OS_LEFT
, ui::EF_NONE
, ui::DomKey::OS
, 0},
907 ui::DomCode::OS_LEFT
,
912 // Press left Control. Confirm the event is not rewritten.
913 {KeyTestCase::TEST_ALL
,
916 ui::DomCode::CONTROL_LEFT
,
921 ui::DomCode::CONTROL_LEFT
,
926 // Press right Control. Confirm the event is not rewritten.
927 {KeyTestCase::TEST_ALL
,
930 ui::DomCode::CONTROL_LEFT
,
935 ui::DomCode::CONTROL_LEFT
,
940 // Press left Alt. Confirm the event is not rewritten.
941 {KeyTestCase::TEST_ALL
,
944 ui::DomCode::ALT_LEFT
,
949 ui::DomCode::ALT_LEFT
,
954 // Press right Alt. Confirm the event is not rewritten.
955 {KeyTestCase::TEST_ALL
,
958 ui::DomCode::ALT_LEFT
,
963 ui::DomCode::ALT_LEFT
,
968 // Test KeyRelease event, just in case.
969 // Release Search. Confirm the release event is not rewritten.
970 {KeyTestCase::TEST_ALL
,
972 {ui::VKEY_LWIN
, ui::DomCode::OS_LEFT
, ui::EF_NONE
, ui::DomKey::OS
, 0},
973 {ui::VKEY_LWIN
, ui::DomCode::OS_LEFT
, ui::EF_NONE
, ui::DomKey::OS
, 0}},
976 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
978 CheckKeyTestCase(&rewriter
, tests
[i
]);
982 TEST_F(EventRewriterTest
, TestRewriteModifiersNoRemapMultipleKeys
) {
983 TestingPrefServiceSyncable prefs
;
984 EventRewriter
rewriter(NULL
);
985 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
986 rewriter
.set_pref_service_for_testing(&prefs
);
988 KeyTestCase tests
[] = {
989 // Press Alt with Shift. Confirm the event is not rewritten.
990 {KeyTestCase::TEST_ALL
,
993 ui::DomCode::ALT_LEFT
,
994 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
,
998 ui::DomCode::ALT_LEFT
,
999 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
,
1003 // Press Search with Caps Lock mask. Confirm the event is not rewritten.
1004 {KeyTestCase::TEST_ALL
,
1007 ui::DomCode::OS_LEFT
,
1008 ui::EF_CAPS_LOCK_DOWN
| ui::EF_COMMAND_DOWN
,
1012 ui::DomCode::OS_LEFT
,
1013 ui::EF_CAPS_LOCK_DOWN
| ui::EF_COMMAND_DOWN
,
1017 // Release Search with Caps Lock mask. Confirm the event is not rewritten.
1018 {KeyTestCase::TEST_ALL
,
1019 ui::ET_KEY_RELEASED
,
1021 ui::DomCode::OS_LEFT
,
1022 ui::EF_CAPS_LOCK_DOWN
,
1026 ui::DomCode::OS_LEFT
,
1027 ui::EF_CAPS_LOCK_DOWN
,
1031 // Press Shift+Ctrl+Alt+Search+A. Confirm the event is not rewritten.
1032 {KeyTestCase::TEST_ALL
,
1036 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
1037 ui::EF_COMMAND_DOWN
,
1038 ui::DomKey::CHARACTER
,
1042 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
1043 ui::EF_COMMAND_DOWN
,
1044 ui::DomKey::CHARACTER
,
1048 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
1050 CheckKeyTestCase(&rewriter
, tests
[i
]);
1054 TEST_F(EventRewriterTest
, TestRewriteModifiersDisableSome
) {
1055 // Disable Search and Control keys.
1056 TestingPrefServiceSyncable prefs
;
1057 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1058 IntegerPrefMember search
;
1059 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
1060 search
.SetValue(chromeos::input_method::kVoidKey
);
1061 IntegerPrefMember control
;
1062 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
1063 control
.SetValue(chromeos::input_method::kVoidKey
);
1065 EventRewriter
rewriter(NULL
);
1066 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1067 rewriter
.set_pref_service_for_testing(&prefs
);
1069 KeyTestCase disabled_modifier_tests
[] = {
1070 // Press Alt with Shift. This key press shouldn't be affected by the
1071 // pref. Confirm the event is not rewritten.
1072 {KeyTestCase::TEST_ALL
,
1075 ui::DomCode::ALT_LEFT
,
1076 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
,
1080 ui::DomCode::ALT_LEFT
,
1081 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
,
1085 // Press Search. Confirm the event is now VKEY_UNKNOWN.
1086 {KeyTestCase::TEST_ALL
,
1088 {ui::VKEY_LWIN
, ui::DomCode::OS_LEFT
, ui::EF_NONE
, ui::DomKey::OS
, 0},
1092 ui::DomKey::UNIDENTIFIED
,
1095 // Press Control. Confirm the event is now VKEY_UNKNOWN.
1096 {KeyTestCase::TEST_ALL
,
1099 ui::DomCode::CONTROL_LEFT
,
1100 ui::EF_CONTROL_DOWN
,
1101 ui::DomKey::CONTROL
,
1106 ui::DomKey::UNIDENTIFIED
,
1109 // Press Control+Search. Confirm the event is now VKEY_UNKNOWN
1110 // without any modifiers.
1111 {KeyTestCase::TEST_ALL
,
1114 ui::DomCode::OS_LEFT
,
1115 ui::EF_CONTROL_DOWN
,
1121 ui::DomKey::UNIDENTIFIED
,
1124 // Press Control+Search+a. Confirm the event is now VKEY_A without any
1126 {KeyTestCase::TEST_ALL
,
1130 ui::EF_CONTROL_DOWN
,
1131 ui::DomKey::CHARACTER
,
1136 ui::DomKey::CHARACTER
,
1139 // Press Control+Search+Alt+a. Confirm the event is now VKEY_A only with
1140 // the Alt modifier.
1141 {KeyTestCase::TEST_ALL
,
1145 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
1146 ui::DomKey::CHARACTER
,
1151 ui::DomKey::CHARACTER
,
1155 for (size_t i
= 0; i
< arraysize(disabled_modifier_tests
); ++i
) {
1157 CheckKeyTestCase(&rewriter
, disabled_modifier_tests
[i
]);
1160 // Remap Alt to Control.
1161 IntegerPrefMember alt
;
1162 alt
.Init(prefs::kLanguageRemapAltKeyTo
, &prefs
);
1163 alt
.SetValue(chromeos::input_method::kControlKey
);
1165 KeyTestCase tests
[] = {
1166 // Press left Alt. Confirm the event is now VKEY_CONTROL
1167 // even though the Control key itself is disabled.
1168 {KeyTestCase::TEST_ALL
,
1171 ui::DomCode::ALT_LEFT
,
1176 ui::DomCode::CONTROL_LEFT
,
1177 ui::EF_CONTROL_DOWN
,
1178 ui::DomKey::CONTROL
,
1181 // Press Alt+a. Confirm the event is now Control+a even though the Control
1182 // key itself is disabled.
1183 {KeyTestCase::TEST_ALL
,
1188 ui::DomKey::CHARACTER
,
1192 ui::EF_CONTROL_DOWN
,
1193 ui::DomKey::CHARACTER
,
1197 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
1199 CheckKeyTestCase(&rewriter
, tests
[i
]);
1203 TEST_F(EventRewriterTest
, TestRewriteModifiersRemapToControl
) {
1204 // Remap Search to Control.
1205 TestingPrefServiceSyncable prefs
;
1206 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1207 IntegerPrefMember search
;
1208 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
1209 search
.SetValue(chromeos::input_method::kControlKey
);
1211 EventRewriter
rewriter(NULL
);
1212 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1213 rewriter
.set_pref_service_for_testing(&prefs
);
1215 KeyTestCase s_tests
[] = {
1216 // Press Search. Confirm the event is now VKEY_CONTROL.
1217 {KeyTestCase::TEST_ALL
,
1220 ui::DomCode::OS_LEFT
,
1221 ui::EF_COMMAND_DOWN
,
1225 ui::DomCode::CONTROL_LEFT
,
1226 ui::EF_CONTROL_DOWN
,
1227 ui::DomKey::CONTROL
,
1231 for (size_t i
= 0; i
< arraysize(s_tests
); ++i
) {
1233 CheckKeyTestCase(&rewriter
, s_tests
[i
]);
1236 // Remap Alt to Control too.
1237 IntegerPrefMember alt
;
1238 alt
.Init(prefs::kLanguageRemapAltKeyTo
, &prefs
);
1239 alt
.SetValue(chromeos::input_method::kControlKey
);
1241 KeyTestCase sa_tests
[] = {
1242 // Press Alt. Confirm the event is now VKEY_CONTROL.
1243 {KeyTestCase::TEST_ALL
,
1246 ui::DomCode::ALT_LEFT
,
1251 ui::DomCode::CONTROL_LEFT
,
1252 ui::EF_CONTROL_DOWN
,
1253 ui::DomKey::CONTROL
,
1256 // Press Alt+Search. Confirm the event is now VKEY_CONTROL.
1257 {KeyTestCase::TEST_ALL
,
1260 ui::DomCode::OS_LEFT
,
1261 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
1265 ui::DomCode::CONTROL_LEFT
,
1266 ui::EF_CONTROL_DOWN
,
1267 ui::DomKey::CONTROL
,
1270 // Press Control+Alt+Search. Confirm the event is now VKEY_CONTROL.
1271 {KeyTestCase::TEST_ALL
,
1274 ui::DomCode::OS_LEFT
,
1275 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
1279 ui::DomCode::CONTROL_LEFT
,
1280 ui::EF_CONTROL_DOWN
,
1281 ui::DomKey::CONTROL
,
1284 // Press Shift+Control+Alt+Search. Confirm the event is now Control with
1285 // Shift and Control modifiers.
1286 {KeyTestCase::TEST_ALL
,
1289 ui::DomCode::OS_LEFT
,
1290 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
1291 ui::EF_COMMAND_DOWN
,
1295 ui::DomCode::CONTROL_LEFT
,
1296 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
1297 ui::DomKey::CONTROL
,
1300 // Press Shift+Control+Alt+Search+B. Confirm the event is now B with Shift
1301 // and Control modifiers.
1302 {KeyTestCase::TEST_ALL
,
1306 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
1307 ui::EF_COMMAND_DOWN
,
1308 ui::DomKey::CHARACTER
,
1312 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
1313 ui::DomKey::CHARACTER
,
1317 for (size_t i
= 0; i
< arraysize(sa_tests
); ++i
) {
1319 CheckKeyTestCase(&rewriter
, sa_tests
[i
]);
1323 TEST_F(EventRewriterTest
, TestRewriteModifiersRemapToEscape
) {
1324 // Remap Search to ESC.
1325 TestingPrefServiceSyncable prefs
;
1326 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1327 IntegerPrefMember search
;
1328 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
1329 search
.SetValue(chromeos::input_method::kEscapeKey
);
1331 EventRewriter
rewriter(NULL
);
1332 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1333 rewriter
.set_pref_service_for_testing(&prefs
);
1335 KeyTestCase tests
[] = {
1336 // Press Search. Confirm the event is now VKEY_ESCAPE.
1337 {KeyTestCase::TEST_ALL
,
1340 ui::DomCode::OS_LEFT
,
1341 ui::EF_COMMAND_DOWN
,
1345 ui::DomCode::ESCAPE
,
1351 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
1353 CheckKeyTestCase(&rewriter
, tests
[i
]);
1357 TEST_F(EventRewriterTest
, TestRewriteModifiersRemapMany
) {
1358 // Remap Search to Alt.
1359 TestingPrefServiceSyncable prefs
;
1360 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1361 IntegerPrefMember search
;
1362 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
1363 search
.SetValue(chromeos::input_method::kAltKey
);
1365 EventRewriter
rewriter(NULL
);
1366 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1367 rewriter
.set_pref_service_for_testing(&prefs
);
1369 KeyTestCase s2a_tests
[] = {
1370 // Press Search. Confirm the event is now VKEY_MENU.
1371 {KeyTestCase::TEST_ALL
,
1374 ui::DomCode::OS_LEFT
,
1375 ui::EF_COMMAND_DOWN
,
1379 ui::DomCode::ALT_LEFT
,
1385 for (size_t i
= 0; i
< arraysize(s2a_tests
); ++i
) {
1387 CheckKeyTestCase(&rewriter
, s2a_tests
[i
]);
1390 // Remap Alt to Control.
1391 IntegerPrefMember alt
;
1392 alt
.Init(prefs::kLanguageRemapAltKeyTo
, &prefs
);
1393 alt
.SetValue(chromeos::input_method::kControlKey
);
1395 KeyTestCase a2c_tests
[] = {
1396 // Press left Alt. Confirm the event is now VKEY_CONTROL.
1397 {KeyTestCase::TEST_ALL
,
1400 ui::DomCode::ALT_LEFT
,
1405 ui::DomCode::CONTROL_LEFT
,
1406 ui::EF_CONTROL_DOWN
,
1407 ui::DomKey::CONTROL
,
1409 // Press Shift+comma. Verify that only the flags are changed.
1410 // The X11 portion of the test addresses crbug.com/390263 by verifying
1411 // that the X keycode remains that for ',<' and not for 105-key '<>'.
1412 {KeyTestCase::TEST_ALL
,
1414 {ui::VKEY_OEM_COMMA
,
1416 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
,
1417 ui::DomKey::UNIDENTIFIED
,
1419 {ui::VKEY_OEM_COMMA
,
1421 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
1422 ui::DomKey::UNIDENTIFIED
,
1424 // Press Shift+9. Verify that only the flags are changed.
1425 {KeyTestCase::TEST_ALL
,
1428 ui::DomCode::DIGIT9
,
1429 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
,
1430 ui::DomKey::CHARACTER
,
1433 ui::DomCode::DIGIT9
,
1434 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
1435 ui::DomKey::CHARACTER
,
1439 for (size_t i
= 0; i
< arraysize(a2c_tests
); ++i
) {
1441 CheckKeyTestCase(&rewriter
, a2c_tests
[i
]);
1444 // Remap Control to Search.
1445 IntegerPrefMember control
;
1446 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
1447 control
.SetValue(chromeos::input_method::kSearchKey
);
1449 KeyTestCase c2s_tests
[] = {
1450 // Press left Control. Confirm the event is now VKEY_LWIN.
1451 {KeyTestCase::TEST_ALL
,
1454 ui::DomCode::CONTROL_LEFT
,
1455 ui::EF_CONTROL_DOWN
,
1456 ui::DomKey::CONTROL
,
1459 ui::DomCode::OS_LEFT
,
1460 ui::EF_COMMAND_DOWN
,
1464 // Then, press all of the three, Control+Alt+Search.
1465 {KeyTestCase::TEST_ALL
,
1468 ui::DomCode::OS_LEFT
,
1469 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
1473 ui::DomCode::ALT_LEFT
,
1474 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
1478 // Press Shift+Control+Alt+Search.
1479 {KeyTestCase::TEST_ALL
,
1482 ui::DomCode::OS_LEFT
,
1483 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
1484 ui::EF_COMMAND_DOWN
,
1488 ui::DomCode::ALT_LEFT
,
1489 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
1490 ui::EF_COMMAND_DOWN
,
1494 // Press Shift+Control+Alt+Search+B
1495 {KeyTestCase::TEST_ALL
,
1499 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
1500 ui::EF_COMMAND_DOWN
,
1501 ui::DomKey::CHARACTER
,
1505 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
1506 ui::EF_COMMAND_DOWN
,
1507 ui::DomKey::CHARACTER
,
1511 for (size_t i
= 0; i
< arraysize(c2s_tests
); ++i
) {
1513 CheckKeyTestCase(&rewriter
, c2s_tests
[i
]);
1517 TEST_F(EventRewriterTest
, TestRewriteModifiersRemapToCapsLock
) {
1518 // Remap Search to Caps Lock.
1519 TestingPrefServiceSyncable prefs
;
1520 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1521 IntegerPrefMember search
;
1522 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
1523 search
.SetValue(chromeos::input_method::kCapsLockKey
);
1525 chromeos::input_method::FakeImeKeyboard ime_keyboard
;
1526 EventRewriter
rewriter(NULL
);
1527 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1528 rewriter
.set_pref_service_for_testing(&prefs
);
1529 rewriter
.set_ime_keyboard_for_testing(&ime_keyboard
);
1530 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
1533 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_CAPITAL
,
1534 ui::DomCode::CAPS_LOCK
,
1535 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
1536 ui::DomKey::CAPS_LOCK
, 0),
1537 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
,
1538 ui::VKEY_LWIN
, ui::DomCode::OS_LEFT
,
1539 ui::EF_COMMAND_DOWN
, ui::DomKey::OS
, 0));
1540 // Confirm that the Caps Lock status is changed.
1541 EXPECT_TRUE(ime_keyboard
.caps_lock_is_enabled_
);
1544 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_RELEASED
, ui::VKEY_CAPITAL
,
1545 ui::DomCode::CAPS_LOCK
, ui::EF_NONE
,
1546 ui::DomKey::CAPS_LOCK
, 0),
1547 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_RELEASED
,
1548 ui::VKEY_LWIN
, ui::DomCode::OS_LEFT
,
1549 ui::EF_NONE
, ui::DomKey::OS
, 0));
1550 // Confirm that the Caps Lock status is not changed.
1551 EXPECT_TRUE(ime_keyboard
.caps_lock_is_enabled_
);
1555 GetExpectedResultAsString(
1556 ui::ET_KEY_PRESSED
, ui::VKEY_CAPITAL
, ui::DomCode::CAPS_LOCK
,
1557 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
, ui::DomKey::CAPS_LOCK
, 0),
1558 GetRewrittenEventAsString(
1559 &rewriter
, ui::ET_KEY_PRESSED
, ui::VKEY_LWIN
, ui::DomCode::OS_LEFT
,
1560 ui::EF_COMMAND_DOWN
| ui::EF_CAPS_LOCK_DOWN
, ui::DomKey::OS
, 0));
1561 // Confirm that the Caps Lock status is changed.
1562 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
1565 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_RELEASED
, ui::VKEY_CAPITAL
,
1566 ui::DomCode::CAPS_LOCK
, ui::EF_NONE
,
1567 ui::DomKey::CAPS_LOCK
, 0),
1568 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_RELEASED
,
1569 ui::VKEY_LWIN
, ui::DomCode::OS_LEFT
,
1570 ui::EF_NONE
, ui::DomKey::OS
, 0));
1571 // Confirm that the Caps Lock status is not changed.
1572 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
1574 // Press Caps Lock (on an external keyboard).
1575 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_CAPITAL
,
1576 ui::DomCode::CAPS_LOCK
,
1577 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
1578 ui::DomKey::CAPS_LOCK
, 0),
1579 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
,
1580 ui::VKEY_CAPITAL
, ui::DomCode::CAPS_LOCK
,
1581 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
1582 ui::DomKey::CAPS_LOCK
, 0));
1584 // Confirm that calling RewriteForTesting() does not change the state of
1585 // |ime_keyboard|. In this case, X Window system itself should change the
1586 // Caps Lock state, not ash::EventRewriter.
1587 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
1589 // Release Caps Lock (on an external keyboard).
1590 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_RELEASED
, ui::VKEY_CAPITAL
,
1591 ui::DomCode::CAPS_LOCK
, ui::EF_NONE
,
1592 ui::DomKey::CAPS_LOCK
, 0),
1593 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_RELEASED
,
1594 ui::VKEY_CAPITAL
, ui::DomCode::CAPS_LOCK
,
1595 ui::EF_NONE
, ui::DomKey::CAPS_LOCK
, 0));
1596 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
1599 TEST_F(EventRewriterTest
, TestRewriteCapsLock
) {
1600 TestingPrefServiceSyncable prefs
;
1601 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1603 chromeos::input_method::FakeImeKeyboard ime_keyboard
;
1604 EventRewriter
rewriter(NULL
);
1605 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1606 rewriter
.set_pref_service_for_testing(&prefs
);
1607 rewriter
.set_ime_keyboard_for_testing(&ime_keyboard
);
1608 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
1610 // On Chrome OS, CapsLock is mapped to F16 with Mod3Mask.
1611 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_CAPITAL
,
1612 ui::DomCode::CAPS_LOCK
,
1613 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
1614 ui::DomKey::CAPS_LOCK
, 0),
1615 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
,
1616 ui::VKEY_F16
, ui::DomCode::F16
,
1617 ui::EF_MOD3_DOWN
, ui::DomKey::F16
, 0));
1618 EXPECT_TRUE(ime_keyboard
.caps_lock_is_enabled_
);
1621 TEST_F(EventRewriterTest
, TestRewriteDiamondKey
) {
1622 TestingPrefServiceSyncable prefs
;
1623 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1625 chromeos::input_method::FakeImeKeyboard ime_keyboard
;
1626 EventRewriter
rewriter(NULL
);
1627 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1628 rewriter
.set_pref_service_for_testing(&prefs
);
1629 rewriter
.set_ime_keyboard_for_testing(&ime_keyboard
);
1631 KeyTestCase tests
[] = {
1632 // F15 should work as Ctrl when --has-chromeos-diamond-key is not
1634 {KeyTestCase::TEST_VKEY
,
1636 {ui::VKEY_F15
, ui::DomCode::F15
, ui::EF_NONE
, ui::DomKey::F15
, 0},
1638 ui::DomCode::CONTROL_LEFT
,
1639 ui::EF_CONTROL_DOWN
,
1640 ui::DomKey::CONTROL
,
1643 {KeyTestCase::TEST_VKEY
,
1644 ui::ET_KEY_RELEASED
,
1645 {ui::VKEY_F15
, ui::DomCode::F15
, ui::EF_NONE
, ui::DomKey::F15
, 0},
1647 ui::DomCode::CONTROL_LEFT
,
1649 ui::DomKey::CONTROL
,
1652 // However, Mod2Mask should not be rewritten to CtrlMask when
1653 // --has-chromeos-diamond-key is not specified.
1654 {KeyTestCase::TEST_VKEY
,
1659 ui::DomKey::CHARACTER
,
1664 ui::DomKey::CHARACTER
,
1668 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
1670 CheckKeyTestCase(&rewriter
, tests
[i
]);
1674 TEST_F(EventRewriterTest
, TestRewriteDiamondKeyWithFlag
) {
1675 const base::CommandLine
original_cl(*base::CommandLine::ForCurrentProcess());
1676 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1677 chromeos::switches::kHasChromeOSDiamondKey
, "");
1679 TestingPrefServiceSyncable prefs
;
1680 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1682 chromeos::input_method::FakeImeKeyboard ime_keyboard
;
1683 EventRewriter
rewriter(NULL
);
1684 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1685 rewriter
.set_pref_service_for_testing(&prefs
);
1686 rewriter
.set_ime_keyboard_for_testing(&ime_keyboard
);
1688 // By default, F15 should work as Control.
1689 EXPECT_EQ(GetExpectedResultAsString(
1690 ui::ET_KEY_PRESSED
, ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
1691 ui::EF_CONTROL_DOWN
, ui::DomKey::CONTROL
, 0),
1692 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
,
1693 ui::VKEY_F15
, ui::DomCode::F15
,
1694 ui::EF_NONE
, ui::DomKey::F15
, 0));
1695 // Check that Control is applied to a subsequent key press.
1696 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1697 ui::DomCode::KEY_A
, ui::EF_CONTROL_DOWN
,
1698 ui::DomKey::CHARACTER
, 'a'),
1699 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1700 ui::DomCode::KEY_A
, ui::EF_NONE
,
1701 ui::DomKey::CHARACTER
, 'a'));
1703 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_RELEASED
, ui::VKEY_CONTROL
,
1704 ui::DomCode::CONTROL_LEFT
, ui::EF_NONE
,
1705 ui::DomKey::CONTROL
, 0),
1706 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_RELEASED
,
1707 ui::VKEY_F15
, ui::DomCode::F15
,
1708 ui::EF_NONE
, ui::DomKey::F15
, 0));
1709 // Check that Control is no longer applied to a subsequent key press.
1710 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1711 ui::DomCode::KEY_A
, ui::EF_NONE
,
1712 ui::DomKey::CHARACTER
, 'a'),
1713 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1714 ui::DomCode::KEY_A
, ui::EF_NONE
,
1715 ui::DomKey::CHARACTER
, 'a'));
1717 IntegerPrefMember diamond
;
1718 diamond
.Init(prefs::kLanguageRemapDiamondKeyTo
, &prefs
);
1719 diamond
.SetValue(chromeos::input_method::kVoidKey
);
1721 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_UNKNOWN
,
1722 ui::DomCode::NONE
, ui::EF_NONE
,
1723 ui::DomKey::NONE
, 0),
1724 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
,
1725 ui::VKEY_F15
, ui::DomCode::F15
,
1726 ui::EF_NONE
, ui::DomKey::F15
, 0));
1727 // Check that no modifier is applied to another key.
1728 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1729 ui::DomCode::KEY_A
, ui::EF_NONE
,
1730 ui::DomKey::CHARACTER
, 'a'),
1731 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1732 ui::DomCode::KEY_A
, ui::EF_NONE
,
1733 ui::DomKey::CHARACTER
, 'a'));
1735 diamond
.SetValue(chromeos::input_method::kControlKey
);
1737 EXPECT_EQ(GetExpectedResultAsString(
1738 ui::ET_KEY_PRESSED
, ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
1739 ui::EF_CONTROL_DOWN
, ui::DomKey::CONTROL
, 0),
1740 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
,
1741 ui::VKEY_F15
, ui::DomCode::F15
,
1742 ui::EF_NONE
, ui::DomKey::F15
, 0));
1743 // Check that Control is applied to a subsequent key press.
1744 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1745 ui::DomCode::KEY_A
, ui::EF_CONTROL_DOWN
,
1746 ui::DomKey::CHARACTER
, 'a'),
1747 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1748 ui::DomCode::KEY_A
, ui::EF_NONE
,
1749 ui::DomKey::CHARACTER
, 'a'));
1751 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_RELEASED
, ui::VKEY_CONTROL
,
1752 ui::DomCode::CONTROL_LEFT
, ui::EF_NONE
,
1753 ui::DomKey::CONTROL
, 0),
1754 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_RELEASED
,
1755 ui::VKEY_F15
, ui::DomCode::F15
,
1756 ui::EF_NONE
, ui::DomKey::F15
, 0));
1757 // Check that Control is no longer applied to a subsequent key press.
1758 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1759 ui::DomCode::KEY_A
, ui::EF_NONE
,
1760 ui::DomKey::CHARACTER
, 'a'),
1761 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1762 ui::DomCode::KEY_A
, ui::EF_NONE
,
1763 ui::DomKey::CHARACTER
, 'a'));
1765 diamond
.SetValue(chromeos::input_method::kAltKey
);
1767 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_MENU
,
1768 ui::DomCode::ALT_LEFT
, ui::EF_ALT_DOWN
,
1769 ui::DomKey::ALT
, 0),
1770 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
,
1771 ui::VKEY_F15
, ui::DomCode::F15
,
1772 ui::EF_NONE
, ui::DomKey::F15
, 0));
1773 // Check that Alt is applied to a subsequent key press.
1774 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1775 ui::DomCode::KEY_A
, ui::EF_ALT_DOWN
,
1776 ui::DomKey::CHARACTER
, 'a'),
1777 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1778 ui::DomCode::KEY_A
, ui::EF_NONE
,
1779 ui::DomKey::CHARACTER
, 'a'));
1781 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_RELEASED
, ui::VKEY_MENU
,
1782 ui::DomCode::ALT_LEFT
, ui::EF_NONE
,
1783 ui::DomKey::ALT
, 0),
1784 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_RELEASED
,
1785 ui::VKEY_F15
, ui::DomCode::F15
,
1786 ui::EF_NONE
, ui::DomKey::F15
, 0));
1787 // Check that Alt is no longer applied to a subsequent key press.
1788 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1789 ui::DomCode::KEY_A
, ui::EF_NONE
,
1790 ui::DomKey::CHARACTER
, 'a'),
1791 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1792 ui::DomCode::KEY_A
, ui::EF_NONE
,
1793 ui::DomKey::CHARACTER
, 'a'));
1795 diamond
.SetValue(chromeos::input_method::kCapsLockKey
);
1797 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_CAPITAL
,
1798 ui::DomCode::CAPS_LOCK
,
1799 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
1800 ui::DomKey::CAPS_LOCK
, 0),
1801 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
,
1802 ui::VKEY_F15
, ui::DomCode::F15
,
1803 ui::EF_NONE
, ui::DomKey::F15
, 0));
1804 // Check that Caps is applied to a subsequent key press.
1805 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1807 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
1808 ui::DomKey::CHARACTER
, 'a'),
1809 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1810 ui::DomCode::KEY_A
, ui::EF_NONE
,
1811 ui::DomKey::CHARACTER
, 'a'));
1813 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_RELEASED
, ui::VKEY_CAPITAL
,
1814 ui::DomCode::CAPS_LOCK
, ui::EF_NONE
,
1815 ui::DomKey::CAPS_LOCK
, 0),
1816 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_RELEASED
,
1817 ui::VKEY_F15
, ui::DomCode::F15
,
1818 ui::EF_NONE
, ui::DomKey::F15
, 0));
1819 // Check that Control is no longer applied to a subsequent key press.
1820 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1821 ui::DomCode::KEY_A
, ui::EF_NONE
,
1822 ui::DomKey::CHARACTER
, 'a'),
1823 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1824 ui::DomCode::KEY_A
, ui::EF_NONE
,
1825 ui::DomKey::CHARACTER
, 'a'));
1827 *base::CommandLine::ForCurrentProcess() = original_cl
;
1830 TEST_F(EventRewriterTest
, TestRewriteCapsLockToControl
) {
1831 // Remap CapsLock to Control.
1832 TestingPrefServiceSyncable prefs
;
1833 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1834 IntegerPrefMember control
;
1835 control
.Init(prefs::kLanguageRemapCapsLockKeyTo
, &prefs
);
1836 control
.SetValue(chromeos::input_method::kControlKey
);
1838 EventRewriter
rewriter(NULL
);
1839 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1840 rewriter
.set_pref_service_for_testing(&prefs
);
1842 KeyTestCase tests
[] = {
1843 // Press CapsLock+a. Confirm that Mod3Mask is rewritten to ControlMask.
1844 // On Chrome OS, CapsLock works as a Mod3 modifier.
1845 {KeyTestCase::TEST_ALL
,
1850 ui::DomKey::CHARACTER
,
1854 ui::EF_CONTROL_DOWN
,
1855 ui::DomKey::CHARACTER
,
1858 // Press Control+CapsLock+a. Confirm that Mod3Mask is rewritten to
1860 {KeyTestCase::TEST_ALL
,
1864 ui::EF_CONTROL_DOWN
| ui::EF_MOD3_DOWN
,
1865 ui::DomKey::CHARACTER
,
1869 ui::EF_CONTROL_DOWN
,
1870 ui::DomKey::CHARACTER
,
1873 // Press Alt+CapsLock+a. Confirm that Mod3Mask is rewritten to
1875 {KeyTestCase::TEST_ALL
,
1879 ui::EF_ALT_DOWN
| ui::EF_MOD3_DOWN
,
1880 ui::DomKey::CHARACTER
,
1884 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
1885 ui::DomKey::CHARACTER
,
1889 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
1891 CheckKeyTestCase(&rewriter
, tests
[i
]);
1895 TEST_F(EventRewriterTest
, TestRewriteCapsLockMod3InUse
) {
1896 // Remap CapsLock to Control.
1897 TestingPrefServiceSyncable prefs
;
1898 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1899 IntegerPrefMember control
;
1900 control
.Init(prefs::kLanguageRemapCapsLockKeyTo
, &prefs
);
1901 control
.SetValue(chromeos::input_method::kControlKey
);
1903 EventRewriter
rewriter(NULL
);
1904 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1905 rewriter
.set_pref_service_for_testing(&prefs
);
1906 input_method_manager_mock_
->set_mod3_used(true);
1908 // Press CapsLock+a. Confirm that Mod3Mask is NOT rewritten to ControlMask
1909 // when Mod3Mask is already in use by the current XKB layout.
1910 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1911 ui::DomCode::KEY_A
, ui::EF_NONE
,
1912 ui::DomKey::CHARACTER
, 'a'),
1913 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1914 ui::DomCode::KEY_A
, ui::EF_NONE
,
1915 ui::DomKey::CHARACTER
, 'a'));
1917 input_method_manager_mock_
->set_mod3_used(false);
1920 TEST_F(EventRewriterTest
, TestRewriteExtendedKeys
) {
1921 TestingPrefServiceSyncable prefs
;
1922 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1923 EventRewriter
rewriter(NULL
);
1924 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1925 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
1926 rewriter
.set_pref_service_for_testing(&prefs
);
1928 KeyTestCase tests
[] = {
1929 // Alt+Backspace -> Delete
1930 {KeyTestCase::TEST_ALL
,
1933 ui::DomCode::BACKSPACE
,
1935 ui::DomKey::BACKSPACE
,
1937 {ui::VKEY_DELETE
, ui::DomCode::DEL
, ui::EF_NONE
, ui::DomKey::DEL
, 0}},
1938 // Control+Alt+Backspace -> Control+Delete
1939 {KeyTestCase::TEST_ALL
,
1942 ui::DomCode::BACKSPACE
,
1943 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
1944 ui::DomKey::BACKSPACE
,
1948 ui::EF_CONTROL_DOWN
,
1951 // Search+Alt+Backspace -> Alt+Backspace
1952 {KeyTestCase::TEST_ALL
,
1955 ui::DomCode::BACKSPACE
,
1956 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
,
1957 ui::DomKey::BACKSPACE
,
1960 ui::DomCode::BACKSPACE
,
1962 ui::DomKey::BACKSPACE
,
1964 // Search+Control+Alt+Backspace -> Control+Alt+Backspace
1965 {KeyTestCase::TEST_ALL
,
1968 ui::DomCode::BACKSPACE
,
1969 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
1970 ui::DomKey::BACKSPACE
,
1973 ui::DomCode::BACKSPACE
,
1974 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
1975 ui::DomKey::BACKSPACE
,
1978 {KeyTestCase::TEST_ALL
,
1981 ui::DomCode::ARROW_UP
,
1983 ui::DomKey::ARROW_UP
,
1986 ui::DomCode::PAGE_UP
,
1988 ui::DomKey::PAGE_UP
,
1991 {KeyTestCase::TEST_ALL
,
1994 ui::DomCode::ARROW_DOWN
,
1996 ui::DomKey::ARROW_DOWN
,
1999 ui::DomCode::PAGE_DOWN
,
2001 ui::DomKey::PAGE_DOWN
,
2003 // Ctrl+Alt+Up -> Home
2004 {KeyTestCase::TEST_ALL
,
2007 ui::DomCode::ARROW_UP
,
2008 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
2009 ui::DomKey::ARROW_UP
,
2011 {ui::VKEY_HOME
, ui::DomCode::HOME
, ui::EF_NONE
, ui::DomKey::HOME
, 0}},
2012 // Ctrl+Alt+Down -> End
2013 {KeyTestCase::TEST_ALL
,
2016 ui::DomCode::ARROW_DOWN
,
2017 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
2018 ui::DomKey::ARROW_DOWN
,
2020 {ui::VKEY_END
, ui::DomCode::END
, ui::EF_NONE
, ui::DomKey::END
, 0}},
2022 // Search+Alt+Up -> Alt+Up
2023 {KeyTestCase::TEST_ALL
,
2026 ui::DomCode::ARROW_UP
,
2027 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
,
2028 ui::DomKey::ARROW_UP
,
2031 ui::DomCode::ARROW_UP
,
2033 ui::DomKey::ARROW_UP
,
2035 // Search+Alt+Down -> Alt+Down
2036 {KeyTestCase::TEST_ALL
,
2039 ui::DomCode::ARROW_DOWN
,
2040 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
,
2041 ui::DomKey::ARROW_DOWN
,
2044 ui::DomCode::ARROW_DOWN
,
2046 ui::DomKey::ARROW_DOWN
,
2048 // Search+Ctrl+Alt+Up -> Search+Ctrl+Alt+Up
2049 {KeyTestCase::TEST_ALL
,
2052 ui::DomCode::ARROW_UP
,
2053 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
2054 ui::DomKey::ARROW_UP
,
2057 ui::DomCode::ARROW_UP
,
2058 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
2059 ui::DomKey::ARROW_UP
,
2061 // Search+Ctrl+Alt+Down -> Ctrl+Alt+Down
2062 {KeyTestCase::TEST_ALL
,
2065 ui::DomCode::ARROW_DOWN
,
2066 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
2067 ui::DomKey::ARROW_DOWN
,
2070 ui::DomCode::ARROW_DOWN
,
2071 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
2072 ui::DomKey::ARROW_DOWN
,
2076 {KeyTestCase::TEST_ALL
,
2078 {ui::VKEY_OEM_PERIOD
,
2079 ui::DomCode::PERIOD
,
2081 ui::DomKey::CHARACTER
,
2083 {ui::VKEY_OEM_PERIOD
,
2084 ui::DomCode::PERIOD
,
2086 ui::DomKey::CHARACTER
,
2089 // Search+Backspace -> Delete
2090 {KeyTestCase::TEST_ALL
,
2093 ui::DomCode::BACKSPACE
,
2094 ui::EF_COMMAND_DOWN
,
2095 ui::DomKey::BACKSPACE
,
2097 {ui::VKEY_DELETE
, ui::DomCode::DEL
, ui::EF_NONE
, ui::DomKey::DEL
, 0}},
2098 // Search+Up -> Prior
2099 {KeyTestCase::TEST_ALL
,
2102 ui::DomCode::ARROW_UP
,
2103 ui::EF_COMMAND_DOWN
,
2104 ui::DomKey::ARROW_UP
,
2107 ui::DomCode::PAGE_UP
,
2109 ui::DomKey::PAGE_UP
,
2111 // Search+Down -> Next
2112 {KeyTestCase::TEST_ALL
,
2115 ui::DomCode::ARROW_DOWN
,
2116 ui::EF_COMMAND_DOWN
,
2117 ui::DomKey::ARROW_DOWN
,
2120 ui::DomCode::PAGE_DOWN
,
2122 ui::DomKey::PAGE_DOWN
,
2124 // Search+Left -> Home
2125 {KeyTestCase::TEST_ALL
,
2128 ui::DomCode::ARROW_LEFT
,
2129 ui::EF_COMMAND_DOWN
,
2130 ui::DomKey::ARROW_LEFT
,
2132 {ui::VKEY_HOME
, ui::DomCode::HOME
, ui::EF_NONE
, ui::DomKey::HOME
, 0}},
2133 // Control+Search+Left -> Home
2134 {KeyTestCase::TEST_ALL
,
2137 ui::DomCode::ARROW_LEFT
,
2138 ui::EF_COMMAND_DOWN
| ui::EF_CONTROL_DOWN
,
2139 ui::DomKey::ARROW_LEFT
,
2143 ui::EF_CONTROL_DOWN
,
2146 // Search+Right -> End
2147 {KeyTestCase::TEST_ALL
,
2150 ui::DomCode::ARROW_RIGHT
,
2151 ui::EF_COMMAND_DOWN
,
2152 ui::DomKey::ARROW_RIGHT
,
2154 {ui::VKEY_END
, ui::DomCode::END
, ui::EF_NONE
, ui::DomKey::END
, 0}},
2155 // Control+Search+Right -> End
2156 {KeyTestCase::TEST_ALL
,
2159 ui::DomCode::ARROW_RIGHT
,
2160 ui::EF_COMMAND_DOWN
| ui::EF_CONTROL_DOWN
,
2161 ui::DomKey::ARROW_RIGHT
,
2165 ui::EF_CONTROL_DOWN
,
2168 // Search+Period -> Insert
2169 {KeyTestCase::TEST_ALL
,
2171 {ui::VKEY_OEM_PERIOD
,
2172 ui::DomCode::PERIOD
,
2173 ui::EF_COMMAND_DOWN
,
2174 ui::DomKey::CHARACTER
,
2177 ui::DomCode::INSERT
,
2181 // Control+Search+Period -> Control+Insert
2182 {KeyTestCase::TEST_ALL
,
2184 {ui::VKEY_OEM_PERIOD
,
2185 ui::DomCode::PERIOD
,
2186 ui::EF_COMMAND_DOWN
| ui::EF_CONTROL_DOWN
,
2187 ui::DomKey::CHARACTER
,
2190 ui::DomCode::INSERT
,
2191 ui::EF_CONTROL_DOWN
,
2195 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
2197 CheckKeyTestCase(&rewriter
, tests
[i
]);
2201 TEST_F(EventRewriterTest
, TestRewriteFunctionKeys
) {
2202 TestingPrefServiceSyncable prefs
;
2203 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
2204 EventRewriter
rewriter(NULL
);
2205 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
2206 rewriter
.set_pref_service_for_testing(&prefs
);
2208 KeyTestCase tests
[] = {
2210 {KeyTestCase::TEST_ALL
,
2212 {ui::VKEY_F1
, ui::DomCode::F1
, ui::EF_NONE
, ui::DomKey::F1
, 0},
2213 {ui::VKEY_BROWSER_BACK
,
2214 ui::DomCode::BROWSER_BACK
,
2216 ui::DomKey::BROWSER_BACK
,
2218 {KeyTestCase::TEST_ALL
,
2220 {ui::VKEY_F1
, ui::DomCode::F1
, ui::EF_CONTROL_DOWN
, ui::DomKey::F1
, 0},
2221 {ui::VKEY_BROWSER_BACK
,
2222 ui::DomCode::BROWSER_BACK
,
2223 ui::EF_CONTROL_DOWN
,
2224 ui::DomKey::BROWSER_BACK
,
2226 {KeyTestCase::TEST_ALL
,
2228 {ui::VKEY_F1
, ui::DomCode::F1
, ui::EF_ALT_DOWN
, ui::DomKey::F1
, 0},
2229 {ui::VKEY_BROWSER_BACK
,
2230 ui::DomCode::BROWSER_BACK
,
2232 ui::DomKey::BROWSER_BACK
,
2235 {KeyTestCase::TEST_ALL
,
2237 {ui::VKEY_F2
, ui::DomCode::F2
, ui::EF_NONE
, ui::DomKey::F2
, 0},
2238 {ui::VKEY_BROWSER_FORWARD
,
2239 ui::DomCode::BROWSER_FORWARD
,
2241 ui::DomKey::BROWSER_FORWARD
,
2243 {KeyTestCase::TEST_ALL
,
2245 {ui::VKEY_F2
, ui::DomCode::F2
, ui::EF_CONTROL_DOWN
, ui::DomKey::F2
, 0},
2246 {ui::VKEY_BROWSER_FORWARD
,
2247 ui::DomCode::BROWSER_FORWARD
,
2248 ui::EF_CONTROL_DOWN
,
2249 ui::DomKey::BROWSER_FORWARD
,
2251 {KeyTestCase::TEST_ALL
,
2253 {ui::VKEY_F2
, ui::DomCode::F2
, ui::EF_ALT_DOWN
, ui::DomKey::F2
, 0},
2254 {ui::VKEY_BROWSER_FORWARD
,
2255 ui::DomCode::BROWSER_FORWARD
,
2257 ui::DomKey::BROWSER_FORWARD
,
2260 {KeyTestCase::TEST_ALL
,
2262 {ui::VKEY_F3
, ui::DomCode::F3
, ui::EF_NONE
, ui::DomKey::F3
, 0},
2263 {ui::VKEY_BROWSER_REFRESH
,
2264 ui::DomCode::BROWSER_REFRESH
,
2266 ui::DomKey::BROWSER_REFRESH
,
2268 {KeyTestCase::TEST_ALL
,
2270 {ui::VKEY_F3
, ui::DomCode::F3
, ui::EF_CONTROL_DOWN
, ui::DomKey::F3
, 0},
2271 {ui::VKEY_BROWSER_REFRESH
,
2272 ui::DomCode::BROWSER_REFRESH
,
2273 ui::EF_CONTROL_DOWN
,
2274 ui::DomKey::BROWSER_REFRESH
,
2276 {KeyTestCase::TEST_ALL
,
2278 {ui::VKEY_F3
, ui::DomCode::F3
, ui::EF_ALT_DOWN
, ui::DomKey::F3
, 0},
2279 {ui::VKEY_BROWSER_REFRESH
,
2280 ui::DomCode::BROWSER_REFRESH
,
2282 ui::DomKey::BROWSER_REFRESH
,
2284 // F4 -> Launch App 2
2285 {KeyTestCase::TEST_ALL
,
2287 {ui::VKEY_F4
, ui::DomCode::F4
, ui::EF_NONE
, ui::DomKey::F4
, 0},
2288 {ui::VKEY_MEDIA_LAUNCH_APP2
,
2289 ui::DomCode::ZOOM_TOGGLE
,
2291 ui::DomKey::ZOOM_TOGGLE
,
2293 {KeyTestCase::TEST_ALL
,
2295 {ui::VKEY_F4
, ui::DomCode::F4
, ui::EF_CONTROL_DOWN
, ui::DomKey::F4
, 0},
2296 {ui::VKEY_MEDIA_LAUNCH_APP2
,
2297 ui::DomCode::ZOOM_TOGGLE
,
2298 ui::EF_CONTROL_DOWN
,
2299 ui::DomKey::ZOOM_TOGGLE
,
2301 {KeyTestCase::TEST_ALL
,
2303 {ui::VKEY_F4
, ui::DomCode::F4
, ui::EF_ALT_DOWN
, ui::DomKey::F4
, 0},
2304 {ui::VKEY_MEDIA_LAUNCH_APP2
,
2305 ui::DomCode::ZOOM_TOGGLE
,
2307 ui::DomKey::ZOOM_TOGGLE
,
2309 // F5 -> Launch App 1
2310 {KeyTestCase::TEST_ALL
,
2312 {ui::VKEY_F5
, ui::DomCode::F5
, ui::EF_NONE
, ui::DomKey::F5
, 0},
2313 {ui::VKEY_MEDIA_LAUNCH_APP1
,
2314 ui::DomCode::SELECT_TASK
,
2316 ui::DomKey::LAUNCH_MY_COMPUTER
,
2318 {KeyTestCase::TEST_ALL
,
2320 {ui::VKEY_F5
, ui::DomCode::F5
, ui::EF_CONTROL_DOWN
, ui::DomKey::F5
, 0},
2321 {ui::VKEY_MEDIA_LAUNCH_APP1
,
2322 ui::DomCode::SELECT_TASK
,
2323 ui::EF_CONTROL_DOWN
,
2324 ui::DomKey::LAUNCH_MY_COMPUTER
,
2326 {KeyTestCase::TEST_ALL
,
2328 {ui::VKEY_F5
, ui::DomCode::F5
, ui::EF_ALT_DOWN
, ui::DomKey::F5
, 0},
2329 {ui::VKEY_MEDIA_LAUNCH_APP1
,
2330 ui::DomCode::SELECT_TASK
,
2332 ui::DomKey::LAUNCH_MY_COMPUTER
,
2334 // F6 -> Brightness down
2335 {KeyTestCase::TEST_ALL
,
2337 {ui::VKEY_F6
, ui::DomCode::F6
, ui::EF_NONE
, ui::DomKey::F6
, 0},
2338 {ui::VKEY_BRIGHTNESS_DOWN
,
2339 ui::DomCode::BRIGHTNESS_DOWN
,
2341 ui::DomKey::BRIGHTNESS_DOWN
,
2343 {KeyTestCase::TEST_ALL
,
2345 {ui::VKEY_F6
, ui::DomCode::F6
, ui::EF_CONTROL_DOWN
, ui::DomKey::F6
, 0},
2346 {ui::VKEY_BRIGHTNESS_DOWN
,
2347 ui::DomCode::BRIGHTNESS_DOWN
,
2348 ui::EF_CONTROL_DOWN
,
2349 ui::DomKey::BRIGHTNESS_DOWN
,
2351 {KeyTestCase::TEST_ALL
,
2353 {ui::VKEY_F6
, ui::DomCode::F6
, ui::EF_ALT_DOWN
, ui::DomKey::F6
, 0},
2354 {ui::VKEY_BRIGHTNESS_DOWN
,
2355 ui::DomCode::BRIGHTNESS_DOWN
,
2357 ui::DomKey::BRIGHTNESS_DOWN
,
2359 // F7 -> Brightness up
2360 {KeyTestCase::TEST_ALL
,
2362 {ui::VKEY_F7
, ui::DomCode::F7
, ui::EF_NONE
, ui::DomKey::F7
, 0},
2363 {ui::VKEY_BRIGHTNESS_UP
,
2364 ui::DomCode::BRIGHTNESS_UP
,
2366 ui::DomKey::BRIGHTNESS_UP
,
2368 {KeyTestCase::TEST_ALL
,
2370 {ui::VKEY_F7
, ui::DomCode::F7
, ui::EF_CONTROL_DOWN
, ui::DomKey::F7
, 0},
2371 {ui::VKEY_BRIGHTNESS_UP
,
2372 ui::DomCode::BRIGHTNESS_UP
,
2373 ui::EF_CONTROL_DOWN
,
2374 ui::DomKey::BRIGHTNESS_UP
,
2376 {KeyTestCase::TEST_ALL
,
2378 {ui::VKEY_F7
, ui::DomCode::F7
, ui::EF_ALT_DOWN
, ui::DomKey::F7
, 0},
2379 {ui::VKEY_BRIGHTNESS_UP
,
2380 ui::DomCode::BRIGHTNESS_UP
,
2382 ui::DomKey::BRIGHTNESS_UP
,
2384 // F8 -> Volume Mute
2385 {KeyTestCase::TEST_ALL
,
2387 {ui::VKEY_F8
, ui::DomCode::F8
, ui::EF_NONE
, ui::DomKey::F8
, 0},
2388 {ui::VKEY_VOLUME_MUTE
,
2389 ui::DomCode::VOLUME_MUTE
,
2391 ui::DomKey::VOLUME_MUTE
,
2393 {KeyTestCase::TEST_ALL
,
2395 {ui::VKEY_F8
, ui::DomCode::F8
, ui::EF_CONTROL_DOWN
, ui::DomKey::F8
, 0},
2396 {ui::VKEY_VOLUME_MUTE
,
2397 ui::DomCode::VOLUME_MUTE
,
2398 ui::EF_CONTROL_DOWN
,
2399 ui::DomKey::VOLUME_MUTE
,
2401 {KeyTestCase::TEST_ALL
,
2403 {ui::VKEY_F8
, ui::DomCode::F8
, ui::EF_ALT_DOWN
, ui::DomKey::F8
, 0},
2404 {ui::VKEY_VOLUME_MUTE
,
2405 ui::DomCode::VOLUME_MUTE
,
2407 ui::DomKey::VOLUME_MUTE
,
2409 // F9 -> Volume Down
2410 {KeyTestCase::TEST_ALL
,
2412 {ui::VKEY_F9
, ui::DomCode::F9
, ui::EF_NONE
, ui::DomKey::F9
, 0},
2413 {ui::VKEY_VOLUME_DOWN
,
2414 ui::DomCode::VOLUME_DOWN
,
2416 ui::DomKey::VOLUME_DOWN
,
2418 {KeyTestCase::TEST_ALL
,
2420 {ui::VKEY_F9
, ui::DomCode::F9
, ui::EF_CONTROL_DOWN
, ui::DomKey::F9
, 0},
2421 {ui::VKEY_VOLUME_DOWN
,
2422 ui::DomCode::VOLUME_DOWN
,
2423 ui::EF_CONTROL_DOWN
,
2424 ui::DomKey::VOLUME_DOWN
,
2426 {KeyTestCase::TEST_ALL
,
2428 {ui::VKEY_F9
, ui::DomCode::F9
, ui::EF_ALT_DOWN
, ui::DomKey::F9
, 0},
2429 {ui::VKEY_VOLUME_DOWN
,
2430 ui::DomCode::VOLUME_DOWN
,
2432 ui::DomKey::VOLUME_DOWN
,
2435 {KeyTestCase::TEST_ALL
,
2437 {ui::VKEY_F10
, ui::DomCode::F10
, ui::EF_NONE
, ui::DomKey::F10
, 0},
2438 {ui::VKEY_VOLUME_UP
,
2439 ui::DomCode::VOLUME_UP
,
2441 ui::DomKey::VOLUME_UP
,
2443 {KeyTestCase::TEST_ALL
,
2447 ui::EF_CONTROL_DOWN
,
2450 {ui::VKEY_VOLUME_UP
,
2451 ui::DomCode::VOLUME_UP
,
2452 ui::EF_CONTROL_DOWN
,
2453 ui::DomKey::VOLUME_UP
,
2455 {KeyTestCase::TEST_ALL
,
2457 {ui::VKEY_F10
, ui::DomCode::F10
, ui::EF_ALT_DOWN
, ui::DomKey::F10
, 0},
2458 {ui::VKEY_VOLUME_UP
,
2459 ui::DomCode::VOLUME_UP
,
2461 ui::DomKey::VOLUME_UP
,
2464 {KeyTestCase::TEST_ALL
,
2466 {ui::VKEY_F11
, ui::DomCode::F11
, ui::EF_NONE
, ui::DomKey::F11
, 0},
2467 {ui::VKEY_F11
, ui::DomCode::F11
, ui::EF_NONE
, ui::DomKey::F11
, 0}},
2468 {KeyTestCase::TEST_ALL
,
2472 ui::EF_CONTROL_DOWN
,
2477 ui::EF_CONTROL_DOWN
,
2480 {KeyTestCase::TEST_ALL
,
2482 {ui::VKEY_F11
, ui::DomCode::F11
, ui::EF_ALT_DOWN
, ui::DomKey::F11
, 0},
2483 {ui::VKEY_F11
, ui::DomCode::F11
, ui::EF_ALT_DOWN
, ui::DomKey::F11
, 0}},
2485 {KeyTestCase::TEST_ALL
,
2487 {ui::VKEY_F12
, ui::DomCode::F12
, ui::EF_NONE
, ui::DomKey::F12
, 0},
2488 {ui::VKEY_F12
, ui::DomCode::F12
, ui::EF_NONE
, ui::DomKey::F12
, 0}},
2489 {KeyTestCase::TEST_ALL
,
2493 ui::EF_CONTROL_DOWN
,
2498 ui::EF_CONTROL_DOWN
,
2501 {KeyTestCase::TEST_ALL
,
2503 {ui::VKEY_F12
, ui::DomCode::F12
, ui::EF_ALT_DOWN
, ui::DomKey::F12
, 0},
2504 {ui::VKEY_F12
, ui::DomCode::F12
, ui::EF_ALT_DOWN
, ui::DomKey::F12
, 0}},
2506 // The number row should not be rewritten without Search key.
2507 {KeyTestCase::TEST_ALL
,
2510 ui::DomCode::DIGIT1
,
2512 ui::DomKey::CHARACTER
,
2515 ui::DomCode::DIGIT1
,
2517 ui::DomKey::CHARACTER
,
2519 {KeyTestCase::TEST_ALL
,
2522 ui::DomCode::DIGIT2
,
2524 ui::DomKey::CHARACTER
,
2527 ui::DomCode::DIGIT2
,
2529 ui::DomKey::CHARACTER
,
2531 {KeyTestCase::TEST_ALL
,
2534 ui::DomCode::DIGIT3
,
2536 ui::DomKey::CHARACTER
,
2539 ui::DomCode::DIGIT3
,
2541 ui::DomKey::CHARACTER
,
2543 {KeyTestCase::TEST_ALL
,
2546 ui::DomCode::DIGIT4
,
2548 ui::DomKey::CHARACTER
,
2551 ui::DomCode::DIGIT4
,
2553 ui::DomKey::CHARACTER
,
2555 {KeyTestCase::TEST_ALL
,
2558 ui::DomCode::DIGIT5
,
2560 ui::DomKey::CHARACTER
,
2563 ui::DomCode::DIGIT5
,
2565 ui::DomKey::CHARACTER
,
2567 {KeyTestCase::TEST_ALL
,
2570 ui::DomCode::DIGIT6
,
2572 ui::DomKey::CHARACTER
,
2575 ui::DomCode::DIGIT6
,
2577 ui::DomKey::CHARACTER
,
2579 {KeyTestCase::TEST_ALL
,
2582 ui::DomCode::DIGIT7
,
2584 ui::DomKey::CHARACTER
,
2587 ui::DomCode::DIGIT7
,
2589 ui::DomKey::CHARACTER
,
2591 {KeyTestCase::TEST_ALL
,
2594 ui::DomCode::DIGIT8
,
2596 ui::DomKey::CHARACTER
,
2599 ui::DomCode::DIGIT8
,
2601 ui::DomKey::CHARACTER
,
2603 {KeyTestCase::TEST_ALL
,
2606 ui::DomCode::DIGIT9
,
2608 ui::DomKey::CHARACTER
,
2611 ui::DomCode::DIGIT9
,
2613 ui::DomKey::CHARACTER
,
2615 {KeyTestCase::TEST_ALL
,
2618 ui::DomCode::DIGIT0
,
2620 ui::DomKey::CHARACTER
,
2623 ui::DomCode::DIGIT0
,
2625 ui::DomKey::CHARACTER
,
2627 {KeyTestCase::TEST_ALL
,
2629 {ui::VKEY_OEM_MINUS
,
2632 ui::DomKey::CHARACTER
,
2634 {ui::VKEY_OEM_MINUS
,
2637 ui::DomKey::CHARACTER
,
2639 {KeyTestCase::TEST_ALL
,
2644 ui::DomKey::CHARACTER
,
2649 ui::DomKey::CHARACTER
,
2652 // The number row should be rewritten as the F<number> row with Search
2654 {KeyTestCase::TEST_ALL
,
2657 ui::DomCode::DIGIT1
,
2658 ui::EF_COMMAND_DOWN
,
2659 ui::DomKey::CHARACTER
,
2661 {ui::VKEY_F1
, ui::DomCode::F1
, ui::EF_NONE
, ui::DomKey::F1
, 0}},
2662 {KeyTestCase::TEST_ALL
,
2665 ui::DomCode::DIGIT2
,
2666 ui::EF_COMMAND_DOWN
,
2667 ui::DomKey::CHARACTER
,
2669 {ui::VKEY_F2
, ui::DomCode::F2
, ui::EF_NONE
, ui::DomKey::F2
, 0}},
2670 {KeyTestCase::TEST_ALL
,
2673 ui::DomCode::DIGIT3
,
2674 ui::EF_COMMAND_DOWN
,
2675 ui::DomKey::CHARACTER
,
2677 {ui::VKEY_F3
, ui::DomCode::F3
, ui::EF_NONE
, ui::DomKey::F3
, 0}},
2678 {KeyTestCase::TEST_ALL
,
2681 ui::DomCode::DIGIT4
,
2682 ui::EF_COMMAND_DOWN
,
2683 ui::DomKey::CHARACTER
,
2685 {ui::VKEY_F4
, ui::DomCode::F4
, ui::EF_NONE
, ui::DomKey::F4
, 0}},
2686 {KeyTestCase::TEST_ALL
,
2689 ui::DomCode::DIGIT5
,
2690 ui::EF_COMMAND_DOWN
,
2691 ui::DomKey::CHARACTER
,
2693 {ui::VKEY_F5
, ui::DomCode::F5
, ui::EF_NONE
, ui::DomKey::F5
, 0}},
2694 {KeyTestCase::TEST_ALL
,
2697 ui::DomCode::DIGIT6
,
2698 ui::EF_COMMAND_DOWN
,
2699 ui::DomKey::CHARACTER
,
2701 {ui::VKEY_F6
, ui::DomCode::F6
, ui::EF_NONE
, ui::DomKey::F6
, 0}},
2702 {KeyTestCase::TEST_ALL
,
2705 ui::DomCode::DIGIT7
,
2706 ui::EF_COMMAND_DOWN
,
2707 ui::DomKey::CHARACTER
,
2709 {ui::VKEY_F7
, ui::DomCode::F7
, ui::EF_NONE
, ui::DomKey::F7
, 0}},
2710 {KeyTestCase::TEST_ALL
,
2713 ui::DomCode::DIGIT8
,
2714 ui::EF_COMMAND_DOWN
,
2715 ui::DomKey::CHARACTER
,
2717 {ui::VKEY_F8
, ui::DomCode::F8
, ui::EF_NONE
, ui::DomKey::F8
, 0}},
2718 {KeyTestCase::TEST_ALL
,
2721 ui::DomCode::DIGIT9
,
2722 ui::EF_COMMAND_DOWN
,
2723 ui::DomKey::CHARACTER
,
2725 {ui::VKEY_F9
, ui::DomCode::F9
, ui::EF_NONE
, ui::DomKey::F9
, 0}},
2726 {KeyTestCase::TEST_ALL
,
2729 ui::DomCode::DIGIT0
,
2730 ui::EF_COMMAND_DOWN
,
2731 ui::DomKey::CHARACTER
,
2733 {ui::VKEY_F10
, ui::DomCode::F10
, ui::EF_NONE
, ui::DomKey::F10
, 0}},
2734 {KeyTestCase::TEST_ALL
,
2736 {ui::VKEY_OEM_MINUS
,
2738 ui::EF_COMMAND_DOWN
,
2739 ui::DomKey::CHARACTER
,
2741 {ui::VKEY_F11
, ui::DomCode::F11
, ui::EF_NONE
, ui::DomKey::F11
, 0}},
2742 {KeyTestCase::TEST_ALL
,
2746 ui::EF_COMMAND_DOWN
,
2747 ui::DomKey::CHARACTER
,
2749 {ui::VKEY_F12
, ui::DomCode::F12
, ui::EF_NONE
, ui::DomKey::F12
, 0}},
2751 // The function keys should not be rewritten with Search key pressed.
2752 {KeyTestCase::TEST_ALL
,
2754 {ui::VKEY_F1
, ui::DomCode::F1
, ui::EF_COMMAND_DOWN
, ui::DomKey::F1
, 0},
2755 {ui::VKEY_F1
, ui::DomCode::F1
, ui::EF_NONE
, ui::DomKey::F1
, 0}},
2756 {KeyTestCase::TEST_ALL
,
2758 {ui::VKEY_F2
, ui::DomCode::F2
, ui::EF_COMMAND_DOWN
, ui::DomKey::F2
, 0},
2759 {ui::VKEY_F2
, ui::DomCode::F2
, ui::EF_NONE
, ui::DomKey::F2
, 0}},
2760 {KeyTestCase::TEST_ALL
,
2762 {ui::VKEY_F3
, ui::DomCode::F3
, ui::EF_COMMAND_DOWN
, ui::DomKey::F3
, 0},
2763 {ui::VKEY_F3
, ui::DomCode::F3
, ui::EF_NONE
, ui::DomKey::F3
, 0}},
2764 {KeyTestCase::TEST_ALL
,
2766 {ui::VKEY_F4
, ui::DomCode::F4
, ui::EF_COMMAND_DOWN
, ui::DomKey::F4
, 0},
2767 {ui::VKEY_F4
, ui::DomCode::F4
, ui::EF_NONE
, ui::DomKey::F4
, 0}},
2768 {KeyTestCase::TEST_ALL
,
2770 {ui::VKEY_F5
, ui::DomCode::F5
, ui::EF_COMMAND_DOWN
, ui::DomKey::F5
, 0},
2771 {ui::VKEY_F5
, ui::DomCode::F5
, ui::EF_NONE
, ui::DomKey::F5
, 0}},
2772 {KeyTestCase::TEST_ALL
,
2774 {ui::VKEY_F6
, ui::DomCode::F6
, ui::EF_COMMAND_DOWN
, ui::DomKey::F6
, 0},
2775 {ui::VKEY_F6
, ui::DomCode::F6
, ui::EF_NONE
, ui::DomKey::F6
, 0}},
2776 {KeyTestCase::TEST_ALL
,
2778 {ui::VKEY_F7
, ui::DomCode::F7
, ui::EF_COMMAND_DOWN
, ui::DomKey::F7
, 0},
2779 {ui::VKEY_F7
, ui::DomCode::F7
, ui::EF_NONE
, ui::DomKey::F7
, 0}},
2780 {KeyTestCase::TEST_ALL
,
2782 {ui::VKEY_F8
, ui::DomCode::F8
, ui::EF_COMMAND_DOWN
, ui::DomKey::F8
, 0},
2783 {ui::VKEY_F8
, ui::DomCode::F8
, ui::EF_NONE
, ui::DomKey::F8
, 0}},
2784 {KeyTestCase::TEST_ALL
,
2786 {ui::VKEY_F9
, ui::DomCode::F9
, ui::EF_COMMAND_DOWN
, ui::DomKey::F9
, 0},
2787 {ui::VKEY_F9
, ui::DomCode::F9
, ui::EF_NONE
, ui::DomKey::F9
, 0}},
2788 {KeyTestCase::TEST_ALL
,
2792 ui::EF_COMMAND_DOWN
,
2795 {ui::VKEY_F10
, ui::DomCode::F10
, ui::EF_NONE
, ui::DomKey::F10
, 0}},
2796 {KeyTestCase::TEST_ALL
,
2800 ui::EF_COMMAND_DOWN
,
2803 {ui::VKEY_F11
, ui::DomCode::F11
, ui::EF_NONE
, ui::DomKey::F11
, 0}},
2804 {KeyTestCase::TEST_ALL
,
2808 ui::EF_COMMAND_DOWN
,
2811 {ui::VKEY_F12
, ui::DomCode::F12
, ui::EF_NONE
, ui::DomKey::F12
, 0}}};
2813 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
2815 CheckKeyTestCase(&rewriter
, tests
[i
]);
2819 TEST_F(EventRewriterTest
, TestRewriteExtendedKeysWithSearchRemapped
) {
2820 const base::CommandLine
original_cl(*base::CommandLine::ForCurrentProcess());
2822 // Remap Search to Control.
2823 TestingPrefServiceSyncable prefs
;
2824 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
2825 IntegerPrefMember search
;
2826 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
2827 search
.SetValue(chromeos::input_method::kControlKey
);
2829 EventRewriter
rewriter(NULL
);
2830 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
2831 rewriter
.set_pref_service_for_testing(&prefs
);
2833 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
2834 chromeos::switches::kHasChromeOSKeyboard
, "");
2836 KeyTestCase tests
[] = {
2837 // Alt+Search+Down -> End
2838 {KeyTestCase::TEST_ALL
,
2841 ui::DomCode::ARROW_DOWN
,
2842 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
2843 ui::DomKey::ARROW_DOWN
,
2845 {ui::VKEY_END
, ui::DomCode::END
, ui::EF_NONE
, ui::DomKey::END
, 0}},
2847 // Shift+Alt+Search+Down -> Shift+End
2848 {KeyTestCase::TEST_ALL
,
2851 ui::DomCode::ARROW_DOWN
,
2852 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
2853 ui::DomKey::ARROW_DOWN
,
2855 {ui::VKEY_END
, ui::DomCode::END
, ui::EF_SHIFT_DOWN
, ui::DomKey::END
, 0}},
2858 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
2860 CheckKeyTestCase(&rewriter
, tests
[i
]);
2863 *base::CommandLine::ForCurrentProcess() = original_cl
;
2866 TEST_F(EventRewriterTest
, TestRewriteKeyEventSentByXSendEvent
) {
2867 // Remap Control to Alt.
2868 TestingPrefServiceSyncable prefs
;
2869 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
2870 IntegerPrefMember control
;
2871 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
2872 control
.SetValue(chromeos::input_method::kAltKey
);
2874 EventRewriter
rewriter(NULL
);
2875 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
2876 rewriter
.set_pref_service_for_testing(&prefs
);
2878 // Send left control press.
2880 ui::KeyEvent
keyevent(ui::ET_KEY_PRESSED
, ui::VKEY_CONTROL
,
2881 ui::DomCode::CONTROL_LEFT
, ui::EF_FINAL
,
2882 ui::DomKey::CONTROL
, 0, ui::EventTimeForNow());
2883 scoped_ptr
<ui::Event
> new_event
;
2884 // Control should NOT be remapped to Alt if EF_FINAL is set.
2885 EXPECT_EQ(ui::EVENT_REWRITE_CONTINUE
,
2886 rewriter
.RewriteEvent(keyevent
, &new_event
));
2887 EXPECT_FALSE(new_event
);
2889 #if defined(USE_X11)
2890 // Send left control press, using XI2 native events.
2892 ui::ScopedXI2Event xev
;
2893 xev
.InitKeyEvent(ui::ET_KEY_PRESSED
, ui::VKEY_CONTROL
, 0);
2894 XEvent
* xevent
= xev
;
2895 xevent
->xkey
.keycode
= XKeysymToKeycode(gfx::GetXDisplay(), XK_Control_L
);
2896 xevent
->xkey
.send_event
= True
; // XSendEvent() always does this.
2897 ui::KeyEvent
keyevent(xev
);
2898 scoped_ptr
<ui::Event
> new_event
;
2899 // Control should NOT be remapped to Alt if send_event
2900 // flag in the event is True.
2901 EXPECT_EQ(ui::EVENT_REWRITE_CONTINUE
,
2902 rewriter
.RewriteEvent(keyevent
, &new_event
));
2903 EXPECT_FALSE(new_event
);
2908 TEST_F(EventRewriterTest
, TestRewriteNonNativeEvent
) {
2909 // Remap Control to Alt.
2910 TestingPrefServiceSyncable prefs
;
2911 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
2912 IntegerPrefMember control
;
2913 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
2914 control
.SetValue(chromeos::input_method::kAltKey
);
2916 EventRewriter
rewriter(NULL
);
2917 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
2918 rewriter
.set_pref_service_for_testing(&prefs
);
2920 const int kTouchId
= 2;
2921 gfx::Point
location(0, 0);
2922 ui::TouchEvent
press(ui::ET_TOUCH_PRESSED
, location
, kTouchId
,
2924 press
.set_flags(ui::EF_CONTROL_DOWN
);
2925 #if defined(USE_X11)
2926 ui::UpdateX11EventForFlags(&press
);
2929 scoped_ptr
<ui::Event
> new_event
;
2930 rewriter
.RewriteEvent(press
, &new_event
);
2931 EXPECT_TRUE(new_event
);
2932 // Control should be remapped to Alt.
2933 EXPECT_EQ(ui::EF_ALT_DOWN
,
2934 new_event
->flags() & (ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
));
2937 // Keeps a buffer of handled events.
2938 class EventBuffer
: public ui::test::TestEventProcessor
{
2941 ~EventBuffer() override
{}
2943 void PopEvents(ScopedVector
<ui::Event
>* events
) {
2945 events
->swap(events_
);
2949 // ui::EventProcessor overrides:
2950 ui::EventDispatchDetails
OnEventFromSource(ui::Event
* event
) override
{
2951 if (event
->IsKeyEvent()) {
2952 events_
.push_back(new ui::KeyEvent(*static_cast<ui::KeyEvent
*>(event
)));
2953 } else if (event
->IsMouseWheelEvent()) {
2955 new ui::MouseWheelEvent(*static_cast<ui::MouseWheelEvent
*>(event
)));
2956 } else if (event
->IsMouseEvent()) {
2958 new ui::MouseEvent(*static_cast<ui::MouseEvent
*>(event
)));
2960 return ui::EventDispatchDetails();
2963 ScopedVector
<ui::Event
> events_
;
2965 DISALLOW_COPY_AND_ASSIGN(EventBuffer
);
2968 // Trivial EventSource that does nothing but send events.
2969 class TestEventSource
: public ui::EventSource
{
2971 explicit TestEventSource(ui::EventProcessor
* processor
)
2972 : processor_(processor
) {}
2973 ui::EventProcessor
* GetEventProcessor() override
{ return processor_
; }
2974 ui::EventDispatchDetails
Send(ui::Event
* event
) {
2975 return SendEventToProcessor(event
);
2979 ui::EventProcessor
* processor_
;
2982 // Tests of event rewriting that depend on the Ash window manager.
2983 class EventRewriterAshTest
: public ash::test::AshTestBase
{
2985 EventRewriterAshTest()
2986 : source_(&buffer_
),
2987 fake_user_manager_(new user_manager::FakeUserManager
),
2988 user_manager_enabler_(fake_user_manager_
) {}
2989 ~EventRewriterAshTest() override
{}
2991 bool RewriteFunctionKeys(const ui::Event
& event
,
2992 scoped_ptr
<ui::Event
>* rewritten_event
) {
2993 return rewriter_
->RewriteEvent(event
, rewritten_event
);
2996 ui::EventDispatchDetails
Send(ui::Event
* event
) {
2997 return source_
.Send(event
);
3000 void SendKeyEvent(ui::EventType type
,
3001 ui::KeyboardCode key_code
,
3004 base::char16 character
) {
3005 ui::KeyEvent
press(type
, key_code
, code
, ui::EF_NONE
, key
, character
,
3006 ui::EventTimeForNow());
3007 ui::EventDispatchDetails details
= Send(&press
);
3008 CHECK(!details
.dispatcher_destroyed
);
3011 void SendActivateStickyKeyPattern(ui::KeyboardCode key_code
,
3014 base::char16 character
) {
3015 SendKeyEvent(ui::ET_KEY_PRESSED
, key_code
, code
, key
, character
);
3016 SendKeyEvent(ui::ET_KEY_RELEASED
, key_code
, code
, key
, character
);
3020 TestingPrefServiceSyncable
* prefs() { return &prefs_
; }
3022 void PopEvents(ScopedVector
<ui::Event
>* events
) { buffer_
.PopEvents(events
); }
3024 void SetUp() override
{
3025 AshTestBase::SetUp();
3026 sticky_keys_controller_
=
3027 ash::Shell::GetInstance()->sticky_keys_controller();
3028 rewriter_
.reset(new EventRewriter(sticky_keys_controller_
));
3029 chromeos::Preferences::RegisterProfilePrefs(prefs_
.registry());
3030 rewriter_
->set_pref_service_for_testing(&prefs_
);
3031 #if defined(USE_X11)
3032 ui::SetUpTouchPadForTest(kTouchPadDeviceId
);
3034 source_
.AddEventRewriter(rewriter_
.get());
3035 sticky_keys_controller_
->Enable(true);
3038 void TearDown() override
{
3040 AshTestBase::TearDown();
3044 ash::StickyKeysController
* sticky_keys_controller_
;
3047 scoped_ptr
<EventRewriter
> rewriter_
;
3049 EventBuffer buffer_
;
3050 TestEventSource source_
;
3052 user_manager::FakeUserManager
* fake_user_manager_
; // Not owned.
3053 chromeos::ScopedUserManagerEnabler user_manager_enabler_
;
3054 TestingPrefServiceSyncable prefs_
;
3056 DISALLOW_COPY_AND_ASSIGN(EventRewriterAshTest
);
3059 TEST_F(EventRewriterAshTest
, TopRowKeysAreFunctionKeys
) {
3060 scoped_ptr
<aura::Window
> window(CreateTestWindowInShellWithId(1));
3061 ash::wm::WindowState
* window_state
= ash::wm::GetWindowState(window
.get());
3062 window_state
->Activate();
3063 ScopedVector
<ui::Event
> events
;
3065 // Create a simulated keypress of F1 targetted at the window.
3066 ui::KeyEvent
press_f1(ui::ET_KEY_PRESSED
, ui::VKEY_F1
, ui::DomCode::F1
,
3067 ui::EF_NONE
, ui::DomKey::F1
, 0, ui::EventTimeForNow());
3069 // Simulate an apps v2 window that has requested top row keys as function
3070 // keys. The event should not be rewritten.
3071 window_state
->set_top_row_keys_are_function_keys(true);
3072 ui::EventDispatchDetails details
= Send(&press_f1
);
3073 ASSERT_FALSE(details
.dispatcher_destroyed
);
3075 EXPECT_EQ(1u, events
.size());
3076 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_F1
,
3077 ui::DomCode::F1
, ui::EF_NONE
,
3079 GetKeyEventAsString(*static_cast<ui::KeyEvent
*>(events
[0])));
3081 // The event should also not be rewritten if the send-function-keys pref is
3082 // additionally set, for both apps v2 and regular windows.
3083 BooleanPrefMember send_function_keys_pref
;
3084 send_function_keys_pref
.Init(prefs::kLanguageSendFunctionKeys
, prefs());
3085 send_function_keys_pref
.SetValue(true);
3086 window_state
->set_top_row_keys_are_function_keys(false);
3087 details
= Send(&press_f1
);
3088 ASSERT_FALSE(details
.dispatcher_destroyed
);
3090 EXPECT_EQ(1u, events
.size());
3091 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_F1
,
3092 ui::DomCode::F1
, ui::EF_NONE
,
3094 GetKeyEventAsString(*static_cast<ui::KeyEvent
*>(events
[0])));
3096 // If the pref isn't set when an event is sent to a regular window, F1 is
3097 // rewritten to the back key.
3098 send_function_keys_pref
.SetValue(false);
3099 details
= Send(&press_f1
);
3100 ASSERT_FALSE(details
.dispatcher_destroyed
);
3102 EXPECT_EQ(1u, events
.size());
3103 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_BROWSER_BACK
,
3104 ui::DomCode::BROWSER_BACK
, ui::EF_NONE
,
3105 ui::DomKey::BROWSER_BACK
, 0),
3106 GetKeyEventAsString(*static_cast<ui::KeyEvent
*>(events
[0])));
3109 TEST_F(EventRewriterTest
, TestRewrittenModifierClick
) {
3110 #if defined(USE_X11)
3111 std::vector
<int> device_list
;
3112 device_list
.push_back(10);
3113 ui::TouchFactory::GetInstance()->SetPointerDeviceForTest(device_list
);
3115 // Remap Control to Alt.
3116 TestingPrefServiceSyncable prefs
;
3117 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
3118 IntegerPrefMember control
;
3119 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
3120 control
.SetValue(chromeos::input_method::kAltKey
);
3122 EventRewriter
rewriter(NULL
);
3123 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
3124 rewriter
.set_pref_service_for_testing(&prefs
);
3126 // Check that Control + Left Button is converted (via Alt + Left Button)
3128 ui::ScopedXI2Event xev
;
3129 xev
.InitGenericButtonEvent(10, ui::ET_MOUSE_PRESSED
, gfx::Point(),
3130 ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_CONTROL_DOWN
);
3131 ui::MouseEvent
press(xev
);
3133 EXPECT_EQ(ui::ET_MOUSE_PRESSED
, press
.type());
3134 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_CONTROL_DOWN
, press
.flags());
3135 scoped_ptr
<ui::Event
> new_event
;
3136 const ui::MouseEvent
* result
=
3137 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
3138 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
3139 EXPECT_FALSE(ui::EF_LEFT_MOUSE_BUTTON
& result
->flags());
3140 EXPECT_FALSE(ui::EF_CONTROL_DOWN
& result
->flags());
3141 EXPECT_FALSE(ui::EF_ALT_DOWN
& result
->flags());
3142 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
3146 TEST_F(EventRewriterTest
, DontRewriteIfNotRewritten
) {
3147 // TODO(kpschoedel): pending changes for crbug.com/360377
3148 // to |chromeos::EventRewriter::RewriteLocatedEvent()
3149 #if defined(USE_X11)
3150 std::vector
<int> device_list
;
3151 device_list
.push_back(10);
3152 device_list
.push_back(11);
3153 ui::TouchFactory::GetInstance()->SetPointerDeviceForTest(device_list
);
3155 TestingPrefServiceSyncable prefs
;
3156 EventRewriter
rewriter(NULL
);
3157 rewriter
.set_pref_service_for_testing(&prefs
);
3158 const int kLeftAndAltFlag
= ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_ALT_DOWN
;
3160 // Test Alt + Left click.
3162 ui::MouseEvent
press(ui::ET_MOUSE_PRESSED
, gfx::Point(), gfx::Point(),
3163 ui::EventTimeForNow(), kLeftAndAltFlag
,
3164 ui::EF_LEFT_MOUSE_BUTTON
);
3165 ui::EventTestApi
test_press(&press
);
3166 test_press
.set_source_device_id(10);
3168 EXPECT_EQ(ui::ET_MOUSE_PRESSED
, press
.type());
3169 EXPECT_EQ(kLeftAndAltFlag
, press
.flags());
3170 scoped_ptr
<ui::Event
> new_event
;
3171 const ui::MouseEvent
* result
=
3172 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
3173 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
3174 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
3175 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
3178 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
, gfx::Point(), gfx::Point(),
3179 ui::EventTimeForNow(), kLeftAndAltFlag
,
3180 ui::EF_LEFT_MOUSE_BUTTON
);
3181 ui::EventTestApi
test_release(&release
);
3182 test_release
.set_source_device_id(10);
3183 scoped_ptr
<ui::Event
> new_event
;
3184 const ui::MouseEvent
* result
=
3185 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
3186 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
3187 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
3188 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
3190 #if defined(USE_X11)
3191 // Test Alt + Left click, using XI2 native events.
3193 ui::ScopedXI2Event xev
;
3194 xev
.InitGenericButtonEvent(10, ui::ET_MOUSE_PRESSED
, gfx::Point(),
3196 ui::MouseEvent
press(xev
);
3198 EXPECT_EQ(ui::ET_MOUSE_PRESSED
, press
.type());
3199 EXPECT_EQ(kLeftAndAltFlag
, press
.flags());
3200 scoped_ptr
<ui::Event
> new_event
;
3201 const ui::MouseEvent
* result
=
3202 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
3203 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
3204 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
3205 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
3208 ui::ScopedXI2Event xev
;
3209 xev
.InitGenericButtonEvent(10, ui::ET_MOUSE_RELEASED
, gfx::Point(),
3211 ui::MouseEvent
release(xev
);
3212 scoped_ptr
<ui::Event
> new_event
;
3213 const ui::MouseEvent
* result
=
3214 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
3215 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
3216 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
3217 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
3221 // No ALT in frst click.
3223 ui::MouseEvent
press(ui::ET_MOUSE_PRESSED
, gfx::Point(), gfx::Point(),
3224 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON
,
3225 ui::EF_LEFT_MOUSE_BUTTON
);
3226 ui::EventTestApi
test_press(&press
);
3227 test_press
.set_source_device_id(10);
3228 scoped_ptr
<ui::Event
> new_event
;
3229 const ui::MouseEvent
* result
=
3230 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
3231 EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON
& result
->flags());
3232 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
3235 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
, gfx::Point(), gfx::Point(),
3236 ui::EventTimeForNow(), kLeftAndAltFlag
,
3237 ui::EF_LEFT_MOUSE_BUTTON
);
3238 ui::EventTestApi
test_release(&release
);
3239 test_release
.set_source_device_id(10);
3240 scoped_ptr
<ui::Event
> new_event
;
3241 const ui::MouseEvent
* result
=
3242 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
3243 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_ALT_DOWN
) & result
->flags());
3244 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
3246 #if defined(USE_X11)
3247 // No ALT in frst click, using XI2 native events.
3249 ui::ScopedXI2Event xev
;
3250 xev
.InitGenericButtonEvent(10, ui::ET_MOUSE_PRESSED
, gfx::Point(),
3251 ui::EF_LEFT_MOUSE_BUTTON
);
3252 ui::MouseEvent
press(xev
);
3253 scoped_ptr
<ui::Event
> new_event
;
3254 const ui::MouseEvent
* result
=
3255 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
3256 EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON
& result
->flags());
3257 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
3260 ui::ScopedXI2Event xev
;
3261 xev
.InitGenericButtonEvent(10, ui::ET_MOUSE_RELEASED
, gfx::Point(),
3263 ui::MouseEvent
release(xev
);
3264 scoped_ptr
<ui::Event
> new_event
;
3265 const ui::MouseEvent
* result
=
3266 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
3267 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_ALT_DOWN
) & result
->flags());
3268 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
3272 // ALT on different device.
3274 ui::MouseEvent
press(ui::ET_MOUSE_PRESSED
, gfx::Point(), gfx::Point(),
3275 ui::EventTimeForNow(), kLeftAndAltFlag
,
3276 ui::EF_LEFT_MOUSE_BUTTON
);
3277 ui::EventTestApi
test_press(&press
);
3278 test_press
.set_source_device_id(11);
3279 scoped_ptr
<ui::Event
> new_event
;
3280 const ui::MouseEvent
* result
=
3281 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
3282 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
3283 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
3284 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
3287 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
, gfx::Point(), gfx::Point(),
3288 ui::EventTimeForNow(), kLeftAndAltFlag
,
3289 ui::EF_LEFT_MOUSE_BUTTON
);
3290 ui::EventTestApi
test_release(&release
);
3291 test_release
.set_source_device_id(10);
3292 scoped_ptr
<ui::Event
> new_event
;
3293 const ui::MouseEvent
* result
=
3294 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
3295 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_ALT_DOWN
) & result
->flags());
3296 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
3299 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
, gfx::Point(), gfx::Point(),
3300 ui::EventTimeForNow(), kLeftAndAltFlag
,
3301 ui::EF_LEFT_MOUSE_BUTTON
);
3302 ui::EventTestApi
test_release(&release
);
3303 test_release
.set_source_device_id(11);
3304 scoped_ptr
<ui::Event
> new_event
;
3305 const ui::MouseEvent
* result
=
3306 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
3307 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
3308 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
3309 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
3311 #if defined(USE_X11)
3312 // ALT on different device, using XI2 native events.
3314 ui::ScopedXI2Event xev
;
3315 xev
.InitGenericButtonEvent(11, ui::ET_MOUSE_PRESSED
, gfx::Point(),
3317 ui::MouseEvent
press(xev
);
3318 scoped_ptr
<ui::Event
> new_event
;
3319 const ui::MouseEvent
* result
=
3320 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
3321 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
3322 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
3323 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
3326 ui::ScopedXI2Event xev
;
3327 xev
.InitGenericButtonEvent(10, ui::ET_MOUSE_RELEASED
, gfx::Point(),
3329 ui::MouseEvent
release(xev
);
3330 scoped_ptr
<ui::Event
> new_event
;
3331 const ui::MouseEvent
* result
=
3332 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
3333 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_ALT_DOWN
) & result
->flags());
3334 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
3337 ui::ScopedXI2Event xev
;
3338 xev
.InitGenericButtonEvent(11, ui::ET_MOUSE_RELEASED
, gfx::Point(),
3340 ui::MouseEvent
release(xev
);
3341 scoped_ptr
<ui::Event
> new_event
;
3342 const ui::MouseEvent
* result
=
3343 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
3344 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
3345 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
3346 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
3351 TEST_F(EventRewriterAshTest
, StickyKeyEventDispatchImpl
) {
3352 // Test the actual key event dispatch implementation.
3353 ScopedVector
<ui::Event
> events
;
3355 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
3356 ui::DomKey::CONTROL
, 0);
3358 EXPECT_EQ(1u, events
.size());
3359 EXPECT_EQ(ui::ET_KEY_PRESSED
, events
[0]->type());
3360 EXPECT_EQ(ui::VKEY_CONTROL
,
3361 static_cast<ui::KeyEvent
*>(events
[0])->key_code());
3363 // Test key press event is correctly modified and modifier release
3365 ui::KeyEvent
press(ui::ET_KEY_PRESSED
, ui::VKEY_C
, ui::DomCode::KEY_C
,
3366 ui::EF_NONE
, ui::DomKey::CHARACTER
, 'c',
3367 ui::EventTimeForNow());
3368 ui::EventDispatchDetails details
= Send(&press
);
3370 EXPECT_EQ(2u, events
.size());
3371 EXPECT_EQ(ui::ET_KEY_PRESSED
, events
[0]->type());
3372 EXPECT_EQ(ui::VKEY_C
, static_cast<ui::KeyEvent
*>(events
[0])->key_code());
3373 EXPECT_TRUE(events
[0]->flags() & ui::EF_CONTROL_DOWN
);
3374 EXPECT_EQ(ui::ET_KEY_RELEASED
, events
[1]->type());
3375 EXPECT_EQ(ui::VKEY_CONTROL
,
3376 static_cast<ui::KeyEvent
*>(events
[1])->key_code());
3378 // Test key release event is not modified.
3379 ui::KeyEvent
release(ui::ET_KEY_RELEASED
, ui::VKEY_C
, ui::DomCode::KEY_C
,
3380 ui::EF_NONE
, ui::DomKey::CHARACTER
, 'c',
3381 ui::EventTimeForNow());
3382 details
= Send(&release
);
3383 ASSERT_FALSE(details
.dispatcher_destroyed
);
3385 EXPECT_EQ(1u, events
.size());
3386 EXPECT_EQ(ui::ET_KEY_RELEASED
, events
[0]->type());
3387 EXPECT_EQ(ui::VKEY_C
, static_cast<ui::KeyEvent
*>(events
[0])->key_code());
3388 EXPECT_FALSE(events
[0]->flags() & ui::EF_CONTROL_DOWN
);
3391 TEST_F(EventRewriterAshTest
, MouseEventDispatchImpl
) {
3392 ScopedVector
<ui::Event
> events
;
3394 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
3395 ui::DomKey::CONTROL
, 0);
3398 // Test mouse press event is correctly modified.
3399 gfx::Point
location(0, 0);
3400 ui::MouseEvent
press(ui::ET_MOUSE_PRESSED
, location
, location
,
3401 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON
,
3402 ui::EF_LEFT_MOUSE_BUTTON
);
3403 ui::EventDispatchDetails details
= Send(&press
);
3404 ASSERT_FALSE(details
.dispatcher_destroyed
);
3406 EXPECT_EQ(1u, events
.size());
3407 EXPECT_EQ(ui::ET_MOUSE_PRESSED
, events
[0]->type());
3408 EXPECT_TRUE(events
[0]->flags() & ui::EF_CONTROL_DOWN
);
3410 // Test mouse release event is correctly modified and modifier release
3411 // event is sent. The mouse event should have the correct DIP location.
3412 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
, location
, location
,
3413 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON
,
3414 ui::EF_LEFT_MOUSE_BUTTON
);
3415 details
= Send(&release
);
3416 ASSERT_FALSE(details
.dispatcher_destroyed
);
3418 EXPECT_EQ(2u, events
.size());
3419 EXPECT_EQ(ui::ET_MOUSE_RELEASED
, events
[0]->type());
3420 EXPECT_TRUE(events
[0]->flags() & ui::EF_CONTROL_DOWN
);
3421 EXPECT_EQ(ui::ET_KEY_RELEASED
, events
[1]->type());
3422 EXPECT_EQ(ui::VKEY_CONTROL
,
3423 static_cast<ui::KeyEvent
*>(events
[1])->key_code());
3426 TEST_F(EventRewriterAshTest
, MouseWheelEventDispatchImpl
) {
3427 ScopedVector
<ui::Event
> events
;
3429 // Test positive mouse wheel event is correctly modified and modifier release
3431 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
3432 ui::DomKey::CONTROL
, 0);
3434 gfx::Point
location(0, 0);
3435 ui::MouseEvent
mev(ui::ET_MOUSEWHEEL
, location
, location
,
3436 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON
,
3437 ui::EF_LEFT_MOUSE_BUTTON
);
3438 ui::MouseWheelEvent
positive(mev
, 0, ui::MouseWheelEvent::kWheelDelta
);
3439 ui::EventDispatchDetails details
= Send(&positive
);
3440 ASSERT_FALSE(details
.dispatcher_destroyed
);
3442 EXPECT_EQ(2u, events
.size());
3443 EXPECT_TRUE(events
[0]->IsMouseWheelEvent());
3444 EXPECT_TRUE(events
[0]->flags() & ui::EF_CONTROL_DOWN
);
3445 EXPECT_EQ(ui::ET_KEY_RELEASED
, events
[1]->type());
3446 EXPECT_EQ(ui::VKEY_CONTROL
,
3447 static_cast<ui::KeyEvent
*>(events
[1])->key_code());
3449 // Test negative mouse wheel event is correctly modified and modifier release
3451 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
3452 ui::DomKey::CONTROL
, 0);
3454 ui::MouseWheelEvent
negative(mev
, 0, -ui::MouseWheelEvent::kWheelDelta
);
3455 details
= Send(&negative
);
3456 ASSERT_FALSE(details
.dispatcher_destroyed
);
3458 EXPECT_EQ(2u, events
.size());
3459 EXPECT_TRUE(events
[0]->IsMouseWheelEvent());
3460 EXPECT_TRUE(events
[0]->flags() & ui::EF_CONTROL_DOWN
);
3461 EXPECT_EQ(ui::ET_KEY_RELEASED
, events
[1]->type());
3462 EXPECT_EQ(ui::VKEY_CONTROL
,
3463 static_cast<ui::KeyEvent
*>(events
[1])->key_code());
3466 class StickyKeysOverlayTest
: public EventRewriterAshTest
{
3468 StickyKeysOverlayTest() : overlay_(NULL
) {}
3470 ~StickyKeysOverlayTest() override
{}
3472 void SetUp() override
{
3473 EventRewriterAshTest::SetUp();
3474 overlay_
= sticky_keys_controller_
->GetOverlayForTest();
3475 ASSERT_TRUE(overlay_
);
3478 ash::StickyKeysOverlay
* overlay_
;
3481 TEST_F(StickyKeysOverlayTest
, OneModifierEnabled
) {
3482 EXPECT_FALSE(overlay_
->is_visible());
3483 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3484 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3486 // Pressing modifier key should show overlay.
3487 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
3488 ui::DomKey::CONTROL
, 0);
3489 EXPECT_TRUE(overlay_
->is_visible());
3490 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
3491 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3493 // Pressing a normal key should hide overlay.
3494 SendActivateStickyKeyPattern(ui::VKEY_T
, ui::DomCode::KEY_T
,
3495 ui::DomKey::CHARACTER
, 't');
3496 EXPECT_FALSE(overlay_
->is_visible());
3497 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3498 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3501 TEST_F(StickyKeysOverlayTest
, TwoModifiersEnabled
) {
3502 EXPECT_FALSE(overlay_
->is_visible());
3503 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3504 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3505 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3506 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
3508 // Pressing two modifiers should show overlay.
3509 SendActivateStickyKeyPattern(ui::VKEY_SHIFT
, ui::DomCode::SHIFT_LEFT
,
3510 ui::DomKey::SHIFT
, 0);
3511 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
3512 ui::DomKey::CONTROL
, 0);
3513 EXPECT_TRUE(overlay_
->is_visible());
3514 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
3515 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
3516 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
3517 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3519 // Pressing a normal key should hide overlay.
3520 SendActivateStickyKeyPattern(ui::VKEY_N
, ui::DomCode::KEY_N
,
3521 ui::DomKey::CHARACTER
, 'n');
3522 EXPECT_FALSE(overlay_
->is_visible());
3523 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3524 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3525 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3526 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
3529 TEST_F(StickyKeysOverlayTest
, LockedModifier
) {
3530 EXPECT_FALSE(overlay_
->is_visible());
3531 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3532 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
3534 // Pressing a modifier key twice should lock modifier and show overlay.
3535 SendActivateStickyKeyPattern(ui::VKEY_LMENU
, ui::DomCode::ALT_LEFT
,
3536 ui::DomKey::ALT
, 0);
3537 SendActivateStickyKeyPattern(ui::VKEY_LMENU
, ui::DomCode::ALT_LEFT
,
3538 ui::DomKey::ALT
, 0);
3539 EXPECT_TRUE(overlay_
->is_visible());
3540 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
3541 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
3543 // Pressing a normal key should not hide overlay.
3544 SendActivateStickyKeyPattern(ui::VKEY_D
, ui::DomCode::KEY_D
,
3545 ui::DomKey::CHARACTER
, 'd');
3546 EXPECT_TRUE(overlay_
->is_visible());
3547 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
3548 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
3551 TEST_F(StickyKeysOverlayTest
, LockedAndNormalModifier
) {
3552 EXPECT_FALSE(overlay_
->is_visible());
3553 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3554 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3555 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3556 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
3558 // Pressing a modifier key twice should lock modifier and show overlay.
3559 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
3560 ui::DomKey::CONTROL
, 0);
3561 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
3562 ui::DomKey::CONTROL
, 0);
3563 EXPECT_TRUE(overlay_
->is_visible());
3564 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
3565 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3567 // Pressing another modifier key should still show overlay.
3568 SendActivateStickyKeyPattern(ui::VKEY_SHIFT
, ui::DomCode::SHIFT_LEFT
,
3569 ui::DomKey::SHIFT
, 0);
3570 EXPECT_TRUE(overlay_
->is_visible());
3571 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
3572 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3573 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
3574 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
3576 // Pressing a normal key should not hide overlay but disable normal modifier.
3577 SendActivateStickyKeyPattern(ui::VKEY_D
, ui::DomCode::KEY_D
,
3578 ui::DomKey::CHARACTER
, 'd');
3579 EXPECT_TRUE(overlay_
->is_visible());
3580 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
3581 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3582 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3583 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
3586 TEST_F(StickyKeysOverlayTest
, ModifiersDisabled
) {
3587 EXPECT_FALSE(overlay_
->is_visible());
3588 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3589 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3590 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3591 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
3592 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3593 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
3594 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3595 overlay_
->GetModifierKeyState(ui::EF_COMMAND_DOWN
));
3597 // Enable modifiers.
3598 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
3599 ui::DomKey::CONTROL
, 0);
3600 SendActivateStickyKeyPattern(ui::VKEY_SHIFT
, ui::DomCode::SHIFT_LEFT
,
3601 ui::DomKey::SHIFT
, 0);
3602 SendActivateStickyKeyPattern(ui::VKEY_SHIFT
, ui::DomCode::SHIFT_LEFT
,
3603 ui::DomKey::SHIFT
, 0);
3604 SendActivateStickyKeyPattern(ui::VKEY_LMENU
, ui::DomCode::ALT_LEFT
,
3605 ui::DomKey::ALT
, 0);
3606 SendActivateStickyKeyPattern(ui::VKEY_COMMAND
, ui::DomCode::OS_LEFT
,
3608 SendActivateStickyKeyPattern(ui::VKEY_COMMAND
, ui::DomCode::OS_LEFT
,
3611 EXPECT_TRUE(overlay_
->is_visible());
3612 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
3613 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3614 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
3615 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
3616 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
3617 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
3618 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
3619 overlay_
->GetModifierKeyState(ui::EF_COMMAND_DOWN
));
3621 // Disable modifiers and overlay should be hidden.
3622 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
3623 ui::DomKey::CONTROL
, 0);
3624 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
3625 ui::DomKey::CONTROL
, 0);
3626 SendActivateStickyKeyPattern(ui::VKEY_SHIFT
, ui::DomCode::SHIFT_LEFT
,
3627 ui::DomKey::SHIFT
, 0);
3628 SendActivateStickyKeyPattern(ui::VKEY_LMENU
, ui::DomCode::ALT_LEFT
,
3629 ui::DomKey::ALT
, 0);
3630 SendActivateStickyKeyPattern(ui::VKEY_LMENU
, ui::DomCode::ALT_LEFT
,
3631 ui::DomKey::ALT
, 0);
3632 SendActivateStickyKeyPattern(ui::VKEY_COMMAND
, ui::DomCode::OS_LEFT
,
3635 EXPECT_FALSE(overlay_
->is_visible());
3636 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3637 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3638 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3639 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
3640 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3641 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
3642 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3643 overlay_
->GetModifierKeyState(ui::EF_COMMAND_DOWN
));
3646 TEST_F(StickyKeysOverlayTest
, ModifierVisibility
) {
3647 // All but AltGr and Mod3 should initially be visible.
3648 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_CONTROL_DOWN
));
3649 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_SHIFT_DOWN
));
3650 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_ALT_DOWN
));
3651 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_COMMAND_DOWN
));
3652 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_ALTGR_DOWN
));
3653 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_MOD3_DOWN
));
3655 // Turn all modifiers on.
3656 sticky_keys_controller_
->SetModifiersEnabled(true, true);
3657 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_CONTROL_DOWN
));
3658 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_SHIFT_DOWN
));
3659 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_ALT_DOWN
));
3660 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_COMMAND_DOWN
));
3661 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_ALTGR_DOWN
));
3662 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_MOD3_DOWN
));
3665 sticky_keys_controller_
->SetModifiersEnabled(false, true);
3666 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_ALTGR_DOWN
));
3667 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_MOD3_DOWN
));
3670 sticky_keys_controller_
->SetModifiersEnabled(true, false);
3671 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_ALTGR_DOWN
));
3672 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_MOD3_DOWN
));
3674 // Turn off AltGr and Mod3.
3675 sticky_keys_controller_
->SetModifiersEnabled(false, false);
3676 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_ALTGR_DOWN
));
3677 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_MOD3_DOWN
));
3680 } // namespace chromeos