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;
54 const int kKeyboardDeviceId
= 2;
56 std::string
GetExpectedResultAsString(ui::EventType ui_type
,
57 ui::KeyboardCode ui_keycode
,
59 int ui_flags
, // ui::EventFlags
61 base::char16 character
) {
62 return base::StringPrintf(
63 "type=%d code=0x%06X flags=0x%X vk=0x%02X key=0x%03X c=0x%02X", ui_type
,
64 static_cast<unsigned int>(code
), ui_flags
& ~ui::EF_IS_REPEAT
, ui_keycode
,
65 static_cast<unsigned int>(key
), character
);
68 std::string
GetKeyEventAsString(const ui::KeyEvent
& keyevent
) {
69 return GetExpectedResultAsString(
70 keyevent
.type(), keyevent
.key_code(), keyevent
.code(), keyevent
.flags(),
71 keyevent
.GetDomKey(), keyevent
.GetCharacter());
74 std::string
GetRewrittenEventAsString(chromeos::EventRewriter
* rewriter
,
75 ui::EventType ui_type
,
76 ui::KeyboardCode ui_keycode
,
78 int ui_flags
, // ui::EventFlags
80 base::char16 character
) {
81 const ui::KeyEvent
event(ui_type
, ui_keycode
, code
, ui_flags
, key
, character
,
82 ui::EventTimeForNow());
83 scoped_ptr
<ui::Event
> new_event
;
84 rewriter
->RewriteEvent(event
, &new_event
);
86 return GetKeyEventAsString(
87 static_cast<const ui::KeyEvent
&>(*new_event
.get()));
88 return GetKeyEventAsString(event
);
91 // Table entry for simple single key event rewriting tests.
95 ui::KeyboardCode key_code
;
97 int flags
; // ui::EventFlags
99 base::char16 character
;
103 std::string
GetTestCaseAsString(ui::EventType ui_type
,
104 const KeyTestCase::Event
& test
) {
105 return GetExpectedResultAsString(ui_type
, test
.key_code
, test
.code
,
106 test
.flags
, test
.key
, test
.character
);
109 // Tests a single stateless key rewrite operation.
110 void CheckKeyTestCase(chromeos::EventRewriter
* rewriter
,
111 const KeyTestCase
& test
) {
112 SCOPED_TRACE("\nSource: " + GetTestCaseAsString(test
.type
, test
.input
));
113 std::string expected
= GetTestCaseAsString(test
.type
, test
.expected
);
115 GetRewrittenEventAsString(rewriter
, test
.type
, test
.input
.key_code
,
116 test
.input
.code
, test
.input
.flags
,
117 test
.input
.key
, test
.input
.character
));
124 class EventRewriterTest
: public ash::test::AshTestBase
{
127 : fake_user_manager_(new user_manager::FakeUserManager
),
128 user_manager_enabler_(fake_user_manager_
),
129 input_method_manager_mock_(NULL
) {}
130 ~EventRewriterTest() override
{}
132 void SetUp() override
{
133 input_method_manager_mock_
=
134 new chromeos::input_method::MockInputMethodManager
;
135 chromeos::input_method::InitializeForTesting(
136 input_method_manager_mock_
); // pass ownership
138 AshTestBase::SetUp();
141 void TearDown() override
{
142 AshTestBase::TearDown();
143 // Shutdown() deletes the IME mock object.
144 chromeos::input_method::Shutdown();
148 void TestRewriteNumPadKeys();
149 void TestRewriteNumPadKeysOnAppleKeyboard();
151 const ui::MouseEvent
* RewriteMouseButtonEvent(
152 chromeos::EventRewriter
* rewriter
,
153 const ui::MouseEvent
& event
,
154 scoped_ptr
<ui::Event
>* new_event
) {
155 rewriter
->RewriteMouseButtonEventForTesting(event
, new_event
);
156 return *new_event
? static_cast<const ui::MouseEvent
*>(new_event
->get())
160 user_manager::FakeUserManager
* fake_user_manager_
; // Not owned.
161 chromeos::ScopedUserManagerEnabler user_manager_enabler_
;
162 chromeos::input_method::MockInputMethodManager
* input_method_manager_mock_
;
165 TEST_F(EventRewriterTest
, TestRewriteCommandToControl
) {
166 // First, test with a PC keyboard.
167 TestingPrefServiceSyncable prefs
;
168 EventRewriter
rewriter(NULL
);
169 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
170 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
171 rewriter
.set_pref_service_for_testing(&prefs
);
173 KeyTestCase pc_keyboard_tests
[] = {
174 // VKEY_A, Alt modifier.
179 ui::DomKey::UNIDENTIFIED
,
184 ui::DomKey::UNIDENTIFIED
,
187 // VKEY_A, Win modifier.
192 ui::DomKey::UNIDENTIFIED
,
197 ui::DomKey::UNIDENTIFIED
,
200 // VKEY_A, Alt+Win modifier.
204 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
205 ui::DomKey::UNIDENTIFIED
,
209 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
210 ui::DomKey::UNIDENTIFIED
,
213 // VKEY_LWIN (left Windows key), Alt modifier.
216 ui::DomCode::OS_LEFT
,
217 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
221 ui::DomCode::OS_LEFT
,
222 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
226 // VKEY_RWIN (right Windows key), Alt modifier.
229 ui::DomCode::OS_RIGHT
,
230 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
234 ui::DomCode::OS_RIGHT
,
235 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
240 for (const auto& test
: pc_keyboard_tests
) {
241 CheckKeyTestCase(&rewriter
, test
);
244 // An Apple keyboard reusing the ID, zero.
245 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "Apple Keyboard");
246 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
248 KeyTestCase apple_keyboard_tests
[] = {
249 // VKEY_A, Alt modifier.
254 ui::DomKey::UNIDENTIFIED
,
259 ui::DomKey::UNIDENTIFIED
,
262 // VKEY_A, Win modifier.
267 ui::DomKey::UNIDENTIFIED
,
272 ui::DomKey::CHARACTER
,
275 // VKEY_A, Alt+Win modifier.
279 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
280 ui::DomKey::UNIDENTIFIED
,
284 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
285 ui::DomKey::CHARACTER
,
288 // VKEY_LWIN (left Windows key), Alt modifier.
291 ui::DomCode::OS_LEFT
,
292 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
,
296 ui::DomCode::CONTROL_LEFT
,
297 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
301 // VKEY_RWIN (right Windows key), Alt modifier.
304 ui::DomCode::OS_RIGHT
,
305 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
,
309 ui::DomCode::CONTROL_RIGHT
,
310 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
315 for (const auto& test
: apple_keyboard_tests
) {
316 CheckKeyTestCase(&rewriter
, test
);
320 // For crbug.com/133896.
321 TEST_F(EventRewriterTest
, TestRewriteCommandToControlWithControlRemapped
) {
322 // Remap Control to Alt.
323 TestingPrefServiceSyncable prefs
;
324 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
325 IntegerPrefMember control
;
326 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
327 control
.SetValue(chromeos::input_method::kAltKey
);
329 EventRewriter
rewriter(NULL
);
330 rewriter
.set_pref_service_for_testing(&prefs
);
331 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
332 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
334 KeyTestCase pc_keyboard_tests
[] = {
335 // Control should be remapped to Alt.
338 ui::DomCode::CONTROL_LEFT
,
343 ui::DomCode::ALT_LEFT
,
349 for (const auto& test
: pc_keyboard_tests
) {
350 CheckKeyTestCase(&rewriter
, test
);
353 // An Apple keyboard reusing the ID, zero.
354 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "Apple Keyboard");
355 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
357 KeyTestCase apple_keyboard_tests
[] = {
358 // VKEY_LWIN (left Command key) with Alt modifier. The remapped Command
359 // key should never be re-remapped to Alt.
362 ui::DomCode::OS_LEFT
,
363 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
,
367 ui::DomCode::CONTROL_LEFT
,
368 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
372 // VKEY_RWIN (right Command key) with Alt modifier. The remapped Command
373 // key should never be re-remapped to Alt.
376 ui::DomCode::OS_RIGHT
,
377 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
,
381 ui::DomCode::CONTROL_RIGHT
,
382 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
387 for (const auto& test
: apple_keyboard_tests
) {
388 CheckKeyTestCase(&rewriter
, test
);
392 void EventRewriterTest::TestRewriteNumPadKeys() {
393 TestingPrefServiceSyncable prefs
;
394 EventRewriter
rewriter(NULL
);
395 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
396 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
397 rewriter
.set_pref_service_for_testing(&prefs
);
399 KeyTestCase tests
[] = {
400 // XK_KP_Insert (= NumPad 0 without Num Lock), no modifier.
403 ui::DomCode::NUMPAD0
,
408 ui::DomCode::NUMPAD0
,
410 ui::DomKey::CHARACTER
,
413 // XK_KP_Insert (= NumPad 0 without Num Lock), Alt modifier.
416 ui::DomCode::NUMPAD0
,
421 ui::DomCode::NUMPAD0
,
423 ui::DomKey::CHARACTER
,
426 // XK_KP_Delete (= NumPad . without Num Lock), Alt modifier.
429 ui::DomCode::NUMPAD_DECIMAL
,
434 ui::DomCode::NUMPAD_DECIMAL
,
436 ui::DomKey::CHARACTER
,
439 // XK_KP_End (= NumPad 1 without Num Lock), Alt modifier.
442 ui::DomCode::NUMPAD1
,
447 ui::DomCode::NUMPAD1
,
449 ui::DomKey::CHARACTER
,
452 // XK_KP_Down (= NumPad 2 without Num Lock), Alt modifier.
455 ui::DomCode::NUMPAD2
,
457 ui::DomKey::ARROW_DOWN
,
460 ui::DomCode::NUMPAD2
,
462 ui::DomKey::CHARACTER
,
465 // XK_KP_Next (= NumPad 3 without Num Lock), Alt modifier.
468 ui::DomCode::NUMPAD3
,
470 ui::DomKey::PAGE_DOWN
,
473 ui::DomCode::NUMPAD3
,
475 ui::DomKey::CHARACTER
,
478 // XK_KP_Left (= NumPad 4 without Num Lock), Alt modifier.
481 ui::DomCode::NUMPAD4
,
483 ui::DomKey::ARROW_LEFT
,
486 ui::DomCode::NUMPAD4
,
488 ui::DomKey::CHARACTER
,
491 // XK_KP_Begin (= NumPad 5 without Num Lock), Alt modifier.
494 ui::DomCode::NUMPAD5
,
499 ui::DomCode::NUMPAD5
,
501 ui::DomKey::CHARACTER
,
504 // XK_KP_Right (= NumPad 6 without Num Lock), Alt modifier.
507 ui::DomCode::NUMPAD6
,
509 ui::DomKey::ARROW_RIGHT
,
512 ui::DomCode::NUMPAD6
,
514 ui::DomKey::CHARACTER
,
517 // XK_KP_Home (= NumPad 7 without Num Lock), Alt modifier.
520 ui::DomCode::NUMPAD7
,
525 ui::DomCode::NUMPAD7
,
527 ui::DomKey::CHARACTER
,
530 // XK_KP_Up (= NumPad 8 without Num Lock), Alt modifier.
533 ui::DomCode::NUMPAD8
,
535 ui::DomKey::ARROW_UP
,
538 ui::DomCode::NUMPAD8
,
540 ui::DomKey::CHARACTER
,
543 // XK_KP_Prior (= NumPad 9 without Num Lock), Alt modifier.
546 ui::DomCode::NUMPAD9
,
551 ui::DomCode::NUMPAD9
,
553 ui::DomKey::CHARACTER
,
556 // XK_KP_0 (= NumPad 0 with Num Lock), Num Lock modifier.
559 ui::DomCode::NUMPAD0
,
561 ui::DomKey::CHARACTER
,
564 ui::DomCode::NUMPAD0
,
566 ui::DomKey::CHARACTER
,
569 // XK_KP_DECIMAL (= NumPad . with Num Lock), Num Lock modifier.
572 ui::DomCode::NUMPAD_DECIMAL
,
574 ui::DomKey::CHARACTER
,
577 ui::DomCode::NUMPAD_DECIMAL
,
579 ui::DomKey::CHARACTER
,
582 // XK_KP_1 (= NumPad 1 with Num Lock), Num Lock modifier.
585 ui::DomCode::NUMPAD1
,
587 ui::DomKey::CHARACTER
,
590 ui::DomCode::NUMPAD1
,
592 ui::DomKey::CHARACTER
,
595 // XK_KP_2 (= NumPad 2 with Num Lock), Num Lock modifier.
598 ui::DomCode::NUMPAD2
,
600 ui::DomKey::CHARACTER
,
603 ui::DomCode::NUMPAD2
,
605 ui::DomKey::CHARACTER
,
608 // XK_KP_3 (= NumPad 3 with Num Lock), Num Lock modifier.
611 ui::DomCode::NUMPAD3
,
613 ui::DomKey::CHARACTER
,
616 ui::DomCode::NUMPAD3
,
618 ui::DomKey::CHARACTER
,
621 // XK_KP_4 (= NumPad 4 with Num Lock), Num Lock modifier.
624 ui::DomCode::NUMPAD4
,
626 ui::DomKey::CHARACTER
,
629 ui::DomCode::NUMPAD4
,
631 ui::DomKey::CHARACTER
,
634 // XK_KP_5 (= NumPad 5 with Num Lock), Num Lock
638 ui::DomCode::NUMPAD5
,
640 ui::DomKey::CHARACTER
,
643 ui::DomCode::NUMPAD5
,
645 ui::DomKey::CHARACTER
,
648 // XK_KP_6 (= NumPad 6 with Num Lock), Num Lock
652 ui::DomCode::NUMPAD6
,
654 ui::DomKey::CHARACTER
,
657 ui::DomCode::NUMPAD6
,
659 ui::DomKey::CHARACTER
,
662 // XK_KP_7 (= NumPad 7 with Num Lock), Num Lock
666 ui::DomCode::NUMPAD7
,
668 ui::DomKey::CHARACTER
,
671 ui::DomCode::NUMPAD7
,
673 ui::DomKey::CHARACTER
,
676 // XK_KP_8 (= NumPad 8 with Num Lock), Num Lock
680 ui::DomCode::NUMPAD8
,
682 ui::DomKey::CHARACTER
,
685 ui::DomCode::NUMPAD8
,
687 ui::DomKey::CHARACTER
,
690 // XK_KP_9 (= NumPad 9 with Num Lock), Num Lock
694 ui::DomCode::NUMPAD9
,
696 ui::DomKey::CHARACTER
,
699 ui::DomCode::NUMPAD9
,
701 ui::DomKey::CHARACTER
,
705 for (const auto& test
: tests
) {
706 CheckKeyTestCase(&rewriter
, test
);
710 TEST_F(EventRewriterTest
, TestRewriteNumPadKeys
) {
711 TestRewriteNumPadKeys();
714 TEST_F(EventRewriterTest
, TestRewriteNumPadKeysWithDiamondKeyFlag
) {
715 // Make sure the num lock works correctly even when Diamond key exists.
716 const base::CommandLine
original_cl(*base::CommandLine::ForCurrentProcess());
717 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
718 chromeos::switches::kHasChromeOSDiamondKey
, "");
720 TestRewriteNumPadKeys();
721 *base::CommandLine::ForCurrentProcess() = original_cl
;
724 // Tests if the rewriter can handle a Command + Num Pad event.
725 void EventRewriterTest::TestRewriteNumPadKeysOnAppleKeyboard() {
726 TestingPrefServiceSyncable prefs
;
727 EventRewriter
rewriter(NULL
);
728 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "Apple Keyboard");
729 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
730 rewriter
.set_pref_service_for_testing(&prefs
);
732 KeyTestCase tests
[] = {
733 // XK_KP_End (= NumPad 1 without Num Lock), Win modifier.
734 // The result should be "Num Pad 1 with Control + Num Lock modifiers".
737 ui::DomCode::NUMPAD1
,
742 ui::DomCode::NUMPAD1
,
744 ui::DomKey::UNIDENTIFIED
,
747 // XK_KP_1 (= NumPad 1 with Num Lock), Win modifier.
748 // The result should also be "Num Pad 1 with Control + Num Lock
752 ui::DomCode::NUMPAD1
,
754 ui::DomKey::CHARACTER
,
757 ui::DomCode::NUMPAD1
,
759 ui::DomKey::UNIDENTIFIED
,
762 for (const auto& test
: tests
) {
763 CheckKeyTestCase(&rewriter
, test
);
767 TEST_F(EventRewriterTest
, TestRewriteNumPadKeysOnAppleKeyboard
) {
768 TestRewriteNumPadKeysOnAppleKeyboard();
771 TEST_F(EventRewriterTest
,
772 TestRewriteNumPadKeysOnAppleKeyboardWithDiamondKeyFlag
) {
773 // Makes sure the num lock works correctly even when Diamond key exists.
774 const base::CommandLine
original_cl(*base::CommandLine::ForCurrentProcess());
775 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
776 chromeos::switches::kHasChromeOSDiamondKey
, "");
778 TestRewriteNumPadKeysOnAppleKeyboard();
779 *base::CommandLine::ForCurrentProcess() = original_cl
;
782 TEST_F(EventRewriterTest
, TestRewriteModifiersNoRemap
) {
783 TestingPrefServiceSyncable prefs
;
784 EventRewriter
rewriter(NULL
);
785 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
786 rewriter
.set_pref_service_for_testing(&prefs
);
788 KeyTestCase tests
[] = {
789 // Press Search. Confirm the event is not rewritten.
791 {ui::VKEY_LWIN
, ui::DomCode::OS_LEFT
, ui::EF_NONE
, ui::DomKey::OS
, 0},
793 ui::DomCode::OS_LEFT
,
798 // Press left Control. Confirm the event is not rewritten.
801 ui::DomCode::CONTROL_LEFT
,
806 ui::DomCode::CONTROL_LEFT
,
811 // Press right Control. Confirm the event is not rewritten.
814 ui::DomCode::CONTROL_LEFT
,
819 ui::DomCode::CONTROL_LEFT
,
824 // Press left Alt. Confirm the event is not rewritten.
827 ui::DomCode::ALT_LEFT
,
832 ui::DomCode::ALT_LEFT
,
837 // Press right Alt. Confirm the event is not rewritten.
840 ui::DomCode::ALT_LEFT
,
845 ui::DomCode::ALT_LEFT
,
850 // Test KeyRelease event, just in case.
851 // Release Search. Confirm the release event is not rewritten.
852 {ui::ET_KEY_RELEASED
,
853 {ui::VKEY_LWIN
, ui::DomCode::OS_LEFT
, ui::EF_NONE
, ui::DomKey::OS
, 0},
854 {ui::VKEY_LWIN
, ui::DomCode::OS_LEFT
, ui::EF_NONE
, ui::DomKey::OS
, 0}},
857 for (const auto& test
: tests
) {
858 CheckKeyTestCase(&rewriter
, test
);
862 TEST_F(EventRewriterTest
, TestRewriteModifiersNoRemapMultipleKeys
) {
863 TestingPrefServiceSyncable prefs
;
864 EventRewriter
rewriter(NULL
);
865 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
866 rewriter
.set_pref_service_for_testing(&prefs
);
868 KeyTestCase tests
[] = {
869 // Press Alt with Shift. Confirm the event is not rewritten.
872 ui::DomCode::ALT_LEFT
,
873 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
,
877 ui::DomCode::ALT_LEFT
,
878 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
,
882 // Press Search with Caps Lock mask. Confirm the event is not rewritten.
885 ui::DomCode::OS_LEFT
,
886 ui::EF_CAPS_LOCK_DOWN
| ui::EF_COMMAND_DOWN
,
890 ui::DomCode::OS_LEFT
,
891 ui::EF_CAPS_LOCK_DOWN
| ui::EF_COMMAND_DOWN
,
895 // Release Search with Caps Lock mask. Confirm the event is not rewritten.
896 {ui::ET_KEY_RELEASED
,
898 ui::DomCode::OS_LEFT
,
899 ui::EF_CAPS_LOCK_DOWN
,
903 ui::DomCode::OS_LEFT
,
904 ui::EF_CAPS_LOCK_DOWN
,
908 // Press Shift+Ctrl+Alt+Search+A. Confirm the event is not rewritten.
912 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
914 ui::DomKey::CHARACTER
,
918 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
920 ui::DomKey::CHARACTER
,
924 for (const auto& test
: tests
) {
925 CheckKeyTestCase(&rewriter
, test
);
929 TEST_F(EventRewriterTest
, TestRewriteModifiersDisableSome
) {
930 // Disable Search and Control keys.
931 TestingPrefServiceSyncable prefs
;
932 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
933 IntegerPrefMember search
;
934 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
935 search
.SetValue(chromeos::input_method::kVoidKey
);
936 IntegerPrefMember control
;
937 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
938 control
.SetValue(chromeos::input_method::kVoidKey
);
940 EventRewriter
rewriter(NULL
);
941 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
942 rewriter
.set_pref_service_for_testing(&prefs
);
944 KeyTestCase disabled_modifier_tests
[] = {
945 // Press Alt with Shift. This key press shouldn't be affected by the
946 // pref. Confirm the event is not rewritten.
949 ui::DomCode::ALT_LEFT
,
950 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
,
954 ui::DomCode::ALT_LEFT
,
955 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
,
959 // Press Search. Confirm the event is now VKEY_UNKNOWN.
961 {ui::VKEY_LWIN
, ui::DomCode::OS_LEFT
, ui::EF_NONE
, ui::DomKey::OS
, 0},
965 ui::DomKey::UNIDENTIFIED
,
968 // Press Control. Confirm the event is now VKEY_UNKNOWN.
971 ui::DomCode::CONTROL_LEFT
,
978 ui::DomKey::UNIDENTIFIED
,
981 // Press Control+Search. Confirm the event is now VKEY_UNKNOWN
982 // without any modifiers.
985 ui::DomCode::OS_LEFT
,
992 ui::DomKey::UNIDENTIFIED
,
995 // Press Control+Search+a. Confirm the event is now VKEY_A without any
1000 ui::EF_CONTROL_DOWN
,
1001 ui::DomKey::CHARACTER
,
1006 ui::DomKey::CHARACTER
,
1009 // Press Control+Search+Alt+a. Confirm the event is now VKEY_A only with
1010 // the Alt modifier.
1011 {ui::ET_KEY_PRESSED
,
1014 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
1015 ui::DomKey::CHARACTER
,
1020 ui::DomKey::CHARACTER
,
1024 for (const auto& test
: disabled_modifier_tests
) {
1025 CheckKeyTestCase(&rewriter
, test
);
1028 // Remap Alt to Control.
1029 IntegerPrefMember alt
;
1030 alt
.Init(prefs::kLanguageRemapAltKeyTo
, &prefs
);
1031 alt
.SetValue(chromeos::input_method::kControlKey
);
1033 KeyTestCase tests
[] = {
1034 // Press left Alt. Confirm the event is now VKEY_CONTROL
1035 // even though the Control key itself is disabled.
1036 {ui::ET_KEY_PRESSED
,
1038 ui::DomCode::ALT_LEFT
,
1043 ui::DomCode::CONTROL_LEFT
,
1044 ui::EF_CONTROL_DOWN
,
1045 ui::DomKey::CONTROL
,
1048 // Press Alt+a. Confirm the event is now Control+a even though the Control
1049 // key itself is disabled.
1050 {ui::ET_KEY_PRESSED
,
1054 ui::DomKey::CHARACTER
,
1058 ui::EF_CONTROL_DOWN
,
1059 ui::DomKey::CHARACTER
,
1063 for (const auto& test
: tests
) {
1064 CheckKeyTestCase(&rewriter
, test
);
1068 TEST_F(EventRewriterTest
, TestRewriteModifiersRemapToControl
) {
1069 // Remap Search to Control.
1070 TestingPrefServiceSyncable prefs
;
1071 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1072 IntegerPrefMember search
;
1073 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
1074 search
.SetValue(chromeos::input_method::kControlKey
);
1076 EventRewriter
rewriter(NULL
);
1077 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1078 rewriter
.set_pref_service_for_testing(&prefs
);
1080 KeyTestCase s_tests
[] = {
1081 // Press Search. Confirm the event is now VKEY_CONTROL.
1082 {ui::ET_KEY_PRESSED
,
1084 ui::DomCode::OS_LEFT
,
1085 ui::EF_COMMAND_DOWN
,
1089 ui::DomCode::CONTROL_LEFT
,
1090 ui::EF_CONTROL_DOWN
,
1091 ui::DomKey::CONTROL
,
1095 for (const auto& test
: s_tests
) {
1096 CheckKeyTestCase(&rewriter
, test
);
1099 // Remap Alt to Control too.
1100 IntegerPrefMember alt
;
1101 alt
.Init(prefs::kLanguageRemapAltKeyTo
, &prefs
);
1102 alt
.SetValue(chromeos::input_method::kControlKey
);
1104 KeyTestCase sa_tests
[] = {
1105 // Press Alt. Confirm the event is now VKEY_CONTROL.
1106 {ui::ET_KEY_PRESSED
,
1108 ui::DomCode::ALT_LEFT
,
1113 ui::DomCode::CONTROL_LEFT
,
1114 ui::EF_CONTROL_DOWN
,
1115 ui::DomKey::CONTROL
,
1118 // Press Alt+Search. Confirm the event is now VKEY_CONTROL.
1119 {ui::ET_KEY_PRESSED
,
1121 ui::DomCode::OS_LEFT
,
1122 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
1126 ui::DomCode::CONTROL_LEFT
,
1127 ui::EF_CONTROL_DOWN
,
1128 ui::DomKey::CONTROL
,
1131 // Press Control+Alt+Search. Confirm the event is now VKEY_CONTROL.
1132 {ui::ET_KEY_PRESSED
,
1134 ui::DomCode::OS_LEFT
,
1135 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
1139 ui::DomCode::CONTROL_LEFT
,
1140 ui::EF_CONTROL_DOWN
,
1141 ui::DomKey::CONTROL
,
1144 // Press Shift+Control+Alt+Search. Confirm the event is now Control with
1145 // Shift and Control modifiers.
1146 {ui::ET_KEY_PRESSED
,
1148 ui::DomCode::OS_LEFT
,
1149 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
1150 ui::EF_COMMAND_DOWN
,
1154 ui::DomCode::CONTROL_LEFT
,
1155 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
1156 ui::DomKey::CONTROL
,
1159 // Press Shift+Control+Alt+Search+B. Confirm the event is now B with Shift
1160 // and Control modifiers.
1161 {ui::ET_KEY_PRESSED
,
1164 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
1165 ui::EF_COMMAND_DOWN
,
1166 ui::DomKey::CHARACTER
,
1170 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
1171 ui::DomKey::CHARACTER
,
1175 for (const auto& test
: sa_tests
) {
1176 CheckKeyTestCase(&rewriter
, test
);
1180 TEST_F(EventRewriterTest
, TestRewriteModifiersRemapToEscape
) {
1181 // Remap Search to ESC.
1182 TestingPrefServiceSyncable prefs
;
1183 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1184 IntegerPrefMember search
;
1185 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
1186 search
.SetValue(chromeos::input_method::kEscapeKey
);
1188 EventRewriter
rewriter(NULL
);
1189 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1190 rewriter
.set_pref_service_for_testing(&prefs
);
1192 KeyTestCase tests
[] = {
1193 // Press Search. Confirm the event is now VKEY_ESCAPE.
1194 {ui::ET_KEY_PRESSED
,
1196 ui::DomCode::OS_LEFT
,
1197 ui::EF_COMMAND_DOWN
,
1201 ui::DomCode::ESCAPE
,
1207 for (const auto& test
: tests
) {
1208 CheckKeyTestCase(&rewriter
, test
);
1212 TEST_F(EventRewriterTest
, TestRewriteModifiersRemapMany
) {
1213 // Remap Search to Alt.
1214 TestingPrefServiceSyncable prefs
;
1215 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1216 IntegerPrefMember search
;
1217 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
1218 search
.SetValue(chromeos::input_method::kAltKey
);
1220 EventRewriter
rewriter(NULL
);
1221 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1222 rewriter
.set_pref_service_for_testing(&prefs
);
1224 KeyTestCase s2a_tests
[] = {
1225 // Press Search. Confirm the event is now VKEY_MENU.
1226 {ui::ET_KEY_PRESSED
,
1228 ui::DomCode::OS_LEFT
,
1229 ui::EF_COMMAND_DOWN
,
1233 ui::DomCode::ALT_LEFT
,
1239 for (const auto& test
: s2a_tests
) {
1240 CheckKeyTestCase(&rewriter
, test
);
1243 // Remap Alt to Control.
1244 IntegerPrefMember alt
;
1245 alt
.Init(prefs::kLanguageRemapAltKeyTo
, &prefs
);
1246 alt
.SetValue(chromeos::input_method::kControlKey
);
1248 KeyTestCase a2c_tests
[] = {
1249 // Press left Alt. Confirm the event is now VKEY_CONTROL.
1250 {ui::ET_KEY_PRESSED
,
1252 ui::DomCode::ALT_LEFT
,
1257 ui::DomCode::CONTROL_LEFT
,
1258 ui::EF_CONTROL_DOWN
,
1259 ui::DomKey::CONTROL
,
1261 // Press Shift+comma. Verify that only the flags are changed.
1262 // The X11 portion of the test addresses crbug.com/390263 by verifying
1263 // that the X keycode remains that for ',<' and not for 105-key '<>'.
1264 {ui::ET_KEY_PRESSED
,
1265 {ui::VKEY_OEM_COMMA
,
1267 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
,
1268 ui::DomKey::UNIDENTIFIED
,
1270 {ui::VKEY_OEM_COMMA
,
1272 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
1273 ui::DomKey::UNIDENTIFIED
,
1275 // Press Shift+9. Verify that only the flags are changed.
1276 {ui::ET_KEY_PRESSED
,
1278 ui::DomCode::DIGIT9
,
1279 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
,
1280 ui::DomKey::UNIDENTIFIED
,
1283 ui::DomCode::DIGIT9
,
1284 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
1285 ui::DomKey::UNIDENTIFIED
,
1289 for (const auto& test
: a2c_tests
) {
1290 CheckKeyTestCase(&rewriter
, test
);
1293 // Remap Control to Search.
1294 IntegerPrefMember control
;
1295 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
1296 control
.SetValue(chromeos::input_method::kSearchKey
);
1298 KeyTestCase c2s_tests
[] = {
1299 // Press left Control. Confirm the event is now VKEY_LWIN.
1300 {ui::ET_KEY_PRESSED
,
1302 ui::DomCode::CONTROL_LEFT
,
1303 ui::EF_CONTROL_DOWN
,
1304 ui::DomKey::CONTROL
,
1307 ui::DomCode::OS_LEFT
,
1308 ui::EF_COMMAND_DOWN
,
1312 // Then, press all of the three, Control+Alt+Search.
1313 {ui::ET_KEY_PRESSED
,
1315 ui::DomCode::OS_LEFT
,
1316 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
1320 ui::DomCode::ALT_LEFT
,
1321 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
1325 // Press Shift+Control+Alt+Search.
1326 {ui::ET_KEY_PRESSED
,
1328 ui::DomCode::OS_LEFT
,
1329 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
1330 ui::EF_COMMAND_DOWN
,
1334 ui::DomCode::ALT_LEFT
,
1335 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
1336 ui::EF_COMMAND_DOWN
,
1340 // Press Shift+Control+Alt+Search+B
1341 {ui::ET_KEY_PRESSED
,
1344 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
1345 ui::EF_COMMAND_DOWN
,
1346 ui::DomKey::CHARACTER
,
1350 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
1351 ui::EF_COMMAND_DOWN
,
1352 ui::DomKey::CHARACTER
,
1356 for (const auto& test
: c2s_tests
) {
1357 CheckKeyTestCase(&rewriter
, test
);
1361 TEST_F(EventRewriterTest
, TestRewriteModifiersRemapToCapsLock
) {
1362 // Remap Search to Caps Lock.
1363 TestingPrefServiceSyncable prefs
;
1364 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1365 IntegerPrefMember search
;
1366 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
1367 search
.SetValue(chromeos::input_method::kCapsLockKey
);
1369 chromeos::input_method::FakeImeKeyboard ime_keyboard
;
1370 EventRewriter
rewriter(NULL
);
1371 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1372 rewriter
.set_pref_service_for_testing(&prefs
);
1373 rewriter
.set_ime_keyboard_for_testing(&ime_keyboard
);
1374 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
1377 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_CAPITAL
,
1378 ui::DomCode::CAPS_LOCK
, ui::EF_MOD3_DOWN
,
1379 ui::DomKey::CAPS_LOCK
, 0),
1380 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
,
1381 ui::VKEY_LWIN
, ui::DomCode::OS_LEFT
,
1382 ui::EF_COMMAND_DOWN
, ui::DomKey::OS
, 0));
1383 // Confirm that the Caps Lock status is changed.
1384 EXPECT_TRUE(ime_keyboard
.caps_lock_is_enabled_
);
1387 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_RELEASED
, ui::VKEY_CAPITAL
,
1388 ui::DomCode::CAPS_LOCK
, ui::EF_NONE
,
1389 ui::DomKey::CAPS_LOCK
, 0),
1390 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_RELEASED
,
1391 ui::VKEY_LWIN
, ui::DomCode::OS_LEFT
,
1392 ui::EF_NONE
, ui::DomKey::OS
, 0));
1393 // Confirm that the Caps Lock status is not changed.
1394 EXPECT_TRUE(ime_keyboard
.caps_lock_is_enabled_
);
1398 GetExpectedResultAsString(
1399 ui::ET_KEY_PRESSED
, ui::VKEY_CAPITAL
, ui::DomCode::CAPS_LOCK
,
1400 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
, ui::DomKey::CAPS_LOCK
, 0),
1401 GetRewrittenEventAsString(
1402 &rewriter
, ui::ET_KEY_PRESSED
, ui::VKEY_LWIN
, ui::DomCode::OS_LEFT
,
1403 ui::EF_COMMAND_DOWN
| ui::EF_CAPS_LOCK_DOWN
, ui::DomKey::OS
, 0));
1404 // Confirm that the Caps Lock status is changed.
1405 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
1408 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_RELEASED
, ui::VKEY_CAPITAL
,
1409 ui::DomCode::CAPS_LOCK
, ui::EF_NONE
,
1410 ui::DomKey::CAPS_LOCK
, 0),
1411 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_RELEASED
,
1412 ui::VKEY_LWIN
, ui::DomCode::OS_LEFT
,
1413 ui::EF_NONE
, ui::DomKey::OS
, 0));
1414 // Confirm that the Caps Lock status is not changed.
1415 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
1417 // Press Caps Lock (on an external keyboard).
1418 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_CAPITAL
,
1419 ui::DomCode::CAPS_LOCK
,
1420 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
1421 ui::DomKey::CAPS_LOCK
, 0),
1422 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
,
1423 ui::VKEY_CAPITAL
, ui::DomCode::CAPS_LOCK
,
1424 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
1425 ui::DomKey::CAPS_LOCK
, 0));
1427 #if defined(USE_X11)
1428 // Confirm that calling RewriteForTesting() does not change the state of
1429 // |ime_keyboard|. In this case, X Window system itself should change the
1430 // Caps Lock state, not ash::EventRewriter.
1431 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
1432 #elif defined(USE_OZONE)
1433 // Under Ozone the rewriter is responsible for changing the caps lock
1434 // state when the final key is Caps Lock, regardless of whether the
1435 // initial key is Caps Lock.
1436 EXPECT_TRUE(ime_keyboard
.caps_lock_is_enabled_
);
1439 // Release Caps Lock (on an external keyboard).
1440 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_RELEASED
, ui::VKEY_CAPITAL
,
1441 ui::DomCode::CAPS_LOCK
, ui::EF_NONE
,
1442 ui::DomKey::CAPS_LOCK
, 0),
1443 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_RELEASED
,
1444 ui::VKEY_CAPITAL
, ui::DomCode::CAPS_LOCK
,
1445 ui::EF_NONE
, ui::DomKey::CAPS_LOCK
, 0));
1446 #if defined(USE_X11)
1447 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
1448 #elif defined(USE_OZONE)
1449 EXPECT_TRUE(ime_keyboard
.caps_lock_is_enabled_
);
1453 TEST_F(EventRewriterTest
, TestRewriteCapsLock
) {
1454 TestingPrefServiceSyncable prefs
;
1455 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1457 chromeos::input_method::FakeImeKeyboard ime_keyboard
;
1458 EventRewriter
rewriter(NULL
);
1459 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1460 rewriter
.set_pref_service_for_testing(&prefs
);
1461 rewriter
.set_ime_keyboard_for_testing(&ime_keyboard
);
1462 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
1464 // On Chrome OS, CapsLock is mapped to F16 with Mod3Mask.
1465 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_CAPITAL
,
1466 ui::DomCode::CAPS_LOCK
,
1467 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
1468 ui::DomKey::CAPS_LOCK
, 0),
1469 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
,
1470 ui::VKEY_F16
, ui::DomCode::F16
,
1471 ui::EF_MOD3_DOWN
, ui::DomKey::F16
, 0));
1472 EXPECT_TRUE(ime_keyboard
.caps_lock_is_enabled_
);
1475 TEST_F(EventRewriterTest
, TestRewriteDiamondKey
) {
1476 TestingPrefServiceSyncable prefs
;
1477 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1479 chromeos::input_method::FakeImeKeyboard ime_keyboard
;
1480 EventRewriter
rewriter(NULL
);
1481 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1482 rewriter
.set_pref_service_for_testing(&prefs
);
1483 rewriter
.set_ime_keyboard_for_testing(&ime_keyboard
);
1485 KeyTestCase tests
[] = {
1486 // F15 should work as Ctrl when --has-chromeos-diamond-key is not
1488 {ui::ET_KEY_PRESSED
,
1489 {ui::VKEY_F15
, ui::DomCode::F15
, ui::EF_NONE
, ui::DomKey::F15
, 0},
1491 ui::DomCode::CONTROL_LEFT
,
1492 ui::EF_CONTROL_DOWN
,
1493 ui::DomKey::CONTROL
,
1496 {ui::ET_KEY_RELEASED
,
1497 {ui::VKEY_F15
, ui::DomCode::F15
, ui::EF_NONE
, ui::DomKey::F15
, 0},
1499 ui::DomCode::CONTROL_LEFT
,
1501 ui::DomKey::CONTROL
,
1504 // However, Mod2Mask should not be rewritten to CtrlMask when
1505 // --has-chromeos-diamond-key is not specified.
1506 {ui::ET_KEY_PRESSED
,
1510 ui::DomKey::CHARACTER
,
1515 ui::DomKey::CHARACTER
,
1519 for (const auto& test
: tests
) {
1520 CheckKeyTestCase(&rewriter
, test
);
1524 TEST_F(EventRewriterTest
, TestRewriteDiamondKeyWithFlag
) {
1525 const base::CommandLine
original_cl(*base::CommandLine::ForCurrentProcess());
1526 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1527 chromeos::switches::kHasChromeOSDiamondKey
, "");
1529 TestingPrefServiceSyncable prefs
;
1530 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1532 chromeos::input_method::FakeImeKeyboard ime_keyboard
;
1533 EventRewriter
rewriter(NULL
);
1534 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1535 rewriter
.set_pref_service_for_testing(&prefs
);
1536 rewriter
.set_ime_keyboard_for_testing(&ime_keyboard
);
1538 // By default, F15 should work as Control.
1539 EXPECT_EQ(GetExpectedResultAsString(
1540 ui::ET_KEY_PRESSED
, ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
1541 ui::EF_CONTROL_DOWN
, ui::DomKey::CONTROL
, 0),
1542 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
,
1543 ui::VKEY_F15
, ui::DomCode::F15
,
1544 ui::EF_NONE
, ui::DomKey::F15
, 0));
1545 // Check that Control is applied to a subsequent key press.
1546 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1547 ui::DomCode::KEY_A
, ui::EF_CONTROL_DOWN
,
1548 ui::DomKey::CHARACTER
, 0x01),
1549 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1550 ui::DomCode::KEY_A
, ui::EF_NONE
,
1551 ui::DomKey::CHARACTER
, 'a'));
1553 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_RELEASED
, ui::VKEY_CONTROL
,
1554 ui::DomCode::CONTROL_LEFT
, ui::EF_NONE
,
1555 ui::DomKey::CONTROL
, 0),
1556 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_RELEASED
,
1557 ui::VKEY_F15
, ui::DomCode::F15
,
1558 ui::EF_NONE
, ui::DomKey::F15
, 0));
1559 // Check that Control is no longer applied to a subsequent key press.
1560 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1561 ui::DomCode::KEY_A
, ui::EF_NONE
,
1562 ui::DomKey::CHARACTER
, 'a'),
1563 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1564 ui::DomCode::KEY_A
, ui::EF_NONE
,
1565 ui::DomKey::CHARACTER
, 'a'));
1567 IntegerPrefMember diamond
;
1568 diamond
.Init(prefs::kLanguageRemapDiamondKeyTo
, &prefs
);
1569 diamond
.SetValue(chromeos::input_method::kVoidKey
);
1571 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_UNKNOWN
,
1572 ui::DomCode::NONE
, ui::EF_NONE
,
1573 ui::DomKey::UNIDENTIFIED
, 0),
1574 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
,
1575 ui::VKEY_F15
, ui::DomCode::F15
,
1576 ui::EF_NONE
, ui::DomKey::F15
, 0));
1577 // Check that no modifier is applied to another key.
1578 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1579 ui::DomCode::KEY_A
, ui::EF_NONE
,
1580 ui::DomKey::CHARACTER
, 'a'),
1581 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1582 ui::DomCode::KEY_A
, ui::EF_NONE
,
1583 ui::DomKey::CHARACTER
, 'a'));
1585 diamond
.SetValue(chromeos::input_method::kControlKey
);
1587 EXPECT_EQ(GetExpectedResultAsString(
1588 ui::ET_KEY_PRESSED
, ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
1589 ui::EF_CONTROL_DOWN
, ui::DomKey::CONTROL
, 0),
1590 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
,
1591 ui::VKEY_F15
, ui::DomCode::F15
,
1592 ui::EF_NONE
, ui::DomKey::F15
, 0));
1593 // Check that Control is applied to a subsequent key press.
1594 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1595 ui::DomCode::KEY_A
, ui::EF_CONTROL_DOWN
,
1596 ui::DomKey::CHARACTER
, 0x01),
1597 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1598 ui::DomCode::KEY_A
, ui::EF_NONE
,
1599 ui::DomKey::CHARACTER
, 'a'));
1601 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_RELEASED
, ui::VKEY_CONTROL
,
1602 ui::DomCode::CONTROL_LEFT
, ui::EF_NONE
,
1603 ui::DomKey::CONTROL
, 0),
1604 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_RELEASED
,
1605 ui::VKEY_F15
, ui::DomCode::F15
,
1606 ui::EF_NONE
, ui::DomKey::F15
, 0));
1607 // Check that Control is no longer applied to a subsequent key press.
1608 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1609 ui::DomCode::KEY_A
, ui::EF_NONE
,
1610 ui::DomKey::CHARACTER
, 'a'),
1611 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1612 ui::DomCode::KEY_A
, ui::EF_NONE
,
1613 ui::DomKey::CHARACTER
, 'a'));
1615 diamond
.SetValue(chromeos::input_method::kAltKey
);
1617 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_MENU
,
1618 ui::DomCode::ALT_LEFT
, ui::EF_ALT_DOWN
,
1619 ui::DomKey::ALT
, 0),
1620 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
,
1621 ui::VKEY_F15
, ui::DomCode::F15
,
1622 ui::EF_NONE
, ui::DomKey::F15
, 0));
1623 // Check that Alt is applied to a subsequent key press.
1624 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1625 ui::DomCode::KEY_A
, ui::EF_ALT_DOWN
,
1626 ui::DomKey::CHARACTER
, 'a'),
1627 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1628 ui::DomCode::KEY_A
, ui::EF_NONE
,
1629 ui::DomKey::CHARACTER
, 'a'));
1631 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_RELEASED
, ui::VKEY_MENU
,
1632 ui::DomCode::ALT_LEFT
, ui::EF_NONE
,
1633 ui::DomKey::ALT
, 0),
1634 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_RELEASED
,
1635 ui::VKEY_F15
, ui::DomCode::F15
,
1636 ui::EF_NONE
, ui::DomKey::F15
, 0));
1637 // Check that Alt is no longer applied to a subsequent key press.
1638 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1639 ui::DomCode::KEY_A
, ui::EF_NONE
,
1640 ui::DomKey::CHARACTER
, 'a'),
1641 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1642 ui::DomCode::KEY_A
, ui::EF_NONE
,
1643 ui::DomKey::CHARACTER
, 'a'));
1645 diamond
.SetValue(chromeos::input_method::kCapsLockKey
);
1647 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_CAPITAL
,
1648 ui::DomCode::CAPS_LOCK
,
1649 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
1650 ui::DomKey::CAPS_LOCK
, 0),
1651 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
,
1652 ui::VKEY_F15
, ui::DomCode::F15
,
1653 ui::EF_NONE
, ui::DomKey::F15
, 0));
1654 // Check that Caps is applied to a subsequent key press.
1655 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1657 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
1658 ui::DomKey::CHARACTER
, 'A'),
1659 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1660 ui::DomCode::KEY_A
, ui::EF_NONE
,
1661 ui::DomKey::CHARACTER
, 'a'));
1663 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_RELEASED
, ui::VKEY_CAPITAL
,
1664 ui::DomCode::CAPS_LOCK
, ui::EF_NONE
,
1665 ui::DomKey::CAPS_LOCK
, 0),
1666 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_RELEASED
,
1667 ui::VKEY_F15
, ui::DomCode::F15
,
1668 ui::EF_NONE
, ui::DomKey::F15
, 0));
1669 // Check that Control is no longer applied to a subsequent key press.
1670 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1671 ui::DomCode::KEY_A
, ui::EF_NONE
,
1672 ui::DomKey::CHARACTER
, 'a'),
1673 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1674 ui::DomCode::KEY_A
, ui::EF_NONE
,
1675 ui::DomKey::CHARACTER
, 'a'));
1677 *base::CommandLine::ForCurrentProcess() = original_cl
;
1680 TEST_F(EventRewriterTest
, TestRewriteCapsLockToControl
) {
1681 // Remap CapsLock to Control.
1682 TestingPrefServiceSyncable prefs
;
1683 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1684 IntegerPrefMember control
;
1685 control
.Init(prefs::kLanguageRemapCapsLockKeyTo
, &prefs
);
1686 control
.SetValue(chromeos::input_method::kControlKey
);
1688 EventRewriter
rewriter(NULL
);
1689 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1690 rewriter
.set_pref_service_for_testing(&prefs
);
1692 KeyTestCase tests
[] = {
1693 // Press CapsLock+a. Confirm that Mod3Mask is rewritten to ControlMask.
1694 // On Chrome OS, CapsLock works as a Mod3 modifier.
1695 {ui::ET_KEY_PRESSED
,
1699 ui::DomKey::CHARACTER
,
1703 ui::EF_CONTROL_DOWN
,
1704 ui::DomKey::CHARACTER
,
1707 // Press Control+CapsLock+a. Confirm that Mod3Mask is rewritten to
1709 {ui::ET_KEY_PRESSED
,
1712 ui::EF_CONTROL_DOWN
| ui::EF_MOD3_DOWN
,
1713 ui::DomKey::CHARACTER
,
1717 ui::EF_CONTROL_DOWN
,
1718 ui::DomKey::CHARACTER
,
1721 // Press Alt+CapsLock+a. Confirm that Mod3Mask is rewritten to
1723 {ui::ET_KEY_PRESSED
,
1726 ui::EF_ALT_DOWN
| ui::EF_MOD3_DOWN
,
1727 ui::DomKey::CHARACTER
,
1731 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
1732 ui::DomKey::CHARACTER
,
1736 for (const auto& test
: tests
) {
1737 CheckKeyTestCase(&rewriter
, test
);
1741 TEST_F(EventRewriterTest
, TestRewriteCapsLockMod3InUse
) {
1742 // Remap CapsLock to Control.
1743 TestingPrefServiceSyncable prefs
;
1744 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1745 IntegerPrefMember control
;
1746 control
.Init(prefs::kLanguageRemapCapsLockKeyTo
, &prefs
);
1747 control
.SetValue(chromeos::input_method::kControlKey
);
1749 EventRewriter
rewriter(NULL
);
1750 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1751 rewriter
.set_pref_service_for_testing(&prefs
);
1752 input_method_manager_mock_
->set_mod3_used(true);
1754 // Press CapsLock+a. Confirm that Mod3Mask is NOT rewritten to ControlMask
1755 // when Mod3Mask is already in use by the current XKB layout.
1756 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1757 ui::DomCode::KEY_A
, ui::EF_NONE
,
1758 ui::DomKey::CHARACTER
, 'a'),
1759 GetRewrittenEventAsString(&rewriter
, ui::ET_KEY_PRESSED
, ui::VKEY_A
,
1760 ui::DomCode::KEY_A
, ui::EF_NONE
,
1761 ui::DomKey::CHARACTER
, 'a'));
1763 input_method_manager_mock_
->set_mod3_used(false);
1766 TEST_F(EventRewriterTest
, TestRewriteExtendedKeys
) {
1767 TestingPrefServiceSyncable prefs
;
1768 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1769 EventRewriter
rewriter(NULL
);
1770 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1771 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
1772 rewriter
.set_pref_service_for_testing(&prefs
);
1774 KeyTestCase tests
[] = {
1775 // Alt+Backspace -> Delete
1776 {ui::ET_KEY_PRESSED
,
1778 ui::DomCode::BACKSPACE
,
1780 ui::DomKey::BACKSPACE
,
1782 {ui::VKEY_DELETE
, ui::DomCode::DEL
, ui::EF_NONE
, ui::DomKey::DEL
, 0x7F}},
1783 // Control+Alt+Backspace -> Control+Delete
1784 {ui::ET_KEY_PRESSED
,
1786 ui::DomCode::BACKSPACE
,
1787 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
1788 ui::DomKey::BACKSPACE
,
1792 ui::EF_CONTROL_DOWN
,
1795 // Search+Alt+Backspace -> Alt+Backspace
1796 {ui::ET_KEY_PRESSED
,
1798 ui::DomCode::BACKSPACE
,
1799 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
,
1800 ui::DomKey::BACKSPACE
,
1803 ui::DomCode::BACKSPACE
,
1805 ui::DomKey::BACKSPACE
,
1807 // Search+Control+Alt+Backspace -> Control+Alt+Backspace
1808 {ui::ET_KEY_PRESSED
,
1810 ui::DomCode::BACKSPACE
,
1811 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
1812 ui::DomKey::BACKSPACE
,
1815 ui::DomCode::BACKSPACE
,
1816 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
1817 ui::DomKey::BACKSPACE
,
1820 {ui::ET_KEY_PRESSED
,
1822 ui::DomCode::ARROW_UP
,
1824 ui::DomKey::ARROW_UP
,
1827 ui::DomCode::PAGE_UP
,
1829 ui::DomKey::PAGE_UP
,
1832 {ui::ET_KEY_PRESSED
,
1834 ui::DomCode::ARROW_DOWN
,
1836 ui::DomKey::ARROW_DOWN
,
1839 ui::DomCode::PAGE_DOWN
,
1841 ui::DomKey::PAGE_DOWN
,
1843 // Ctrl+Alt+Up -> Home
1844 {ui::ET_KEY_PRESSED
,
1846 ui::DomCode::ARROW_UP
,
1847 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
1848 ui::DomKey::ARROW_UP
,
1850 {ui::VKEY_HOME
, ui::DomCode::HOME
, ui::EF_NONE
, ui::DomKey::HOME
, 0}},
1851 // Ctrl+Alt+Down -> End
1852 {ui::ET_KEY_PRESSED
,
1854 ui::DomCode::ARROW_DOWN
,
1855 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
1856 ui::DomKey::ARROW_DOWN
,
1858 {ui::VKEY_END
, ui::DomCode::END
, ui::EF_NONE
, ui::DomKey::END
, 0}},
1860 // Search+Alt+Up -> Alt+Up
1861 {ui::ET_KEY_PRESSED
,
1863 ui::DomCode::ARROW_UP
,
1864 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
,
1865 ui::DomKey::ARROW_UP
,
1868 ui::DomCode::ARROW_UP
,
1870 ui::DomKey::ARROW_UP
,
1872 // Search+Alt+Down -> Alt+Down
1873 {ui::ET_KEY_PRESSED
,
1875 ui::DomCode::ARROW_DOWN
,
1876 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
,
1877 ui::DomKey::ARROW_DOWN
,
1880 ui::DomCode::ARROW_DOWN
,
1882 ui::DomKey::ARROW_DOWN
,
1884 // Search+Ctrl+Alt+Up -> Search+Ctrl+Alt+Up
1885 {ui::ET_KEY_PRESSED
,
1887 ui::DomCode::ARROW_UP
,
1888 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
1889 ui::DomKey::ARROW_UP
,
1892 ui::DomCode::ARROW_UP
,
1893 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
1894 ui::DomKey::ARROW_UP
,
1896 // Search+Ctrl+Alt+Down -> Ctrl+Alt+Down
1897 {ui::ET_KEY_PRESSED
,
1899 ui::DomCode::ARROW_DOWN
,
1900 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
1901 ui::DomKey::ARROW_DOWN
,
1904 ui::DomCode::ARROW_DOWN
,
1905 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
1906 ui::DomKey::ARROW_DOWN
,
1910 {ui::ET_KEY_PRESSED
,
1911 {ui::VKEY_OEM_PERIOD
,
1912 ui::DomCode::PERIOD
,
1914 ui::DomKey::CHARACTER
,
1916 {ui::VKEY_OEM_PERIOD
,
1917 ui::DomCode::PERIOD
,
1919 ui::DomKey::CHARACTER
,
1922 // Search+Backspace -> Delete
1923 {ui::ET_KEY_PRESSED
,
1925 ui::DomCode::BACKSPACE
,
1926 ui::EF_COMMAND_DOWN
,
1927 ui::DomKey::BACKSPACE
,
1929 {ui::VKEY_DELETE
, ui::DomCode::DEL
, ui::EF_NONE
, ui::DomKey::DEL
, 0x7F}},
1930 // Search+Up -> Prior
1931 {ui::ET_KEY_PRESSED
,
1933 ui::DomCode::ARROW_UP
,
1934 ui::EF_COMMAND_DOWN
,
1935 ui::DomKey::ARROW_UP
,
1938 ui::DomCode::PAGE_UP
,
1940 ui::DomKey::PAGE_UP
,
1942 // Search+Down -> Next
1943 {ui::ET_KEY_PRESSED
,
1945 ui::DomCode::ARROW_DOWN
,
1946 ui::EF_COMMAND_DOWN
,
1947 ui::DomKey::ARROW_DOWN
,
1950 ui::DomCode::PAGE_DOWN
,
1952 ui::DomKey::PAGE_DOWN
,
1954 // Search+Left -> Home
1955 {ui::ET_KEY_PRESSED
,
1957 ui::DomCode::ARROW_LEFT
,
1958 ui::EF_COMMAND_DOWN
,
1959 ui::DomKey::ARROW_LEFT
,
1961 {ui::VKEY_HOME
, ui::DomCode::HOME
, ui::EF_NONE
, ui::DomKey::HOME
, 0}},
1962 // Control+Search+Left -> Home
1963 {ui::ET_KEY_PRESSED
,
1965 ui::DomCode::ARROW_LEFT
,
1966 ui::EF_COMMAND_DOWN
| ui::EF_CONTROL_DOWN
,
1967 ui::DomKey::ARROW_LEFT
,
1971 ui::EF_CONTROL_DOWN
,
1974 // Search+Right -> End
1975 {ui::ET_KEY_PRESSED
,
1977 ui::DomCode::ARROW_RIGHT
,
1978 ui::EF_COMMAND_DOWN
,
1979 ui::DomKey::ARROW_RIGHT
,
1981 {ui::VKEY_END
, ui::DomCode::END
, ui::EF_NONE
, ui::DomKey::END
, 0}},
1982 // Control+Search+Right -> End
1983 {ui::ET_KEY_PRESSED
,
1985 ui::DomCode::ARROW_RIGHT
,
1986 ui::EF_COMMAND_DOWN
| ui::EF_CONTROL_DOWN
,
1987 ui::DomKey::ARROW_RIGHT
,
1991 ui::EF_CONTROL_DOWN
,
1994 // Search+Period -> Insert
1995 {ui::ET_KEY_PRESSED
,
1996 {ui::VKEY_OEM_PERIOD
,
1997 ui::DomCode::PERIOD
,
1998 ui::EF_COMMAND_DOWN
,
1999 ui::DomKey::CHARACTER
,
2002 ui::DomCode::INSERT
,
2006 // Control+Search+Period -> Control+Insert
2007 {ui::ET_KEY_PRESSED
,
2008 {ui::VKEY_OEM_PERIOD
,
2009 ui::DomCode::PERIOD
,
2010 ui::EF_COMMAND_DOWN
| ui::EF_CONTROL_DOWN
,
2011 ui::DomKey::CHARACTER
,
2014 ui::DomCode::INSERT
,
2015 ui::EF_CONTROL_DOWN
,
2019 for (const auto& test
: tests
) {
2020 CheckKeyTestCase(&rewriter
, test
);
2024 TEST_F(EventRewriterTest
, TestRewriteFunctionKeys
) {
2025 TestingPrefServiceSyncable prefs
;
2026 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
2027 EventRewriter
rewriter(NULL
);
2028 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
2029 rewriter
.set_pref_service_for_testing(&prefs
);
2031 KeyTestCase tests
[] = {
2033 {ui::ET_KEY_PRESSED
,
2034 {ui::VKEY_F1
, ui::DomCode::F1
, ui::EF_NONE
, ui::DomKey::F1
, 0},
2035 {ui::VKEY_BROWSER_BACK
,
2036 ui::DomCode::BROWSER_BACK
,
2038 ui::DomKey::BROWSER_BACK
,
2040 {ui::ET_KEY_PRESSED
,
2041 {ui::VKEY_F1
, ui::DomCode::F1
, ui::EF_CONTROL_DOWN
, ui::DomKey::F1
, 0},
2042 {ui::VKEY_BROWSER_BACK
,
2043 ui::DomCode::BROWSER_BACK
,
2044 ui::EF_CONTROL_DOWN
,
2045 ui::DomKey::BROWSER_BACK
,
2047 {ui::ET_KEY_PRESSED
,
2048 {ui::VKEY_F1
, ui::DomCode::F1
, ui::EF_ALT_DOWN
, ui::DomKey::F1
, 0},
2049 {ui::VKEY_BROWSER_BACK
,
2050 ui::DomCode::BROWSER_BACK
,
2052 ui::DomKey::BROWSER_BACK
,
2055 {ui::ET_KEY_PRESSED
,
2056 {ui::VKEY_F2
, ui::DomCode::F2
, ui::EF_NONE
, ui::DomKey::F2
, 0},
2057 {ui::VKEY_BROWSER_FORWARD
,
2058 ui::DomCode::BROWSER_FORWARD
,
2060 ui::DomKey::BROWSER_FORWARD
,
2062 {ui::ET_KEY_PRESSED
,
2063 {ui::VKEY_F2
, ui::DomCode::F2
, ui::EF_CONTROL_DOWN
, ui::DomKey::F2
, 0},
2064 {ui::VKEY_BROWSER_FORWARD
,
2065 ui::DomCode::BROWSER_FORWARD
,
2066 ui::EF_CONTROL_DOWN
,
2067 ui::DomKey::BROWSER_FORWARD
,
2069 {ui::ET_KEY_PRESSED
,
2070 {ui::VKEY_F2
, ui::DomCode::F2
, ui::EF_ALT_DOWN
, ui::DomKey::F2
, 0},
2071 {ui::VKEY_BROWSER_FORWARD
,
2072 ui::DomCode::BROWSER_FORWARD
,
2074 ui::DomKey::BROWSER_FORWARD
,
2077 {ui::ET_KEY_PRESSED
,
2078 {ui::VKEY_F3
, ui::DomCode::F3
, ui::EF_NONE
, ui::DomKey::F3
, 0},
2079 {ui::VKEY_BROWSER_REFRESH
,
2080 ui::DomCode::BROWSER_REFRESH
,
2082 ui::DomKey::BROWSER_REFRESH
,
2084 {ui::ET_KEY_PRESSED
,
2085 {ui::VKEY_F3
, ui::DomCode::F3
, ui::EF_CONTROL_DOWN
, ui::DomKey::F3
, 0},
2086 {ui::VKEY_BROWSER_REFRESH
,
2087 ui::DomCode::BROWSER_REFRESH
,
2088 ui::EF_CONTROL_DOWN
,
2089 ui::DomKey::BROWSER_REFRESH
,
2091 {ui::ET_KEY_PRESSED
,
2092 {ui::VKEY_F3
, ui::DomCode::F3
, ui::EF_ALT_DOWN
, ui::DomKey::F3
, 0},
2093 {ui::VKEY_BROWSER_REFRESH
,
2094 ui::DomCode::BROWSER_REFRESH
,
2096 ui::DomKey::BROWSER_REFRESH
,
2098 // F4 -> Launch App 2
2099 {ui::ET_KEY_PRESSED
,
2100 {ui::VKEY_F4
, ui::DomCode::F4
, ui::EF_NONE
, ui::DomKey::F4
, 0},
2101 {ui::VKEY_MEDIA_LAUNCH_APP2
,
2102 ui::DomCode::ZOOM_TOGGLE
,
2104 ui::DomKey::ZOOM_TOGGLE
,
2106 {ui::ET_KEY_PRESSED
,
2107 {ui::VKEY_F4
, ui::DomCode::F4
, ui::EF_CONTROL_DOWN
, ui::DomKey::F4
, 0},
2108 {ui::VKEY_MEDIA_LAUNCH_APP2
,
2109 ui::DomCode::ZOOM_TOGGLE
,
2110 ui::EF_CONTROL_DOWN
,
2111 ui::DomKey::ZOOM_TOGGLE
,
2113 {ui::ET_KEY_PRESSED
,
2114 {ui::VKEY_F4
, ui::DomCode::F4
, ui::EF_ALT_DOWN
, ui::DomKey::F4
, 0},
2115 {ui::VKEY_MEDIA_LAUNCH_APP2
,
2116 ui::DomCode::ZOOM_TOGGLE
,
2118 ui::DomKey::ZOOM_TOGGLE
,
2120 // F5 -> Launch App 1
2121 {ui::ET_KEY_PRESSED
,
2122 {ui::VKEY_F5
, ui::DomCode::F5
, ui::EF_NONE
, ui::DomKey::F5
, 0},
2123 {ui::VKEY_MEDIA_LAUNCH_APP1
,
2124 ui::DomCode::SELECT_TASK
,
2126 ui::DomKey::LAUNCH_MY_COMPUTER
,
2128 {ui::ET_KEY_PRESSED
,
2129 {ui::VKEY_F5
, ui::DomCode::F5
, ui::EF_CONTROL_DOWN
, ui::DomKey::F5
, 0},
2130 {ui::VKEY_MEDIA_LAUNCH_APP1
,
2131 ui::DomCode::SELECT_TASK
,
2132 ui::EF_CONTROL_DOWN
,
2133 ui::DomKey::LAUNCH_MY_COMPUTER
,
2135 {ui::ET_KEY_PRESSED
,
2136 {ui::VKEY_F5
, ui::DomCode::F5
, ui::EF_ALT_DOWN
, ui::DomKey::F5
, 0},
2137 {ui::VKEY_MEDIA_LAUNCH_APP1
,
2138 ui::DomCode::SELECT_TASK
,
2140 ui::DomKey::LAUNCH_MY_COMPUTER
,
2142 // F6 -> Brightness down
2143 {ui::ET_KEY_PRESSED
,
2144 {ui::VKEY_F6
, ui::DomCode::F6
, ui::EF_NONE
, ui::DomKey::F6
, 0},
2145 {ui::VKEY_BRIGHTNESS_DOWN
,
2146 ui::DomCode::BRIGHTNESS_DOWN
,
2148 ui::DomKey::BRIGHTNESS_DOWN
,
2150 {ui::ET_KEY_PRESSED
,
2151 {ui::VKEY_F6
, ui::DomCode::F6
, ui::EF_CONTROL_DOWN
, ui::DomKey::F6
, 0},
2152 {ui::VKEY_BRIGHTNESS_DOWN
,
2153 ui::DomCode::BRIGHTNESS_DOWN
,
2154 ui::EF_CONTROL_DOWN
,
2155 ui::DomKey::BRIGHTNESS_DOWN
,
2157 {ui::ET_KEY_PRESSED
,
2158 {ui::VKEY_F6
, ui::DomCode::F6
, ui::EF_ALT_DOWN
, ui::DomKey::F6
, 0},
2159 {ui::VKEY_BRIGHTNESS_DOWN
,
2160 ui::DomCode::BRIGHTNESS_DOWN
,
2162 ui::DomKey::BRIGHTNESS_DOWN
,
2164 // F7 -> Brightness up
2165 {ui::ET_KEY_PRESSED
,
2166 {ui::VKEY_F7
, ui::DomCode::F7
, ui::EF_NONE
, ui::DomKey::F7
, 0},
2167 {ui::VKEY_BRIGHTNESS_UP
,
2168 ui::DomCode::BRIGHTNESS_UP
,
2170 ui::DomKey::BRIGHTNESS_UP
,
2172 {ui::ET_KEY_PRESSED
,
2173 {ui::VKEY_F7
, ui::DomCode::F7
, ui::EF_CONTROL_DOWN
, ui::DomKey::F7
, 0},
2174 {ui::VKEY_BRIGHTNESS_UP
,
2175 ui::DomCode::BRIGHTNESS_UP
,
2176 ui::EF_CONTROL_DOWN
,
2177 ui::DomKey::BRIGHTNESS_UP
,
2179 {ui::ET_KEY_PRESSED
,
2180 {ui::VKEY_F7
, ui::DomCode::F7
, ui::EF_ALT_DOWN
, ui::DomKey::F7
, 0},
2181 {ui::VKEY_BRIGHTNESS_UP
,
2182 ui::DomCode::BRIGHTNESS_UP
,
2184 ui::DomKey::BRIGHTNESS_UP
,
2186 // F8 -> Volume Mute
2187 {ui::ET_KEY_PRESSED
,
2188 {ui::VKEY_F8
, ui::DomCode::F8
, ui::EF_NONE
, ui::DomKey::F8
, 0},
2189 {ui::VKEY_VOLUME_MUTE
,
2190 ui::DomCode::VOLUME_MUTE
,
2192 ui::DomKey::VOLUME_MUTE
,
2194 {ui::ET_KEY_PRESSED
,
2195 {ui::VKEY_F8
, ui::DomCode::F8
, ui::EF_CONTROL_DOWN
, ui::DomKey::F8
, 0},
2196 {ui::VKEY_VOLUME_MUTE
,
2197 ui::DomCode::VOLUME_MUTE
,
2198 ui::EF_CONTROL_DOWN
,
2199 ui::DomKey::VOLUME_MUTE
,
2201 {ui::ET_KEY_PRESSED
,
2202 {ui::VKEY_F8
, ui::DomCode::F8
, ui::EF_ALT_DOWN
, ui::DomKey::F8
, 0},
2203 {ui::VKEY_VOLUME_MUTE
,
2204 ui::DomCode::VOLUME_MUTE
,
2206 ui::DomKey::VOLUME_MUTE
,
2208 // F9 -> Volume Down
2209 {ui::ET_KEY_PRESSED
,
2210 {ui::VKEY_F9
, ui::DomCode::F9
, ui::EF_NONE
, ui::DomKey::F9
, 0},
2211 {ui::VKEY_VOLUME_DOWN
,
2212 ui::DomCode::VOLUME_DOWN
,
2214 ui::DomKey::VOLUME_DOWN
,
2216 {ui::ET_KEY_PRESSED
,
2217 {ui::VKEY_F9
, ui::DomCode::F9
, ui::EF_CONTROL_DOWN
, ui::DomKey::F9
, 0},
2218 {ui::VKEY_VOLUME_DOWN
,
2219 ui::DomCode::VOLUME_DOWN
,
2220 ui::EF_CONTROL_DOWN
,
2221 ui::DomKey::VOLUME_DOWN
,
2223 {ui::ET_KEY_PRESSED
,
2224 {ui::VKEY_F9
, ui::DomCode::F9
, ui::EF_ALT_DOWN
, ui::DomKey::F9
, 0},
2225 {ui::VKEY_VOLUME_DOWN
,
2226 ui::DomCode::VOLUME_DOWN
,
2228 ui::DomKey::VOLUME_DOWN
,
2231 {ui::ET_KEY_PRESSED
,
2232 {ui::VKEY_F10
, ui::DomCode::F10
, ui::EF_NONE
, ui::DomKey::F10
, 0},
2233 {ui::VKEY_VOLUME_UP
,
2234 ui::DomCode::VOLUME_UP
,
2236 ui::DomKey::VOLUME_UP
,
2238 {ui::ET_KEY_PRESSED
,
2241 ui::EF_CONTROL_DOWN
,
2244 {ui::VKEY_VOLUME_UP
,
2245 ui::DomCode::VOLUME_UP
,
2246 ui::EF_CONTROL_DOWN
,
2247 ui::DomKey::VOLUME_UP
,
2249 {ui::ET_KEY_PRESSED
,
2250 {ui::VKEY_F10
, ui::DomCode::F10
, ui::EF_ALT_DOWN
, ui::DomKey::F10
, 0},
2251 {ui::VKEY_VOLUME_UP
,
2252 ui::DomCode::VOLUME_UP
,
2254 ui::DomKey::VOLUME_UP
,
2257 {ui::ET_KEY_PRESSED
,
2258 {ui::VKEY_F11
, ui::DomCode::F11
, ui::EF_NONE
, ui::DomKey::F11
, 0},
2259 {ui::VKEY_F11
, ui::DomCode::F11
, ui::EF_NONE
, ui::DomKey::F11
, 0}},
2260 {ui::ET_KEY_PRESSED
,
2263 ui::EF_CONTROL_DOWN
,
2268 ui::EF_CONTROL_DOWN
,
2271 {ui::ET_KEY_PRESSED
,
2272 {ui::VKEY_F11
, ui::DomCode::F11
, ui::EF_ALT_DOWN
, ui::DomKey::F11
, 0},
2273 {ui::VKEY_F11
, ui::DomCode::F11
, ui::EF_ALT_DOWN
, ui::DomKey::F11
, 0}},
2275 {ui::ET_KEY_PRESSED
,
2276 {ui::VKEY_F12
, ui::DomCode::F12
, ui::EF_NONE
, ui::DomKey::F12
, 0},
2277 {ui::VKEY_F12
, ui::DomCode::F12
, ui::EF_NONE
, ui::DomKey::F12
, 0}},
2278 {ui::ET_KEY_PRESSED
,
2281 ui::EF_CONTROL_DOWN
,
2286 ui::EF_CONTROL_DOWN
,
2289 {ui::ET_KEY_PRESSED
,
2290 {ui::VKEY_F12
, ui::DomCode::F12
, ui::EF_ALT_DOWN
, ui::DomKey::F12
, 0},
2291 {ui::VKEY_F12
, ui::DomCode::F12
, ui::EF_ALT_DOWN
, ui::DomKey::F12
, 0}},
2293 // The number row should not be rewritten without Search key.
2294 {ui::ET_KEY_PRESSED
,
2296 ui::DomCode::DIGIT1
,
2298 ui::DomKey::CHARACTER
,
2301 ui::DomCode::DIGIT1
,
2303 ui::DomKey::CHARACTER
,
2305 {ui::ET_KEY_PRESSED
,
2307 ui::DomCode::DIGIT2
,
2309 ui::DomKey::CHARACTER
,
2312 ui::DomCode::DIGIT2
,
2314 ui::DomKey::CHARACTER
,
2316 {ui::ET_KEY_PRESSED
,
2318 ui::DomCode::DIGIT3
,
2320 ui::DomKey::CHARACTER
,
2323 ui::DomCode::DIGIT3
,
2325 ui::DomKey::CHARACTER
,
2327 {ui::ET_KEY_PRESSED
,
2329 ui::DomCode::DIGIT4
,
2331 ui::DomKey::CHARACTER
,
2334 ui::DomCode::DIGIT4
,
2336 ui::DomKey::CHARACTER
,
2338 {ui::ET_KEY_PRESSED
,
2340 ui::DomCode::DIGIT5
,
2342 ui::DomKey::CHARACTER
,
2345 ui::DomCode::DIGIT5
,
2347 ui::DomKey::CHARACTER
,
2349 {ui::ET_KEY_PRESSED
,
2351 ui::DomCode::DIGIT6
,
2353 ui::DomKey::CHARACTER
,
2356 ui::DomCode::DIGIT6
,
2358 ui::DomKey::CHARACTER
,
2360 {ui::ET_KEY_PRESSED
,
2362 ui::DomCode::DIGIT7
,
2364 ui::DomKey::CHARACTER
,
2367 ui::DomCode::DIGIT7
,
2369 ui::DomKey::CHARACTER
,
2371 {ui::ET_KEY_PRESSED
,
2373 ui::DomCode::DIGIT8
,
2375 ui::DomKey::CHARACTER
,
2378 ui::DomCode::DIGIT8
,
2380 ui::DomKey::CHARACTER
,
2382 {ui::ET_KEY_PRESSED
,
2384 ui::DomCode::DIGIT9
,
2386 ui::DomKey::CHARACTER
,
2389 ui::DomCode::DIGIT9
,
2391 ui::DomKey::CHARACTER
,
2393 {ui::ET_KEY_PRESSED
,
2395 ui::DomCode::DIGIT0
,
2397 ui::DomKey::CHARACTER
,
2400 ui::DomCode::DIGIT0
,
2402 ui::DomKey::CHARACTER
,
2404 {ui::ET_KEY_PRESSED
,
2405 {ui::VKEY_OEM_MINUS
,
2408 ui::DomKey::CHARACTER
,
2410 {ui::VKEY_OEM_MINUS
,
2413 ui::DomKey::CHARACTER
,
2415 {ui::ET_KEY_PRESSED
,
2419 ui::DomKey::CHARACTER
,
2424 ui::DomKey::CHARACTER
,
2427 // The number row should be rewritten as the F<number> row with Search
2429 {ui::ET_KEY_PRESSED
,
2431 ui::DomCode::DIGIT1
,
2432 ui::EF_COMMAND_DOWN
,
2433 ui::DomKey::CHARACTER
,
2435 {ui::VKEY_F1
, ui::DomCode::F1
, ui::EF_NONE
, ui::DomKey::F1
, 0}},
2436 {ui::ET_KEY_PRESSED
,
2438 ui::DomCode::DIGIT2
,
2439 ui::EF_COMMAND_DOWN
,
2440 ui::DomKey::CHARACTER
,
2442 {ui::VKEY_F2
, ui::DomCode::F2
, ui::EF_NONE
, ui::DomKey::F2
, 0}},
2443 {ui::ET_KEY_PRESSED
,
2445 ui::DomCode::DIGIT3
,
2446 ui::EF_COMMAND_DOWN
,
2447 ui::DomKey::CHARACTER
,
2449 {ui::VKEY_F3
, ui::DomCode::F3
, ui::EF_NONE
, ui::DomKey::F3
, 0}},
2450 {ui::ET_KEY_PRESSED
,
2452 ui::DomCode::DIGIT4
,
2453 ui::EF_COMMAND_DOWN
,
2454 ui::DomKey::CHARACTER
,
2456 {ui::VKEY_F4
, ui::DomCode::F4
, ui::EF_NONE
, ui::DomKey::F4
, 0}},
2457 {ui::ET_KEY_PRESSED
,
2459 ui::DomCode::DIGIT5
,
2460 ui::EF_COMMAND_DOWN
,
2461 ui::DomKey::CHARACTER
,
2463 {ui::VKEY_F5
, ui::DomCode::F5
, ui::EF_NONE
, ui::DomKey::F5
, 0}},
2464 {ui::ET_KEY_PRESSED
,
2466 ui::DomCode::DIGIT6
,
2467 ui::EF_COMMAND_DOWN
,
2468 ui::DomKey::CHARACTER
,
2470 {ui::VKEY_F6
, ui::DomCode::F6
, ui::EF_NONE
, ui::DomKey::F6
, 0}},
2471 {ui::ET_KEY_PRESSED
,
2473 ui::DomCode::DIGIT7
,
2474 ui::EF_COMMAND_DOWN
,
2475 ui::DomKey::CHARACTER
,
2477 {ui::VKEY_F7
, ui::DomCode::F7
, ui::EF_NONE
, ui::DomKey::F7
, 0}},
2478 {ui::ET_KEY_PRESSED
,
2480 ui::DomCode::DIGIT8
,
2481 ui::EF_COMMAND_DOWN
,
2482 ui::DomKey::CHARACTER
,
2484 {ui::VKEY_F8
, ui::DomCode::F8
, ui::EF_NONE
, ui::DomKey::F8
, 0}},
2485 {ui::ET_KEY_PRESSED
,
2487 ui::DomCode::DIGIT9
,
2488 ui::EF_COMMAND_DOWN
,
2489 ui::DomKey::CHARACTER
,
2491 {ui::VKEY_F9
, ui::DomCode::F9
, ui::EF_NONE
, ui::DomKey::F9
, 0}},
2492 {ui::ET_KEY_PRESSED
,
2494 ui::DomCode::DIGIT0
,
2495 ui::EF_COMMAND_DOWN
,
2496 ui::DomKey::CHARACTER
,
2498 {ui::VKEY_F10
, ui::DomCode::F10
, ui::EF_NONE
, ui::DomKey::F10
, 0}},
2499 {ui::ET_KEY_PRESSED
,
2500 {ui::VKEY_OEM_MINUS
,
2502 ui::EF_COMMAND_DOWN
,
2503 ui::DomKey::CHARACTER
,
2505 {ui::VKEY_F11
, ui::DomCode::F11
, ui::EF_NONE
, ui::DomKey::F11
, 0}},
2506 {ui::ET_KEY_PRESSED
,
2509 ui::EF_COMMAND_DOWN
,
2510 ui::DomKey::CHARACTER
,
2512 {ui::VKEY_F12
, ui::DomCode::F12
, ui::EF_NONE
, ui::DomKey::F12
, 0}},
2514 // The function keys should not be rewritten with Search key pressed.
2515 {ui::ET_KEY_PRESSED
,
2516 {ui::VKEY_F1
, ui::DomCode::F1
, ui::EF_COMMAND_DOWN
, ui::DomKey::F1
, 0},
2517 {ui::VKEY_F1
, ui::DomCode::F1
, ui::EF_NONE
, ui::DomKey::F1
, 0}},
2518 {ui::ET_KEY_PRESSED
,
2519 {ui::VKEY_F2
, ui::DomCode::F2
, ui::EF_COMMAND_DOWN
, ui::DomKey::F2
, 0},
2520 {ui::VKEY_F2
, ui::DomCode::F2
, ui::EF_NONE
, ui::DomKey::F2
, 0}},
2521 {ui::ET_KEY_PRESSED
,
2522 {ui::VKEY_F3
, ui::DomCode::F3
, ui::EF_COMMAND_DOWN
, ui::DomKey::F3
, 0},
2523 {ui::VKEY_F3
, ui::DomCode::F3
, ui::EF_NONE
, ui::DomKey::F3
, 0}},
2524 {ui::ET_KEY_PRESSED
,
2525 {ui::VKEY_F4
, ui::DomCode::F4
, ui::EF_COMMAND_DOWN
, ui::DomKey::F4
, 0},
2526 {ui::VKEY_F4
, ui::DomCode::F4
, ui::EF_NONE
, ui::DomKey::F4
, 0}},
2527 {ui::ET_KEY_PRESSED
,
2528 {ui::VKEY_F5
, ui::DomCode::F5
, ui::EF_COMMAND_DOWN
, ui::DomKey::F5
, 0},
2529 {ui::VKEY_F5
, ui::DomCode::F5
, ui::EF_NONE
, ui::DomKey::F5
, 0}},
2530 {ui::ET_KEY_PRESSED
,
2531 {ui::VKEY_F6
, ui::DomCode::F6
, ui::EF_COMMAND_DOWN
, ui::DomKey::F6
, 0},
2532 {ui::VKEY_F6
, ui::DomCode::F6
, ui::EF_NONE
, ui::DomKey::F6
, 0}},
2533 {ui::ET_KEY_PRESSED
,
2534 {ui::VKEY_F7
, ui::DomCode::F7
, ui::EF_COMMAND_DOWN
, ui::DomKey::F7
, 0},
2535 {ui::VKEY_F7
, ui::DomCode::F7
, ui::EF_NONE
, ui::DomKey::F7
, 0}},
2536 {ui::ET_KEY_PRESSED
,
2537 {ui::VKEY_F8
, ui::DomCode::F8
, ui::EF_COMMAND_DOWN
, ui::DomKey::F8
, 0},
2538 {ui::VKEY_F8
, ui::DomCode::F8
, ui::EF_NONE
, ui::DomKey::F8
, 0}},
2539 {ui::ET_KEY_PRESSED
,
2540 {ui::VKEY_F9
, ui::DomCode::F9
, ui::EF_COMMAND_DOWN
, ui::DomKey::F9
, 0},
2541 {ui::VKEY_F9
, ui::DomCode::F9
, ui::EF_NONE
, ui::DomKey::F9
, 0}},
2542 {ui::ET_KEY_PRESSED
,
2545 ui::EF_COMMAND_DOWN
,
2548 {ui::VKEY_F10
, ui::DomCode::F10
, ui::EF_NONE
, ui::DomKey::F10
, 0}},
2549 {ui::ET_KEY_PRESSED
,
2552 ui::EF_COMMAND_DOWN
,
2555 {ui::VKEY_F11
, ui::DomCode::F11
, ui::EF_NONE
, ui::DomKey::F11
, 0}},
2556 {ui::ET_KEY_PRESSED
,
2559 ui::EF_COMMAND_DOWN
,
2562 {ui::VKEY_F12
, ui::DomCode::F12
, ui::EF_NONE
, ui::DomKey::F12
, 0}}};
2564 for (const auto& test
: tests
) {
2565 CheckKeyTestCase(&rewriter
, test
);
2569 TEST_F(EventRewriterTest
, TestRewriteExtendedKeysWithSearchRemapped
) {
2570 // Remap Search to Control.
2571 TestingPrefServiceSyncable prefs
;
2572 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
2573 IntegerPrefMember search
;
2574 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
2575 search
.SetValue(chromeos::input_method::kControlKey
);
2577 EventRewriter
rewriter(NULL
);
2578 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
2579 rewriter
.set_pref_service_for_testing(&prefs
);
2581 KeyTestCase tests
[] = {
2582 // Alt+Search+Down -> End
2583 {ui::ET_KEY_PRESSED
,
2585 ui::DomCode::ARROW_DOWN
,
2586 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
2587 ui::DomKey::ARROW_DOWN
,
2589 {ui::VKEY_END
, ui::DomCode::END
, ui::EF_NONE
, ui::DomKey::END
, 0}},
2591 // Shift+Alt+Search+Down -> Shift+End
2592 {ui::ET_KEY_PRESSED
,
2594 ui::DomCode::ARROW_DOWN
,
2595 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
,
2596 ui::DomKey::ARROW_DOWN
,
2598 {ui::VKEY_END
, ui::DomCode::END
, ui::EF_SHIFT_DOWN
, ui::DomKey::END
, 0}},
2601 for (const auto& test
: tests
) {
2602 CheckKeyTestCase(&rewriter
, test
);
2606 TEST_F(EventRewriterTest
, TestRewriteKeyEventSentByXSendEvent
) {
2607 // Remap Control to Alt.
2608 TestingPrefServiceSyncable prefs
;
2609 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
2610 IntegerPrefMember control
;
2611 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
2612 control
.SetValue(chromeos::input_method::kAltKey
);
2614 EventRewriter
rewriter(NULL
);
2615 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
2616 rewriter
.set_pref_service_for_testing(&prefs
);
2618 // Send left control press.
2620 ui::KeyEvent
keyevent(ui::ET_KEY_PRESSED
, ui::VKEY_CONTROL
,
2621 ui::DomCode::CONTROL_LEFT
, ui::EF_FINAL
,
2622 ui::DomKey::CONTROL
, 0, ui::EventTimeForNow());
2623 scoped_ptr
<ui::Event
> new_event
;
2624 // Control should NOT be remapped to Alt if EF_FINAL is set.
2625 EXPECT_EQ(ui::EVENT_REWRITE_CONTINUE
,
2626 rewriter
.RewriteEvent(keyevent
, &new_event
));
2627 EXPECT_FALSE(new_event
);
2629 #if defined(USE_X11)
2630 // Send left control press, using XI2 native events.
2632 ui::ScopedXI2Event xev
;
2633 xev
.InitKeyEvent(ui::ET_KEY_PRESSED
, ui::VKEY_CONTROL
, 0);
2634 XEvent
* xevent
= xev
;
2635 xevent
->xkey
.keycode
= XKeysymToKeycode(gfx::GetXDisplay(), XK_Control_L
);
2636 xevent
->xkey
.send_event
= True
; // XSendEvent() always does this.
2637 ui::KeyEvent
keyevent(xev
);
2638 scoped_ptr
<ui::Event
> new_event
;
2639 // Control should NOT be remapped to Alt if send_event
2640 // flag in the event is True.
2641 EXPECT_EQ(ui::EVENT_REWRITE_CONTINUE
,
2642 rewriter
.RewriteEvent(keyevent
, &new_event
));
2643 EXPECT_FALSE(new_event
);
2648 TEST_F(EventRewriterTest
, TestRewriteNonNativeEvent
) {
2649 // Remap Control to Alt.
2650 TestingPrefServiceSyncable prefs
;
2651 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
2652 IntegerPrefMember control
;
2653 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
2654 control
.SetValue(chromeos::input_method::kAltKey
);
2656 EventRewriter
rewriter(NULL
);
2657 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
2658 rewriter
.set_pref_service_for_testing(&prefs
);
2660 const int kTouchId
= 2;
2661 gfx::Point
location(0, 0);
2662 ui::TouchEvent
press(ui::ET_TOUCH_PRESSED
, location
, kTouchId
,
2664 press
.set_flags(ui::EF_CONTROL_DOWN
);
2665 #if defined(USE_X11)
2666 ui::UpdateX11EventForFlags(&press
);
2669 scoped_ptr
<ui::Event
> new_event
;
2670 rewriter
.RewriteEvent(press
, &new_event
);
2671 EXPECT_TRUE(new_event
);
2672 // Control should be remapped to Alt.
2673 EXPECT_EQ(ui::EF_ALT_DOWN
,
2674 new_event
->flags() & (ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
));
2677 // Keeps a buffer of handled events.
2678 class EventBuffer
: public ui::test::TestEventProcessor
{
2681 ~EventBuffer() override
{}
2683 void PopEvents(ScopedVector
<ui::Event
>* events
) {
2685 events
->swap(events_
);
2689 // ui::EventProcessor overrides:
2690 ui::EventDispatchDetails
OnEventFromSource(ui::Event
* event
) override
{
2691 if (event
->IsKeyEvent()) {
2692 events_
.push_back(new ui::KeyEvent(*static_cast<ui::KeyEvent
*>(event
)));
2693 } else if (event
->IsMouseWheelEvent()) {
2695 new ui::MouseWheelEvent(*static_cast<ui::MouseWheelEvent
*>(event
)));
2696 } else if (event
->IsMouseEvent()) {
2698 new ui::MouseEvent(*static_cast<ui::MouseEvent
*>(event
)));
2700 return ui::EventDispatchDetails();
2703 ScopedVector
<ui::Event
> events_
;
2705 DISALLOW_COPY_AND_ASSIGN(EventBuffer
);
2708 // Trivial EventSource that does nothing but send events.
2709 class TestEventSource
: public ui::EventSource
{
2711 explicit TestEventSource(ui::EventProcessor
* processor
)
2712 : processor_(processor
) {}
2713 ui::EventProcessor
* GetEventProcessor() override
{ return processor_
; }
2714 ui::EventDispatchDetails
Send(ui::Event
* event
) {
2715 return SendEventToProcessor(event
);
2719 ui::EventProcessor
* processor_
;
2722 // Tests of event rewriting that depend on the Ash window manager.
2723 class EventRewriterAshTest
: public ash::test::AshTestBase
{
2725 EventRewriterAshTest()
2726 : source_(&buffer_
),
2727 fake_user_manager_(new user_manager::FakeUserManager
),
2728 user_manager_enabler_(fake_user_manager_
) {}
2729 ~EventRewriterAshTest() override
{}
2731 bool RewriteFunctionKeys(const ui::Event
& event
,
2732 scoped_ptr
<ui::Event
>* rewritten_event
) {
2733 return rewriter_
->RewriteEvent(event
, rewritten_event
);
2736 ui::EventDispatchDetails
Send(ui::Event
* event
) {
2737 return source_
.Send(event
);
2740 void SendKeyEvent(ui::EventType type
,
2741 ui::KeyboardCode key_code
,
2744 base::char16 character
) {
2745 ui::KeyEvent
press(type
, key_code
, code
, ui::EF_NONE
, key
, character
,
2746 ui::EventTimeForNow());
2747 ui::EventDispatchDetails details
= Send(&press
);
2748 CHECK(!details
.dispatcher_destroyed
);
2751 void SendActivateStickyKeyPattern(ui::KeyboardCode key_code
,
2754 base::char16 character
) {
2755 SendKeyEvent(ui::ET_KEY_PRESSED
, key_code
, code
, key
, character
);
2756 SendKeyEvent(ui::ET_KEY_RELEASED
, key_code
, code
, key
, character
);
2760 TestingPrefServiceSyncable
* prefs() { return &prefs_
; }
2762 void PopEvents(ScopedVector
<ui::Event
>* events
) { buffer_
.PopEvents(events
); }
2764 void SetUp() override
{
2765 AshTestBase::SetUp();
2766 sticky_keys_controller_
=
2767 ash::Shell::GetInstance()->sticky_keys_controller();
2768 rewriter_
.reset(new EventRewriter(sticky_keys_controller_
));
2769 chromeos::Preferences::RegisterProfilePrefs(prefs_
.registry());
2770 rewriter_
->set_pref_service_for_testing(&prefs_
);
2771 #if defined(USE_X11)
2772 ui::SetUpTouchPadForTest(kTouchPadDeviceId
);
2774 source_
.AddEventRewriter(rewriter_
.get());
2775 sticky_keys_controller_
->Enable(true);
2778 void TearDown() override
{
2780 AshTestBase::TearDown();
2784 ash::StickyKeysController
* sticky_keys_controller_
;
2787 scoped_ptr
<EventRewriter
> rewriter_
;
2789 EventBuffer buffer_
;
2790 TestEventSource source_
;
2792 user_manager::FakeUserManager
* fake_user_manager_
; // Not owned.
2793 chromeos::ScopedUserManagerEnabler user_manager_enabler_
;
2794 TestingPrefServiceSyncable prefs_
;
2796 DISALLOW_COPY_AND_ASSIGN(EventRewriterAshTest
);
2799 TEST_F(EventRewriterAshTest
, TopRowKeysAreFunctionKeys
) {
2800 scoped_ptr
<aura::Window
> window(CreateTestWindowInShellWithId(1));
2801 ash::wm::WindowState
* window_state
= ash::wm::GetWindowState(window
.get());
2802 window_state
->Activate();
2803 ScopedVector
<ui::Event
> events
;
2805 // Create a simulated keypress of F1 targetted at the window.
2806 ui::KeyEvent
press_f1(ui::ET_KEY_PRESSED
, ui::VKEY_F1
, ui::DomCode::F1
,
2807 ui::EF_NONE
, ui::DomKey::F1
, 0, ui::EventTimeForNow());
2809 // Simulate an apps v2 window that has requested top row keys as function
2810 // keys. The event should not be rewritten.
2811 window_state
->set_top_row_keys_are_function_keys(true);
2812 ui::EventDispatchDetails details
= Send(&press_f1
);
2813 ASSERT_FALSE(details
.dispatcher_destroyed
);
2815 EXPECT_EQ(1u, events
.size());
2816 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_F1
,
2817 ui::DomCode::F1
, ui::EF_NONE
,
2819 GetKeyEventAsString(*static_cast<ui::KeyEvent
*>(events
[0])));
2821 // The event should also not be rewritten if the send-function-keys pref is
2822 // additionally set, for both apps v2 and regular windows.
2823 BooleanPrefMember send_function_keys_pref
;
2824 send_function_keys_pref
.Init(prefs::kLanguageSendFunctionKeys
, prefs());
2825 send_function_keys_pref
.SetValue(true);
2826 window_state
->set_top_row_keys_are_function_keys(false);
2827 details
= Send(&press_f1
);
2828 ASSERT_FALSE(details
.dispatcher_destroyed
);
2830 EXPECT_EQ(1u, events
.size());
2831 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_F1
,
2832 ui::DomCode::F1
, ui::EF_NONE
,
2834 GetKeyEventAsString(*static_cast<ui::KeyEvent
*>(events
[0])));
2836 // If the pref isn't set when an event is sent to a regular window, F1 is
2837 // rewritten to the back key.
2838 send_function_keys_pref
.SetValue(false);
2839 details
= Send(&press_f1
);
2840 ASSERT_FALSE(details
.dispatcher_destroyed
);
2842 EXPECT_EQ(1u, events
.size());
2843 EXPECT_EQ(GetExpectedResultAsString(ui::ET_KEY_PRESSED
, ui::VKEY_BROWSER_BACK
,
2844 ui::DomCode::BROWSER_BACK
, ui::EF_NONE
,
2845 ui::DomKey::BROWSER_BACK
, 0),
2846 GetKeyEventAsString(*static_cast<ui::KeyEvent
*>(events
[0])));
2849 TEST_F(EventRewriterTest
, TestRewrittenModifierClick
) {
2850 #if defined(USE_X11)
2851 std::vector
<int> device_list
;
2852 device_list
.push_back(10);
2853 ui::TouchFactory::GetInstance()->SetPointerDeviceForTest(device_list
);
2855 // Remap Control to Alt.
2856 TestingPrefServiceSyncable prefs
;
2857 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
2858 IntegerPrefMember control
;
2859 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
2860 control
.SetValue(chromeos::input_method::kAltKey
);
2862 EventRewriter
rewriter(NULL
);
2863 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
2864 rewriter
.set_pref_service_for_testing(&prefs
);
2866 // Check that Control + Left Button is converted (via Alt + Left Button)
2868 ui::ScopedXI2Event xev
;
2869 xev
.InitGenericButtonEvent(10, ui::ET_MOUSE_PRESSED
, gfx::Point(),
2870 ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_CONTROL_DOWN
);
2871 ui::MouseEvent
press(xev
);
2873 EXPECT_EQ(ui::ET_MOUSE_PRESSED
, press
.type());
2874 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_CONTROL_DOWN
, press
.flags());
2875 scoped_ptr
<ui::Event
> new_event
;
2876 const ui::MouseEvent
* result
=
2877 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
2878 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
2879 EXPECT_FALSE(ui::EF_LEFT_MOUSE_BUTTON
& result
->flags());
2880 EXPECT_FALSE(ui::EF_CONTROL_DOWN
& result
->flags());
2881 EXPECT_FALSE(ui::EF_ALT_DOWN
& result
->flags());
2882 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
2886 TEST_F(EventRewriterTest
, DontRewriteIfNotRewritten
) {
2887 // TODO(kpschoedel): pending changes for crbug.com/360377
2888 // to |chromeos::EventRewriter::RewriteLocatedEvent()
2889 #if defined(USE_X11)
2890 std::vector
<int> device_list
;
2891 device_list
.push_back(10);
2892 device_list
.push_back(11);
2893 ui::TouchFactory::GetInstance()->SetPointerDeviceForTest(device_list
);
2895 TestingPrefServiceSyncable prefs
;
2896 EventRewriter
rewriter(NULL
);
2897 rewriter
.set_pref_service_for_testing(&prefs
);
2898 const int kLeftAndAltFlag
= ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_ALT_DOWN
;
2900 // Test Alt + Left click.
2902 ui::MouseEvent
press(ui::ET_MOUSE_PRESSED
, gfx::Point(), gfx::Point(),
2903 ui::EventTimeForNow(), kLeftAndAltFlag
,
2904 ui::EF_LEFT_MOUSE_BUTTON
);
2905 ui::EventTestApi
test_press(&press
);
2906 test_press
.set_source_device_id(10);
2908 EXPECT_EQ(ui::ET_MOUSE_PRESSED
, press
.type());
2909 EXPECT_EQ(kLeftAndAltFlag
, press
.flags());
2910 scoped_ptr
<ui::Event
> new_event
;
2911 const ui::MouseEvent
* result
=
2912 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
2913 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
2914 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
2915 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
2918 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
, gfx::Point(), gfx::Point(),
2919 ui::EventTimeForNow(), kLeftAndAltFlag
,
2920 ui::EF_LEFT_MOUSE_BUTTON
);
2921 ui::EventTestApi
test_release(&release
);
2922 test_release
.set_source_device_id(10);
2923 scoped_ptr
<ui::Event
> new_event
;
2924 const ui::MouseEvent
* result
=
2925 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
2926 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
2927 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
2928 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
2930 #if defined(USE_X11)
2931 // Test Alt + Left click, using XI2 native events.
2933 ui::ScopedXI2Event xev
;
2934 xev
.InitGenericButtonEvent(10, ui::ET_MOUSE_PRESSED
, gfx::Point(),
2936 ui::MouseEvent
press(xev
);
2938 EXPECT_EQ(ui::ET_MOUSE_PRESSED
, press
.type());
2939 EXPECT_EQ(kLeftAndAltFlag
, press
.flags());
2940 scoped_ptr
<ui::Event
> new_event
;
2941 const ui::MouseEvent
* result
=
2942 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
2943 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
2944 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
2945 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
2948 ui::ScopedXI2Event xev
;
2949 xev
.InitGenericButtonEvent(10, ui::ET_MOUSE_RELEASED
, gfx::Point(),
2951 ui::MouseEvent
release(xev
);
2952 scoped_ptr
<ui::Event
> new_event
;
2953 const ui::MouseEvent
* result
=
2954 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
2955 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
2956 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
2957 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
2961 // No ALT in frst click.
2963 ui::MouseEvent
press(ui::ET_MOUSE_PRESSED
, gfx::Point(), gfx::Point(),
2964 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON
,
2965 ui::EF_LEFT_MOUSE_BUTTON
);
2966 ui::EventTestApi
test_press(&press
);
2967 test_press
.set_source_device_id(10);
2968 scoped_ptr
<ui::Event
> new_event
;
2969 const ui::MouseEvent
* result
=
2970 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
2971 EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON
& result
->flags());
2972 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
2975 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
, gfx::Point(), gfx::Point(),
2976 ui::EventTimeForNow(), kLeftAndAltFlag
,
2977 ui::EF_LEFT_MOUSE_BUTTON
);
2978 ui::EventTestApi
test_release(&release
);
2979 test_release
.set_source_device_id(10);
2980 scoped_ptr
<ui::Event
> new_event
;
2981 const ui::MouseEvent
* result
=
2982 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
2983 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_ALT_DOWN
) & result
->flags());
2984 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
2986 #if defined(USE_X11)
2987 // No ALT in frst click, using XI2 native events.
2989 ui::ScopedXI2Event xev
;
2990 xev
.InitGenericButtonEvent(10, ui::ET_MOUSE_PRESSED
, gfx::Point(),
2991 ui::EF_LEFT_MOUSE_BUTTON
);
2992 ui::MouseEvent
press(xev
);
2993 scoped_ptr
<ui::Event
> new_event
;
2994 const ui::MouseEvent
* result
=
2995 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
2996 EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON
& result
->flags());
2997 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
3000 ui::ScopedXI2Event xev
;
3001 xev
.InitGenericButtonEvent(10, ui::ET_MOUSE_RELEASED
, gfx::Point(),
3003 ui::MouseEvent
release(xev
);
3004 scoped_ptr
<ui::Event
> new_event
;
3005 const ui::MouseEvent
* result
=
3006 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
3007 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_ALT_DOWN
) & result
->flags());
3008 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
3012 // ALT on different device.
3014 ui::MouseEvent
press(ui::ET_MOUSE_PRESSED
, gfx::Point(), gfx::Point(),
3015 ui::EventTimeForNow(), kLeftAndAltFlag
,
3016 ui::EF_LEFT_MOUSE_BUTTON
);
3017 ui::EventTestApi
test_press(&press
);
3018 test_press
.set_source_device_id(11);
3019 scoped_ptr
<ui::Event
> new_event
;
3020 const ui::MouseEvent
* result
=
3021 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
3022 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
3023 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
3024 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
3027 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
, gfx::Point(), gfx::Point(),
3028 ui::EventTimeForNow(), kLeftAndAltFlag
,
3029 ui::EF_LEFT_MOUSE_BUTTON
);
3030 ui::EventTestApi
test_release(&release
);
3031 test_release
.set_source_device_id(10);
3032 scoped_ptr
<ui::Event
> new_event
;
3033 const ui::MouseEvent
* result
=
3034 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
3035 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_ALT_DOWN
) & result
->flags());
3036 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
3039 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
, gfx::Point(), gfx::Point(),
3040 ui::EventTimeForNow(), kLeftAndAltFlag
,
3041 ui::EF_LEFT_MOUSE_BUTTON
);
3042 ui::EventTestApi
test_release(&release
);
3043 test_release
.set_source_device_id(11);
3044 scoped_ptr
<ui::Event
> new_event
;
3045 const ui::MouseEvent
* result
=
3046 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
3047 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
3048 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
3049 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
3051 #if defined(USE_X11)
3052 // ALT on different device, using XI2 native events.
3054 ui::ScopedXI2Event xev
;
3055 xev
.InitGenericButtonEvent(11, ui::ET_MOUSE_PRESSED
, gfx::Point(),
3057 ui::MouseEvent
press(xev
);
3058 scoped_ptr
<ui::Event
> new_event
;
3059 const ui::MouseEvent
* result
=
3060 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
3061 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
3062 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
3063 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
3066 ui::ScopedXI2Event xev
;
3067 xev
.InitGenericButtonEvent(10, ui::ET_MOUSE_RELEASED
, gfx::Point(),
3069 ui::MouseEvent
release(xev
);
3070 scoped_ptr
<ui::Event
> new_event
;
3071 const ui::MouseEvent
* result
=
3072 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
3073 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_ALT_DOWN
) & result
->flags());
3074 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
3077 ui::ScopedXI2Event xev
;
3078 xev
.InitGenericButtonEvent(11, ui::ET_MOUSE_RELEASED
, gfx::Point(),
3080 ui::MouseEvent
release(xev
);
3081 scoped_ptr
<ui::Event
> new_event
;
3082 const ui::MouseEvent
* result
=
3083 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
3084 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
3085 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
3086 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
3091 TEST_F(EventRewriterAshTest
, StickyKeyEventDispatchImpl
) {
3092 // Test the actual key event dispatch implementation.
3093 ScopedVector
<ui::Event
> events
;
3095 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
3096 ui::DomKey::CONTROL
, 0);
3098 EXPECT_EQ(1u, events
.size());
3099 EXPECT_EQ(ui::ET_KEY_PRESSED
, events
[0]->type());
3100 EXPECT_EQ(ui::VKEY_CONTROL
,
3101 static_cast<ui::KeyEvent
*>(events
[0])->key_code());
3103 // Test key press event is correctly modified and modifier release
3105 ui::KeyEvent
press(ui::ET_KEY_PRESSED
, ui::VKEY_C
, ui::DomCode::KEY_C
,
3106 ui::EF_NONE
, ui::DomKey::CHARACTER
, 'c',
3107 ui::EventTimeForNow());
3108 ui::EventDispatchDetails details
= Send(&press
);
3110 EXPECT_EQ(2u, events
.size());
3111 EXPECT_EQ(ui::ET_KEY_PRESSED
, events
[0]->type());
3112 EXPECT_EQ(ui::VKEY_C
, static_cast<ui::KeyEvent
*>(events
[0])->key_code());
3113 EXPECT_TRUE(events
[0]->flags() & ui::EF_CONTROL_DOWN
);
3114 EXPECT_EQ(ui::ET_KEY_RELEASED
, events
[1]->type());
3115 EXPECT_EQ(ui::VKEY_CONTROL
,
3116 static_cast<ui::KeyEvent
*>(events
[1])->key_code());
3118 // Test key release event is not modified.
3119 ui::KeyEvent
release(ui::ET_KEY_RELEASED
, ui::VKEY_C
, ui::DomCode::KEY_C
,
3120 ui::EF_NONE
, ui::DomKey::CHARACTER
, 'c',
3121 ui::EventTimeForNow());
3122 details
= Send(&release
);
3123 ASSERT_FALSE(details
.dispatcher_destroyed
);
3125 EXPECT_EQ(1u, events
.size());
3126 EXPECT_EQ(ui::ET_KEY_RELEASED
, events
[0]->type());
3127 EXPECT_EQ(ui::VKEY_C
, static_cast<ui::KeyEvent
*>(events
[0])->key_code());
3128 EXPECT_FALSE(events
[0]->flags() & ui::EF_CONTROL_DOWN
);
3131 TEST_F(EventRewriterAshTest
, MouseEventDispatchImpl
) {
3132 ScopedVector
<ui::Event
> events
;
3134 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
3135 ui::DomKey::CONTROL
, 0);
3138 // Test mouse press event is correctly modified.
3139 gfx::Point
location(0, 0);
3140 ui::MouseEvent
press(ui::ET_MOUSE_PRESSED
, location
, location
,
3141 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON
,
3142 ui::EF_LEFT_MOUSE_BUTTON
);
3143 ui::EventDispatchDetails details
= Send(&press
);
3144 ASSERT_FALSE(details
.dispatcher_destroyed
);
3146 EXPECT_EQ(1u, events
.size());
3147 EXPECT_EQ(ui::ET_MOUSE_PRESSED
, events
[0]->type());
3148 EXPECT_TRUE(events
[0]->flags() & ui::EF_CONTROL_DOWN
);
3150 // Test mouse release event is correctly modified and modifier release
3151 // event is sent. The mouse event should have the correct DIP location.
3152 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
, location
, location
,
3153 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON
,
3154 ui::EF_LEFT_MOUSE_BUTTON
);
3155 details
= Send(&release
);
3156 ASSERT_FALSE(details
.dispatcher_destroyed
);
3158 EXPECT_EQ(2u, events
.size());
3159 EXPECT_EQ(ui::ET_MOUSE_RELEASED
, events
[0]->type());
3160 EXPECT_TRUE(events
[0]->flags() & ui::EF_CONTROL_DOWN
);
3161 EXPECT_EQ(ui::ET_KEY_RELEASED
, events
[1]->type());
3162 EXPECT_EQ(ui::VKEY_CONTROL
,
3163 static_cast<ui::KeyEvent
*>(events
[1])->key_code());
3166 TEST_F(EventRewriterAshTest
, MouseWheelEventDispatchImpl
) {
3167 ScopedVector
<ui::Event
> events
;
3169 // Test positive mouse wheel event is correctly modified and modifier release
3171 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
3172 ui::DomKey::CONTROL
, 0);
3174 gfx::Point
location(0, 0);
3175 ui::MouseEvent
mev(ui::ET_MOUSEWHEEL
, location
, location
,
3176 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON
,
3177 ui::EF_LEFT_MOUSE_BUTTON
);
3178 ui::MouseWheelEvent
positive(mev
, 0, ui::MouseWheelEvent::kWheelDelta
);
3179 ui::EventDispatchDetails details
= Send(&positive
);
3180 ASSERT_FALSE(details
.dispatcher_destroyed
);
3182 EXPECT_EQ(2u, events
.size());
3183 EXPECT_TRUE(events
[0]->IsMouseWheelEvent());
3184 EXPECT_TRUE(events
[0]->flags() & ui::EF_CONTROL_DOWN
);
3185 EXPECT_EQ(ui::ET_KEY_RELEASED
, events
[1]->type());
3186 EXPECT_EQ(ui::VKEY_CONTROL
,
3187 static_cast<ui::KeyEvent
*>(events
[1])->key_code());
3189 // Test negative mouse wheel event is correctly modified and modifier release
3191 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
3192 ui::DomKey::CONTROL
, 0);
3194 ui::MouseWheelEvent
negative(mev
, 0, -ui::MouseWheelEvent::kWheelDelta
);
3195 details
= Send(&negative
);
3196 ASSERT_FALSE(details
.dispatcher_destroyed
);
3198 EXPECT_EQ(2u, events
.size());
3199 EXPECT_TRUE(events
[0]->IsMouseWheelEvent());
3200 EXPECT_TRUE(events
[0]->flags() & ui::EF_CONTROL_DOWN
);
3201 EXPECT_EQ(ui::ET_KEY_RELEASED
, events
[1]->type());
3202 EXPECT_EQ(ui::VKEY_CONTROL
,
3203 static_cast<ui::KeyEvent
*>(events
[1])->key_code());
3206 class StickyKeysOverlayTest
: public EventRewriterAshTest
{
3208 StickyKeysOverlayTest() : overlay_(NULL
) {}
3210 ~StickyKeysOverlayTest() override
{}
3212 void SetUp() override
{
3213 EventRewriterAshTest::SetUp();
3214 overlay_
= sticky_keys_controller_
->GetOverlayForTest();
3215 ASSERT_TRUE(overlay_
);
3218 ash::StickyKeysOverlay
* overlay_
;
3221 TEST_F(StickyKeysOverlayTest
, OneModifierEnabled
) {
3222 EXPECT_FALSE(overlay_
->is_visible());
3223 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3224 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3226 // Pressing modifier key should show overlay.
3227 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
3228 ui::DomKey::CONTROL
, 0);
3229 EXPECT_TRUE(overlay_
->is_visible());
3230 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
3231 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3233 // Pressing a normal key should hide overlay.
3234 SendActivateStickyKeyPattern(ui::VKEY_T
, ui::DomCode::KEY_T
,
3235 ui::DomKey::CHARACTER
, 't');
3236 EXPECT_FALSE(overlay_
->is_visible());
3237 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3238 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3241 TEST_F(StickyKeysOverlayTest
, TwoModifiersEnabled
) {
3242 EXPECT_FALSE(overlay_
->is_visible());
3243 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3244 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3245 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3246 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
3248 // Pressing two modifiers should show overlay.
3249 SendActivateStickyKeyPattern(ui::VKEY_SHIFT
, ui::DomCode::SHIFT_LEFT
,
3250 ui::DomKey::SHIFT
, 0);
3251 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
3252 ui::DomKey::CONTROL
, 0);
3253 EXPECT_TRUE(overlay_
->is_visible());
3254 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
3255 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
3256 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
3257 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3259 // Pressing a normal key should hide overlay.
3260 SendActivateStickyKeyPattern(ui::VKEY_N
, ui::DomCode::KEY_N
,
3261 ui::DomKey::CHARACTER
, 'n');
3262 EXPECT_FALSE(overlay_
->is_visible());
3263 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3264 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3265 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3266 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
3269 TEST_F(StickyKeysOverlayTest
, LockedModifier
) {
3270 EXPECT_FALSE(overlay_
->is_visible());
3271 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3272 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
3274 // Pressing a modifier key twice should lock modifier and show overlay.
3275 SendActivateStickyKeyPattern(ui::VKEY_LMENU
, ui::DomCode::ALT_LEFT
,
3276 ui::DomKey::ALT
, 0);
3277 SendActivateStickyKeyPattern(ui::VKEY_LMENU
, ui::DomCode::ALT_LEFT
,
3278 ui::DomKey::ALT
, 0);
3279 EXPECT_TRUE(overlay_
->is_visible());
3280 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
3281 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
3283 // Pressing a normal key should not hide overlay.
3284 SendActivateStickyKeyPattern(ui::VKEY_D
, ui::DomCode::KEY_D
,
3285 ui::DomKey::CHARACTER
, 'd');
3286 EXPECT_TRUE(overlay_
->is_visible());
3287 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
3288 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
3291 TEST_F(StickyKeysOverlayTest
, LockedAndNormalModifier
) {
3292 EXPECT_FALSE(overlay_
->is_visible());
3293 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3294 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3295 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3296 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
3298 // Pressing a modifier key twice should lock modifier and show overlay.
3299 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
3300 ui::DomKey::CONTROL
, 0);
3301 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
3302 ui::DomKey::CONTROL
, 0);
3303 EXPECT_TRUE(overlay_
->is_visible());
3304 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
3305 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3307 // Pressing another modifier key should still show overlay.
3308 SendActivateStickyKeyPattern(ui::VKEY_SHIFT
, ui::DomCode::SHIFT_LEFT
,
3309 ui::DomKey::SHIFT
, 0);
3310 EXPECT_TRUE(overlay_
->is_visible());
3311 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
3312 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3313 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
3314 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
3316 // Pressing a normal key should not hide overlay but disable normal modifier.
3317 SendActivateStickyKeyPattern(ui::VKEY_D
, ui::DomCode::KEY_D
,
3318 ui::DomKey::CHARACTER
, 'd');
3319 EXPECT_TRUE(overlay_
->is_visible());
3320 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
3321 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3322 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3323 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
3326 TEST_F(StickyKeysOverlayTest
, ModifiersDisabled
) {
3327 EXPECT_FALSE(overlay_
->is_visible());
3328 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3329 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3330 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3331 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
3332 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3333 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
3334 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3335 overlay_
->GetModifierKeyState(ui::EF_COMMAND_DOWN
));
3337 // Enable modifiers.
3338 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
3339 ui::DomKey::CONTROL
, 0);
3340 SendActivateStickyKeyPattern(ui::VKEY_SHIFT
, ui::DomCode::SHIFT_LEFT
,
3341 ui::DomKey::SHIFT
, 0);
3342 SendActivateStickyKeyPattern(ui::VKEY_SHIFT
, ui::DomCode::SHIFT_LEFT
,
3343 ui::DomKey::SHIFT
, 0);
3344 SendActivateStickyKeyPattern(ui::VKEY_LMENU
, ui::DomCode::ALT_LEFT
,
3345 ui::DomKey::ALT
, 0);
3346 SendActivateStickyKeyPattern(ui::VKEY_COMMAND
, ui::DomCode::OS_LEFT
,
3348 SendActivateStickyKeyPattern(ui::VKEY_COMMAND
, ui::DomCode::OS_LEFT
,
3351 EXPECT_TRUE(overlay_
->is_visible());
3352 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
3353 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3354 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
3355 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
3356 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
3357 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
3358 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
3359 overlay_
->GetModifierKeyState(ui::EF_COMMAND_DOWN
));
3361 // Disable modifiers and overlay should be hidden.
3362 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
3363 ui::DomKey::CONTROL
, 0);
3364 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
, ui::DomCode::CONTROL_LEFT
,
3365 ui::DomKey::CONTROL
, 0);
3366 SendActivateStickyKeyPattern(ui::VKEY_SHIFT
, ui::DomCode::SHIFT_LEFT
,
3367 ui::DomKey::SHIFT
, 0);
3368 SendActivateStickyKeyPattern(ui::VKEY_LMENU
, ui::DomCode::ALT_LEFT
,
3369 ui::DomKey::ALT
, 0);
3370 SendActivateStickyKeyPattern(ui::VKEY_LMENU
, ui::DomCode::ALT_LEFT
,
3371 ui::DomKey::ALT
, 0);
3372 SendActivateStickyKeyPattern(ui::VKEY_COMMAND
, ui::DomCode::OS_LEFT
,
3375 EXPECT_FALSE(overlay_
->is_visible());
3376 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3377 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
3378 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3379 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
3380 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3381 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
3382 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
3383 overlay_
->GetModifierKeyState(ui::EF_COMMAND_DOWN
));
3386 TEST_F(StickyKeysOverlayTest
, ModifierVisibility
) {
3387 // All but AltGr and Mod3 should initially be visible.
3388 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_CONTROL_DOWN
));
3389 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_SHIFT_DOWN
));
3390 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_ALT_DOWN
));
3391 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_COMMAND_DOWN
));
3392 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_ALTGR_DOWN
));
3393 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_MOD3_DOWN
));
3395 // Turn all modifiers on.
3396 sticky_keys_controller_
->SetModifiersEnabled(true, true);
3397 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_CONTROL_DOWN
));
3398 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_SHIFT_DOWN
));
3399 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_ALT_DOWN
));
3400 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_COMMAND_DOWN
));
3401 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_ALTGR_DOWN
));
3402 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_MOD3_DOWN
));
3405 sticky_keys_controller_
->SetModifiersEnabled(false, true);
3406 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_ALTGR_DOWN
));
3407 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_MOD3_DOWN
));
3410 sticky_keys_controller_
->SetModifiersEnabled(true, false);
3411 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_ALTGR_DOWN
));
3412 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_MOD3_DOWN
));
3414 // Turn off AltGr and Mod3.
3415 sticky_keys_controller_
->SetModifiersEnabled(false, false);
3416 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_ALTGR_DOWN
));
3417 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_MOD3_DOWN
));
3420 } // namespace chromeos