1 // Copyright (c) 2012 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/ui/ash/event_rewriter.h"
7 #include "base/basictypes.h"
8 #include "base/command_line.h"
9 #include "base/prefs/pref_member.h"
10 #include "base/strings/stringprintf.h"
11 #include "chrome/common/pref_names.h"
12 #include "chrome/test/base/testing_pref_service_syncable.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "ui/events/event.h"
16 #if defined(OS_CHROMEOS)
17 #include <X11/keysym.h>
18 #include <X11/XF86keysym.h>
21 #include "ash/test/ash_test_base.h"
22 #include "ash/wm/window_state.h"
23 #include "chrome/browser/chromeos/input_method/input_method_configuration.h"
24 #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h"
25 #include "chrome/browser/chromeos/login/mock_user_manager.h"
26 #include "chrome/browser/chromeos/login/user_manager.h"
27 #include "chrome/browser/chromeos/preferences.h"
28 #include "chromeos/chromeos_switches.h"
29 #include "chromeos/ime/mock_xkeyboard.h"
30 #include "ui/aura/window.h"
31 #include "ui/events/test/events_test_utils_x11.h"
32 #include "ui/gfx/x/x11_types.h"
36 std::string
GetRewrittenEventAsString(EventRewriter
* rewriter
,
37 ui::KeyboardCode ui_keycode
,
39 ui::EventType ui_type
,
41 unsigned int x_state
) {
42 ui::ScopedXI2Event xev
;
43 xev
.InitKeyEvent(ui_type
, ui_keycode
, ui_flags
);
45 xevent
->xkey
.keycode
= x_keycode
;
46 xevent
->xkey
.state
= x_state
;
47 ui::KeyEvent
keyevent(xev
, false /* is_char */);
48 rewriter
->RewriteForTesting(&keyevent
);
49 return base::StringPrintf(
50 "ui_keycode=%d ui_flags=%d ui_type=%d x_keycode=%u x_state=%u x_type=%d",
51 keyevent
.key_code(), keyevent
.flags(), keyevent
.type(),
52 xevent
->xkey
.keycode
, xevent
->xkey
.state
, xevent
->xkey
.type
);
55 std::string
GetExpectedResultAsString(ui::KeyboardCode ui_keycode
,
57 ui::EventType ui_type
,
61 return base::StringPrintf(
62 "ui_keycode=%d ui_flags=%d ui_type=%d x_keycode=%u x_state=%u x_type=%d",
63 ui_keycode
, ui_flags
, ui_type
, x_keycode
, x_state
, x_type
);
66 class EventRewriterTest
: public testing::Test
{
69 : display_(gfx::GetXDisplay()),
70 keycode_a_(XKeysymToKeycode(display_
, XK_a
)),
71 keycode_alt_l_(XKeysymToKeycode(display_
, XK_Alt_L
)),
72 keycode_alt_r_(XKeysymToKeycode(display_
, XK_Alt_R
)),
73 keycode_b_(XKeysymToKeycode(display_
, XK_B
)),
74 keycode_caps_lock_(XKeysymToKeycode(display_
, XK_Caps_Lock
)),
75 keycode_control_l_(XKeysymToKeycode(display_
, XK_Control_L
)),
76 keycode_control_r_(XKeysymToKeycode(display_
, XK_Control_R
)),
77 keycode_meta_l_(XKeysymToKeycode(display_
, XK_Meta_L
)),
78 keycode_meta_r_(XKeysymToKeycode(display_
, XK_Meta_R
)),
79 keycode_num_pad_0_(XKeysymToKeycode(display_
, XK_KP_0
)),
80 keycode_num_pad_1_(XKeysymToKeycode(display_
, XK_KP_1
)),
81 keycode_num_pad_2_(XKeysymToKeycode(display_
, XK_KP_2
)),
82 keycode_num_pad_3_(XKeysymToKeycode(display_
, XK_KP_3
)),
83 keycode_num_pad_4_(XKeysymToKeycode(display_
, XK_KP_4
)),
84 keycode_num_pad_5_(XKeysymToKeycode(display_
, XK_KP_5
)),
85 keycode_num_pad_6_(XKeysymToKeycode(display_
, XK_KP_6
)),
86 keycode_num_pad_7_(XKeysymToKeycode(display_
, XK_KP_7
)),
87 keycode_num_pad_8_(XKeysymToKeycode(display_
, XK_KP_8
)),
88 keycode_num_pad_9_(XKeysymToKeycode(display_
, XK_KP_9
)),
89 keycode_num_pad_begin_(XKeysymToKeycode(display_
, XK_KP_Begin
)),
90 keycode_num_pad_decimal_(XKeysymToKeycode(display_
, XK_KP_Decimal
)),
91 keycode_num_pad_delete_(XKeysymToKeycode(display_
, XK_KP_Delete
)),
92 keycode_num_pad_down_(XKeysymToKeycode(display_
, XK_KP_Down
)),
93 keycode_num_pad_end_(XKeysymToKeycode(display_
, XK_KP_End
)),
94 keycode_num_pad_home_(XKeysymToKeycode(display_
, XK_KP_Home
)),
95 keycode_num_pad_insert_(XKeysymToKeycode(display_
, XK_KP_Insert
)),
96 keycode_num_pad_left_(XKeysymToKeycode(display_
, XK_KP_Left
)),
97 keycode_num_pad_next_(XKeysymToKeycode(display_
, XK_KP_Next
)),
98 keycode_num_pad_prior_(XKeysymToKeycode(display_
, XK_KP_Prior
)),
99 keycode_num_pad_right_(XKeysymToKeycode(display_
, XK_KP_Right
)),
100 keycode_num_pad_up_(XKeysymToKeycode(display_
, XK_KP_Up
)),
101 keycode_super_l_(XKeysymToKeycode(display_
, XK_Super_L
)),
102 keycode_super_r_(XKeysymToKeycode(display_
, XK_Super_R
)),
103 keycode_void_symbol_(XKeysymToKeycode(display_
, XK_VoidSymbol
)),
104 keycode_delete_(XKeysymToKeycode(display_
, XK_Delete
)),
105 keycode_backspace_(XKeysymToKeycode(display_
, XK_BackSpace
)),
106 keycode_up_(XKeysymToKeycode(display_
, XK_Up
)),
107 keycode_down_(XKeysymToKeycode(display_
, XK_Down
)),
108 keycode_left_(XKeysymToKeycode(display_
, XK_Left
)),
109 keycode_right_(XKeysymToKeycode(display_
, XK_Right
)),
110 keycode_prior_(XKeysymToKeycode(display_
, XK_Prior
)),
111 keycode_next_(XKeysymToKeycode(display_
, XK_Next
)),
112 keycode_home_(XKeysymToKeycode(display_
, XK_Home
)),
113 keycode_end_(XKeysymToKeycode(display_
, XK_End
)),
114 keycode_escape_(XKeysymToKeycode(display_
, XK_Escape
)),
115 keycode_launch6_(XKeysymToKeycode(display_
, XF86XK_Launch6
)),
116 keycode_launch7_(XKeysymToKeycode(display_
, XF86XK_Launch7
)),
117 keycode_f1_(XKeysymToKeycode(display_
, XK_F1
)),
118 keycode_f2_(XKeysymToKeycode(display_
, XK_F2
)),
119 keycode_f3_(XKeysymToKeycode(display_
, XK_F3
)),
120 keycode_f4_(XKeysymToKeycode(display_
, XK_F4
)),
121 keycode_f5_(XKeysymToKeycode(display_
, XK_F5
)),
122 keycode_f6_(XKeysymToKeycode(display_
, XK_F6
)),
123 keycode_f7_(XKeysymToKeycode(display_
, XK_F7
)),
124 keycode_f8_(XKeysymToKeycode(display_
, XK_F8
)),
125 keycode_f9_(XKeysymToKeycode(display_
, XK_F9
)),
126 keycode_f10_(XKeysymToKeycode(display_
, XK_F10
)),
127 keycode_f11_(XKeysymToKeycode(display_
, XK_F11
)),
128 keycode_f12_(XKeysymToKeycode(display_
, XK_F12
)),
129 keycode_browser_back_(XKeysymToKeycode(display_
, XF86XK_Back
)),
130 keycode_browser_forward_(XKeysymToKeycode(display_
, XF86XK_Forward
)),
131 keycode_browser_refresh_(XKeysymToKeycode(display_
, XF86XK_Reload
)),
132 keycode_media_launch_app1_(XKeysymToKeycode(display_
, XF86XK_LaunchA
)),
133 keycode_media_launch_app2_(XKeysymToKeycode(display_
, XF86XK_LaunchB
)),
134 keycode_brightness_down_(XKeysymToKeycode(
135 display_
, XF86XK_MonBrightnessDown
)),
136 keycode_brightness_up_(XKeysymToKeycode(
137 display_
, XF86XK_MonBrightnessUp
)),
138 keycode_volume_mute_(XKeysymToKeycode(display_
, XF86XK_AudioMute
)),
139 keycode_volume_down_(XKeysymToKeycode(
140 display_
, XF86XK_AudioLowerVolume
)),
141 keycode_volume_up_(XKeysymToKeycode(
142 display_
, XF86XK_AudioRaiseVolume
)),
143 keycode_power_(XKeysymToKeycode(display_
, XF86XK_PowerOff
)),
144 keycode_1_(XKeysymToKeycode(display_
, XK_1
)),
145 keycode_2_(XKeysymToKeycode(display_
, XK_2
)),
146 keycode_3_(XKeysymToKeycode(display_
, XK_3
)),
147 keycode_4_(XKeysymToKeycode(display_
, XK_4
)),
148 keycode_5_(XKeysymToKeycode(display_
, XK_5
)),
149 keycode_6_(XKeysymToKeycode(display_
, XK_6
)),
150 keycode_7_(XKeysymToKeycode(display_
, XK_7
)),
151 keycode_8_(XKeysymToKeycode(display_
, XK_8
)),
152 keycode_9_(XKeysymToKeycode(display_
, XK_9
)),
153 keycode_0_(XKeysymToKeycode(display_
, XK_0
)),
154 keycode_minus_(XKeysymToKeycode(display_
, XK_minus
)),
155 keycode_equal_(XKeysymToKeycode(display_
, XK_equal
)),
156 keycode_period_(XKeysymToKeycode(display_
, XK_period
)),
157 keycode_insert_(XKeysymToKeycode(display_
, XK_Insert
)),
158 mock_user_manager_(new chromeos::MockUserManager
),
159 user_manager_enabler_(mock_user_manager_
),
160 input_method_manager_mock_(NULL
) {
162 virtual ~EventRewriterTest() {}
164 virtual void SetUp() {
165 // Mocking user manager because the real one needs to be called on UI thread
166 EXPECT_CALL(*mock_user_manager_
, IsLoggedInAsGuest())
167 .WillRepeatedly(testing::Return(false));
168 input_method_manager_mock_
=
169 new chromeos::input_method::MockInputMethodManager
;
170 chromeos::input_method::InitializeForTesting(
171 input_method_manager_mock_
); // pass ownership
174 virtual void TearDown() {
175 // Shutdown() deletes the IME mock object.
176 chromeos::input_method::Shutdown();
180 void TestRewriteNumPadKeys();
181 void TestRewriteNumPadKeysOnAppleKeyboard();
184 const KeyCode keycode_a_
;
185 const KeyCode keycode_alt_l_
;
186 const KeyCode keycode_alt_r_
;
187 const KeyCode keycode_b_
;
188 const KeyCode keycode_caps_lock_
;
189 const KeyCode keycode_control_l_
;
190 const KeyCode keycode_control_r_
;
191 const KeyCode keycode_meta_l_
;
192 const KeyCode keycode_meta_r_
;
193 const KeyCode keycode_num_pad_0_
;
194 const KeyCode keycode_num_pad_1_
;
195 const KeyCode keycode_num_pad_2_
;
196 const KeyCode keycode_num_pad_3_
;
197 const KeyCode keycode_num_pad_4_
;
198 const KeyCode keycode_num_pad_5_
;
199 const KeyCode keycode_num_pad_6_
;
200 const KeyCode keycode_num_pad_7_
;
201 const KeyCode keycode_num_pad_8_
;
202 const KeyCode keycode_num_pad_9_
;
203 const KeyCode keycode_num_pad_begin_
;
204 const KeyCode keycode_num_pad_decimal_
;
205 const KeyCode keycode_num_pad_delete_
;
206 const KeyCode keycode_num_pad_down_
;
207 const KeyCode keycode_num_pad_end_
;
208 const KeyCode keycode_num_pad_home_
;
209 const KeyCode keycode_num_pad_insert_
;
210 const KeyCode keycode_num_pad_left_
;
211 const KeyCode keycode_num_pad_next_
;
212 const KeyCode keycode_num_pad_prior_
;
213 const KeyCode keycode_num_pad_right_
;
214 const KeyCode keycode_num_pad_up_
;
215 const KeyCode keycode_super_l_
;
216 const KeyCode keycode_super_r_
;
217 const KeyCode keycode_void_symbol_
;
218 const KeyCode keycode_delete_
;
219 const KeyCode keycode_backspace_
;
220 const KeyCode keycode_up_
;
221 const KeyCode keycode_down_
;
222 const KeyCode keycode_left_
;
223 const KeyCode keycode_right_
;
224 const KeyCode keycode_prior_
;
225 const KeyCode keycode_next_
;
226 const KeyCode keycode_home_
;
227 const KeyCode keycode_end_
;
228 const KeyCode keycode_escape_
;
229 const KeyCode keycode_launch6_
; // F15
230 const KeyCode keycode_launch7_
; // F16
231 const KeyCode keycode_f1_
;
232 const KeyCode keycode_f2_
;
233 const KeyCode keycode_f3_
;
234 const KeyCode keycode_f4_
;
235 const KeyCode keycode_f5_
;
236 const KeyCode keycode_f6_
;
237 const KeyCode keycode_f7_
;
238 const KeyCode keycode_f8_
;
239 const KeyCode keycode_f9_
;
240 const KeyCode keycode_f10_
;
241 const KeyCode keycode_f11_
;
242 const KeyCode keycode_f12_
;
243 const KeyCode keycode_browser_back_
;
244 const KeyCode keycode_browser_forward_
;
245 const KeyCode keycode_browser_refresh_
;
246 const KeyCode keycode_media_launch_app1_
;
247 const KeyCode keycode_media_launch_app2_
;
248 const KeyCode keycode_brightness_down_
;
249 const KeyCode keycode_brightness_up_
;
250 const KeyCode keycode_volume_mute_
;
251 const KeyCode keycode_volume_down_
;
252 const KeyCode keycode_volume_up_
;
253 const KeyCode keycode_power_
;
254 const KeyCode keycode_1_
;
255 const KeyCode keycode_2_
;
256 const KeyCode keycode_3_
;
257 const KeyCode keycode_4_
;
258 const KeyCode keycode_5_
;
259 const KeyCode keycode_6_
;
260 const KeyCode keycode_7_
;
261 const KeyCode keycode_8_
;
262 const KeyCode keycode_9_
;
263 const KeyCode keycode_0_
;
264 const KeyCode keycode_minus_
;
265 const KeyCode keycode_equal_
;
266 const KeyCode keycode_period_
;
267 const KeyCode keycode_insert_
;
268 chromeos::MockUserManager
* mock_user_manager_
; // Not owned.
269 chromeos::ScopedUserManagerEnabler user_manager_enabler_
;
270 chromeos::input_method::MockInputMethodManager
* input_method_manager_mock_
;
275 class EventRewriterTest
: public testing::Test
{
277 EventRewriterTest() {}
278 virtual ~EventRewriterTest() {}
282 TEST_F(EventRewriterTest
, TestGetDeviceType
) {
283 // This is the typical string which an Apple keyboard sends.
284 EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard
,
285 EventRewriter::GetDeviceType("Apple Inc. Apple Keyboard"));
287 // Other cases we accept.
288 EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard
,
289 EventRewriter::GetDeviceType("Apple Keyboard"));
290 EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard
,
291 EventRewriter::GetDeviceType("apple keyboard"));
292 EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard
,
293 EventRewriter::GetDeviceType("apple keyboard."));
294 EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard
,
295 EventRewriter::GetDeviceType("apple.keyboard."));
296 EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard
,
297 EventRewriter::GetDeviceType(".apple.keyboard."));
299 // Dell, Microsoft, Logitech, ... should be recognized as a kDeviceUnknown.
300 EXPECT_EQ(EventRewriter::kDeviceUnknown
,
301 EventRewriter::GetDeviceType("Dell Dell USB Entry Keyboard"));
302 EXPECT_EQ(EventRewriter::kDeviceUnknown
,
303 EventRewriter::GetDeviceType(
304 "Microsoft Natural Ergonomic Keyboard"));
305 EXPECT_EQ(EventRewriter::kDeviceUnknown
,
306 EventRewriter::GetDeviceType("CHESEN USB Keyboard"));
308 // Some corner cases.
309 EXPECT_EQ(EventRewriter::kDeviceUnknown
, EventRewriter::GetDeviceType(""));
310 EXPECT_EQ(EventRewriter::kDeviceUnknown
,
311 EventRewriter::GetDeviceType("."));
312 EXPECT_EQ(EventRewriter::kDeviceUnknown
,
313 EventRewriter::GetDeviceType(". "));
314 EXPECT_EQ(EventRewriter::kDeviceUnknown
,
315 EventRewriter::GetDeviceType(" ."));
316 EXPECT_EQ(EventRewriter::kDeviceUnknown
,
317 EventRewriter::GetDeviceType("not-an-apple keyboard"));
320 TEST_F(EventRewriterTest
, TestDeviceAddedOrRemoved
) {
321 EventRewriter rewriter
;
322 EXPECT_TRUE(rewriter
.device_id_to_type_for_testing().empty());
323 EXPECT_EQ(EventRewriter::kDeviceUnknown
,
324 rewriter
.DeviceAddedForTesting(0, "PC Keyboard"));
325 EXPECT_EQ(1U, rewriter
.device_id_to_type_for_testing().size());
326 EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard
,
327 rewriter
.DeviceAddedForTesting(1, "Apple Keyboard"));
328 EXPECT_EQ(2U, rewriter
.device_id_to_type_for_testing().size());
329 // Try to reuse the first ID.
330 EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard
,
331 rewriter
.DeviceAddedForTesting(0, "Apple Keyboard"));
332 EXPECT_EQ(2U, rewriter
.device_id_to_type_for_testing().size());
335 #if defined(OS_CHROMEOS)
336 TEST_F(EventRewriterTest
, TestRewriteCommandToControl
) {
337 // First, test with a PC keyboard.
338 TestingPrefServiceSyncable prefs
;
339 EventRewriter rewriter
;
340 rewriter
.DeviceAddedForTesting(0, "PC Keyboard");
341 rewriter
.set_last_device_id_for_testing(0);
342 rewriter
.set_pref_service_for_testing(&prefs
);
344 // XK_a, Alt modifier.
345 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A
,
351 GetRewrittenEventAsString(&rewriter
,
358 // XK_a, Win modifier.
359 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A
,
365 GetRewrittenEventAsString(&rewriter
,
372 // XK_a, Alt+Win modifier.
373 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A
,
379 GetRewrittenEventAsString(&rewriter
,
384 Mod1Mask
| Mod4Mask
));
386 // XK_Super_L (left Windows key), Alt modifier.
387 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN
,
393 GetRewrittenEventAsString(&rewriter
,
400 // XK_Super_R (right Windows key), Alt modifier.
401 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_RWIN
,
407 GetRewrittenEventAsString(&rewriter
,
414 // An Apple keyboard reusing the ID, zero.
415 rewriter
.DeviceAddedForTesting(0, "Apple Keyboard");
416 rewriter
.set_last_device_id_for_testing(0);
418 // XK_a, Alt modifier.
419 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A
,
425 GetRewrittenEventAsString(&rewriter
,
432 // XK_a, Win modifier.
433 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A
,
439 GetRewrittenEventAsString(&rewriter
,
446 // XK_a, Alt+Win modifier.
447 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A
,
448 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
451 Mod1Mask
| ControlMask
,
453 GetRewrittenEventAsString(&rewriter
,
458 Mod1Mask
| Mod4Mask
));
460 // XK_Super_L (left Windows key), Alt modifier.
461 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL
,
462 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
467 GetRewrittenEventAsString(&rewriter
,
474 // XK_Super_R (right Windows key), Alt modifier.
475 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL
,
476 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
481 GetRewrittenEventAsString(&rewriter
,
489 // For crbug.com/133896.
490 TEST_F(EventRewriterTest
, TestRewriteCommandToControlWithControlRemapped
) {
491 // Remap Control to Alt.
492 TestingPrefServiceSyncable prefs
;
493 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
494 IntegerPrefMember control
;
495 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
496 control
.SetValue(chromeos::input_method::kAltKey
);
498 EventRewriter rewriter
;
499 rewriter
.set_pref_service_for_testing(&prefs
);
500 rewriter
.DeviceAddedForTesting(0, "PC Keyboard");
501 rewriter
.set_last_device_id_for_testing(0);
503 // XK_Control_L (left Control key) should be remapped to Alt.
504 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU
,
510 GetRewrittenEventAsString(&rewriter
,
517 // An Apple keyboard reusing the ID, zero.
518 rewriter
.DeviceAddedForTesting(0, "Apple Keyboard");
519 rewriter
.set_last_device_id_for_testing(0);
521 // XK_Super_L (left Command key) with Alt modifier. The remapped Command key
522 // should never be re-remapped to Alt.
523 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL
,
524 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
529 GetRewrittenEventAsString(&rewriter
,
536 // XK_Super_R (right Command key) with Alt modifier. The remapped Command key
537 // should never be re-remapped to Alt.
538 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL
,
539 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
544 GetRewrittenEventAsString(&rewriter
,
552 void EventRewriterTest::TestRewriteNumPadKeys() {
553 TestingPrefServiceSyncable prefs
;
554 EventRewriter rewriter
;
555 rewriter
.set_pref_service_for_testing(&prefs
);
557 // XK_KP_Insert (= NumPad 0 without Num Lock), no modifier.
558 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD0
,
562 Mod2Mask
, // Num Lock
564 GetRewrittenEventAsString(&rewriter
,
568 keycode_num_pad_insert_
,
571 // XK_KP_Insert (= NumPad 0 without Num Lock), Alt modifier.
572 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD0
,
578 GetRewrittenEventAsString(&rewriter
,
582 keycode_num_pad_insert_
,
585 // XK_KP_Delete (= NumPad . without Num Lock), Alt modifier.
586 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_DECIMAL
,
589 keycode_num_pad_decimal_
,
592 GetRewrittenEventAsString(&rewriter
,
596 keycode_num_pad_delete_
,
599 // XK_KP_End (= NumPad 1 without Num Lock), Alt modifier.
600 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD1
,
606 GetRewrittenEventAsString(&rewriter
,
610 keycode_num_pad_end_
,
613 // XK_KP_Down (= NumPad 2 without Num Lock), Alt modifier.
614 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD2
,
620 GetRewrittenEventAsString(&rewriter
,
624 keycode_num_pad_down_
,
627 // XK_KP_Next (= NumPad 3 without Num Lock), Alt modifier.
628 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD3
,
634 GetRewrittenEventAsString(&rewriter
,
638 keycode_num_pad_next_
,
641 // XK_KP_Left (= NumPad 4 without Num Lock), Alt modifier.
642 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD4
,
648 GetRewrittenEventAsString(&rewriter
,
652 keycode_num_pad_left_
,
655 // XK_KP_Begin (= NumPad 5 without Num Lock), Alt modifier.
656 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD5
,
662 GetRewrittenEventAsString(&rewriter
,
666 keycode_num_pad_begin_
,
669 // XK_KP_Right (= NumPad 6 without Num Lock), Alt modifier.
670 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD6
,
676 GetRewrittenEventAsString(&rewriter
,
680 keycode_num_pad_right_
,
683 // XK_KP_Home (= NumPad 7 without Num Lock), Alt modifier.
684 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD7
,
690 GetRewrittenEventAsString(&rewriter
,
694 keycode_num_pad_home_
,
697 // XK_KP_Up (= NumPad 8 without Num Lock), Alt modifier.
698 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD8
,
704 GetRewrittenEventAsString(&rewriter
,
711 // XK_KP_Prior (= NumPad 9 without Num Lock), Alt modifier.
712 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD9
,
718 GetRewrittenEventAsString(&rewriter
,
722 keycode_num_pad_prior_
,
725 // XK_KP_0 (= NumPad 0 with Num Lock), Num Lock modifier.
726 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD0
,
732 GetRewrittenEventAsString(&rewriter
,
739 // XK_KP_DECIMAL (= NumPad . with Num Lock), Num Lock modifier.
740 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_DECIMAL
,
743 keycode_num_pad_decimal_
,
746 GetRewrittenEventAsString(&rewriter
,
750 keycode_num_pad_decimal_
,
753 // XK_KP_1 (= NumPad 1 with Num Lock), Num Lock modifier.
754 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD1
,
760 GetRewrittenEventAsString(&rewriter
,
767 // XK_KP_2 (= NumPad 2 with Num Lock), Num Lock modifier.
768 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD2
,
774 GetRewrittenEventAsString(&rewriter
,
781 // XK_KP_3 (= NumPad 3 with Num Lock), Num Lock modifier.
782 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD3
,
788 GetRewrittenEventAsString(&rewriter
,
795 // XK_KP_4 (= NumPad 4 with Num Lock), Num Lock modifier.
796 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD4
,
802 GetRewrittenEventAsString(&rewriter
,
809 // XK_KP_5 (= NumPad 5 with Num Lock), Num Lock modifier.
810 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD5
,
816 GetRewrittenEventAsString(&rewriter
,
823 // XK_KP_6 (= NumPad 6 with Num Lock), Num Lock modifier.
824 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD6
,
830 GetRewrittenEventAsString(&rewriter
,
837 // XK_KP_7 (= NumPad 7 with Num Lock), Num Lock modifier.
838 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD7
,
844 GetRewrittenEventAsString(&rewriter
,
851 // XK_KP_8 (= NumPad 8 with Num Lock), Num Lock modifier.
852 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD8
,
858 GetRewrittenEventAsString(&rewriter
,
865 // XK_KP_9 (= NumPad 9 with Num Lock), Num Lock modifier.
866 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD9
,
872 GetRewrittenEventAsString(&rewriter
,
880 TEST_F(EventRewriterTest
, TestRewriteNumPadKeys
) {
881 TestRewriteNumPadKeys();
884 TEST_F(EventRewriterTest
, TestRewriteNumPadKeysWithDiamondKeyFlag
) {
885 // Make sure the num lock works correctly even when Diamond key exists.
886 const CommandLine
original_cl(*CommandLine::ForCurrentProcess());
887 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
888 chromeos::switches::kHasChromeOSDiamondKey
, "");
890 TestRewriteNumPadKeys();
891 *CommandLine::ForCurrentProcess() = original_cl
;
894 // Tests if the rewriter can handle a Command + Num Pad event.
895 void EventRewriterTest::TestRewriteNumPadKeysOnAppleKeyboard() {
896 TestingPrefServiceSyncable prefs
;
897 EventRewriter rewriter
;
898 rewriter
.DeviceAddedForTesting(0, "Apple Keyboard");
899 rewriter
.set_last_device_id_for_testing(0);
900 rewriter
.set_pref_service_for_testing(&prefs
);
902 // XK_KP_End (= NumPad 1 without Num Lock), Win modifier.
903 // The result should be "Num Pad 1 with Control + Num Lock modifiers".
904 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD1
,
908 ControlMask
| Mod2Mask
,
910 GetRewrittenEventAsString(&rewriter
,
914 keycode_num_pad_end_
,
917 // XK_KP_1 (= NumPad 1 without Num Lock), Win modifier.
918 // The result should also be "Num Pad 1 with Control + Num Lock modifiers".
919 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD1
,
923 ControlMask
| Mod2Mask
,
925 GetRewrittenEventAsString(&rewriter
,
929 keycode_num_pad_end_
,
933 TEST_F(EventRewriterTest
, TestRewriteNumPadKeysOnAppleKeyboard
) {
934 TestRewriteNumPadKeysOnAppleKeyboard();
937 TEST_F(EventRewriterTest
,
938 TestRewriteNumPadKeysOnAppleKeyboardWithDiamondKeyFlag
) {
939 // Makes sure the num lock works correctly even when Diamond key exists.
940 const CommandLine
original_cl(*CommandLine::ForCurrentProcess());
941 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
942 chromeos::switches::kHasChromeOSDiamondKey
, "");
944 TestRewriteNumPadKeysOnAppleKeyboard();
945 *CommandLine::ForCurrentProcess() = original_cl
;
948 TEST_F(EventRewriterTest
, TestRewriteModifiersNoRemap
) {
949 TestingPrefServiceSyncable prefs
;
950 EventRewriter rewriter
;
951 rewriter
.set_pref_service_for_testing(&prefs
);
953 // Press Search. Confirm the event is not rewritten.
954 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN
,
960 GetRewrittenEventAsString(&rewriter
,
967 // Press left Control. Confirm the event is not rewritten.
968 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL
,
974 GetRewrittenEventAsString(&rewriter
,
981 // Press right Control. Confirm the event is not rewritten.
982 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL
,
988 GetRewrittenEventAsString(&rewriter
,
995 // Press left Alt. Confirm the event is not rewritten.
996 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU
,
1002 GetRewrittenEventAsString(&rewriter
,
1009 // Press right Alt. Confirm the event is not rewritten.
1010 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU
,
1016 GetRewrittenEventAsString(&rewriter
,
1023 // Test KeyRelease event, just in case.
1024 // Release Search. Confirm the release event is not rewritten.
1025 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN
,
1027 ui::ET_KEY_RELEASED
,
1031 GetRewrittenEventAsString(&rewriter
,
1034 ui::ET_KEY_RELEASED
,
1039 TEST_F(EventRewriterTest
, TestRewriteModifiersNoRemapMultipleKeys
) {
1040 TestingPrefServiceSyncable prefs
;
1041 EventRewriter rewriter
;
1042 rewriter
.set_pref_service_for_testing(&prefs
);
1044 // Press left Alt with Shift. Confirm the event is not rewritten.
1045 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU
,
1046 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
,
1051 GetRewrittenEventAsString(&rewriter
,
1058 // Press right Alt with Shift. Confirm the event is not rewritten.
1059 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU
,
1060 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
,
1065 GetRewrittenEventAsString(&rewriter
,
1072 // Press Search with Caps Lock mask. Confirm the event is not rewritten.
1073 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN
,
1074 ui::EF_CAPS_LOCK_DOWN
,
1079 GetRewrittenEventAsString(&rewriter
,
1081 ui::EF_CAPS_LOCK_DOWN
,
1086 // Release Search with Caps Lock mask. Confirm the event is not rewritten.
1087 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN
,
1088 ui::EF_CAPS_LOCK_DOWN
,
1089 ui::ET_KEY_RELEASED
,
1091 LockMask
| Mod4Mask
,
1093 GetRewrittenEventAsString(&rewriter
,
1095 ui::EF_CAPS_LOCK_DOWN
,
1096 ui::ET_KEY_RELEASED
,
1098 LockMask
| Mod4Mask
));
1100 // Press Shift+Ctrl+Alt+Search+A. Confirm the event is not rewritten.
1101 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_B
,
1103 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
1106 ShiftMask
| ControlMask
| Mod1Mask
|
1109 GetRewrittenEventAsString(&rewriter
,
1112 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
1115 ShiftMask
| ControlMask
| Mod1Mask
|
1119 TEST_F(EventRewriterTest
, TestRewriteModifiersDisableSome
) {
1120 // Disable Search and Control keys.
1121 TestingPrefServiceSyncable prefs
;
1122 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1123 IntegerPrefMember search
;
1124 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
1125 search
.SetValue(chromeos::input_method::kVoidKey
);
1126 IntegerPrefMember control
;
1127 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
1128 control
.SetValue(chromeos::input_method::kVoidKey
);
1130 EventRewriter rewriter
;
1131 rewriter
.set_pref_service_for_testing(&prefs
);
1133 // Press left Alt with Shift. This key press shouldn't be affected by the
1134 // pref. Confirm the event is not rewritten.
1135 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU
,
1136 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
,
1141 GetRewrittenEventAsString(&rewriter
,
1148 // Press Search. Confirm the event is now VKEY_UNKNOWN + XK_VoidSymbol.
1149 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_UNKNOWN
,
1152 keycode_void_symbol_
,
1155 GetRewrittenEventAsString(&rewriter
,
1162 // Press Control. Confirm the event is now VKEY_UNKNOWN + XK_VoidSymbol.
1163 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_UNKNOWN
,
1166 keycode_void_symbol_
,
1169 GetRewrittenEventAsString(&rewriter
,
1176 // Press Control+Search. Confirm the event is now VKEY_UNKNOWN +
1177 // XK_VoidSymbol without any modifiers.
1178 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_UNKNOWN
,
1181 keycode_void_symbol_
,
1184 GetRewrittenEventAsString(&rewriter
,
1186 ui::EF_CONTROL_DOWN
,
1191 // Press Control+Search+a. Confirm the event is now VKEY_A without any
1193 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A
,
1199 GetRewrittenEventAsString(&rewriter
,
1201 ui::EF_CONTROL_DOWN
,
1204 ControlMask
| Mod4Mask
));
1206 // Press Control+Search+Alt+a. Confirm the event is now VKEY_A only with
1207 // the Alt modifier.
1208 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A
,
1214 GetRewrittenEventAsString(&rewriter
,
1216 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
1219 ControlMask
| Mod1Mask
| Mod4Mask
));
1221 // Remap Alt to Control.
1222 IntegerPrefMember alt
;
1223 alt
.Init(prefs::kLanguageRemapAltKeyTo
, &prefs
);
1224 alt
.SetValue(chromeos::input_method::kControlKey
);
1226 // Press left Alt. Confirm the event is now VKEY_CONTROL + XK_Control_L
1227 // even though the Control key itself is disabled.
1228 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL
,
1229 ui::EF_CONTROL_DOWN
,
1234 GetRewrittenEventAsString(&rewriter
,
1241 // Press Alt+a. Confirm the event is now Control+a even though the Control
1242 // key itself is disabled.
1243 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A
,
1244 ui::EF_CONTROL_DOWN
,
1249 GetRewrittenEventAsString(&rewriter
,
1257 TEST_F(EventRewriterTest
, TestRewriteModifiersRemapToControl
) {
1258 // Remap Search to Control.
1259 TestingPrefServiceSyncable prefs
;
1260 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1261 IntegerPrefMember search
;
1262 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
1263 search
.SetValue(chromeos::input_method::kControlKey
);
1265 EventRewriter rewriter
;
1266 rewriter
.set_pref_service_for_testing(&prefs
);
1268 // Press Search. Confirm the event is now VKEY_CONTROL + XK_Control_L.
1269 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL
,
1270 ui::EF_CONTROL_DOWN
,
1275 GetRewrittenEventAsString(&rewriter
,
1282 // Remap Alt to Control too.
1283 IntegerPrefMember alt
;
1284 alt
.Init(prefs::kLanguageRemapAltKeyTo
, &prefs
);
1285 alt
.SetValue(chromeos::input_method::kControlKey
);
1287 // Press left Alt. Confirm the event is now VKEY_CONTROL + XK_Control_L.
1288 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL
,
1289 ui::EF_CONTROL_DOWN
,
1294 GetRewrittenEventAsString(&rewriter
,
1301 // Press right Alt. Confirm the event is now VKEY_CONTROL + XK_Control_R.
1302 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL
,
1303 ui::EF_CONTROL_DOWN
,
1308 GetRewrittenEventAsString(&rewriter
,
1315 // Press Alt+Search. Confirm the event is now VKEY_CONTROL + XK_Control_L.
1316 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL
,
1317 ui::EF_CONTROL_DOWN
,
1322 GetRewrittenEventAsString(&rewriter
,
1329 // Press Control+Alt+Search. Confirm the event is now VKEY_CONTROL +
1331 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL
,
1332 ui::EF_CONTROL_DOWN
,
1337 GetRewrittenEventAsString(&rewriter
,
1339 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
1342 ControlMask
| Mod1Mask
));
1344 // Press Shift+Control+Alt+Search. Confirm the event is now Control with
1345 // Shift and Control modifiers.
1346 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL
,
1347 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
1350 ShiftMask
| ControlMask
,
1352 GetRewrittenEventAsString(&rewriter
,
1355 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
1358 ShiftMask
| ControlMask
| Mod1Mask
));
1360 // Press Shift+Control+Alt+Search+B. Confirm the event is now B with Shift
1361 // and Control modifiers.
1362 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_B
,
1363 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
,
1366 ShiftMask
| ControlMask
,
1368 GetRewrittenEventAsString(&rewriter
,
1371 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
1374 ShiftMask
| ControlMask
| Mod1Mask
));
1377 TEST_F(EventRewriterTest
, TestRewriteModifiersRemapToEscape
) {
1378 // Remap Search to ESC.
1379 TestingPrefServiceSyncable prefs
;
1380 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1381 IntegerPrefMember search
;
1382 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
1383 search
.SetValue(chromeos::input_method::kEscapeKey
);
1385 EventRewriter rewriter
;
1386 rewriter
.set_pref_service_for_testing(&prefs
);
1388 // Press Search. Confirm the event is now VKEY_ESCAPE.
1389 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_ESCAPE
,
1395 GetRewrittenEventAsString(&rewriter
,
1403 TEST_F(EventRewriterTest
, TestRewriteModifiersRemapMany
) {
1404 // Remap Search to Alt.
1405 TestingPrefServiceSyncable prefs
;
1406 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1407 IntegerPrefMember search
;
1408 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
1409 search
.SetValue(chromeos::input_method::kAltKey
);
1411 EventRewriter rewriter
;
1412 rewriter
.set_pref_service_for_testing(&prefs
);
1414 // Press Search. Confirm the event is now VKEY_MENU + XK_Alt_L.
1415 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU
,
1421 GetRewrittenEventAsString(&rewriter
,
1428 // Remap Alt to Control.
1429 IntegerPrefMember alt
;
1430 alt
.Init(prefs::kLanguageRemapAltKeyTo
, &prefs
);
1431 alt
.SetValue(chromeos::input_method::kControlKey
);
1433 // Press left Alt. Confirm the event is now VKEY_CONTROL + XK_Control_L.
1434 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL
,
1435 ui::EF_CONTROL_DOWN
,
1440 GetRewrittenEventAsString(&rewriter
,
1447 // Remap Control to Search.
1448 IntegerPrefMember control
;
1449 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
1450 control
.SetValue(chromeos::input_method::kSearchKey
);
1452 // Press left Control. Confirm the event is now VKEY_LWIN.
1453 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN
,
1459 GetRewrittenEventAsString(&rewriter
,
1466 // Then, press all of the three, Control+Alt+Search.
1467 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU
,
1468 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
1471 ControlMask
| Mod4Mask
,
1473 GetRewrittenEventAsString(&rewriter
,
1475 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
1478 ControlMask
| Mod1Mask
));
1480 // Press Shift+Control+Alt+Search.
1481 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU
,
1482 (ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
|
1486 ShiftMask
| ControlMask
| Mod4Mask
,
1488 GetRewrittenEventAsString(&rewriter
,
1491 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
1494 ShiftMask
| ControlMask
| Mod1Mask
));
1496 // Press Shift+Control+Alt+Search+B
1497 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_B
,
1499 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
1502 ShiftMask
| ControlMask
| Mod1Mask
|
1505 GetRewrittenEventAsString(&rewriter
,
1508 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
,
1511 ShiftMask
| ControlMask
| Mod1Mask
|
1515 TEST_F(EventRewriterTest
, TestRewriteModifiersRemapToCapsLock
) {
1516 // Remap Search to Caps Lock.
1517 TestingPrefServiceSyncable prefs
;
1518 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1519 IntegerPrefMember search
;
1520 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
1521 search
.SetValue(chromeos::input_method::kCapsLockKey
);
1523 chromeos::input_method::MockXKeyboard xkeyboard
;
1524 EventRewriter rewriter
;
1525 rewriter
.set_pref_service_for_testing(&prefs
);
1526 rewriter
.set_xkeyboard_for_testing(&xkeyboard
);
1527 EXPECT_FALSE(xkeyboard
.caps_lock_is_enabled_
);
1530 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL
,
1531 ui::EF_CAPS_LOCK_DOWN
,
1536 GetRewrittenEventAsString(&rewriter
,
1542 // Confirm that the Caps Lock status is changed.
1543 EXPECT_TRUE(xkeyboard
.caps_lock_is_enabled_
);
1546 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL
,
1548 ui::ET_KEY_RELEASED
,
1552 GetRewrittenEventAsString(&rewriter
,
1554 ui::EF_CAPS_LOCK_DOWN
,
1555 ui::ET_KEY_RELEASED
,
1557 Mod4Mask
| LockMask
));
1558 // Confirm that the Caps Lock status is not changed.
1559 EXPECT_TRUE(xkeyboard
.caps_lock_is_enabled_
);
1562 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL
,
1563 ui::EF_CAPS_LOCK_DOWN
,
1568 GetRewrittenEventAsString(&rewriter
,
1570 ui::EF_CAPS_LOCK_DOWN
,
1574 // Confirm that the Caps Lock status is changed.
1575 EXPECT_FALSE(xkeyboard
.caps_lock_is_enabled_
);
1578 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL
,
1580 ui::ET_KEY_RELEASED
,
1584 GetRewrittenEventAsString(&rewriter
,
1586 ui::EF_CAPS_LOCK_DOWN
,
1587 ui::ET_KEY_RELEASED
,
1589 Mod4Mask
| LockMask
));
1590 // Confirm that the Caps Lock status is not changed.
1591 EXPECT_FALSE(xkeyboard
.caps_lock_is_enabled_
);
1593 // Press Caps Lock (on an external keyboard).
1594 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL
,
1595 ui::EF_CAPS_LOCK_DOWN
,
1600 GetRewrittenEventAsString(&rewriter
,
1607 // Confirm that calling RewriteForTesting() does not change the state of
1608 // |xkeyboard|. In this case, X Window system itself should change the
1609 // Caps Lock state, not ash::EventRewriter.
1610 EXPECT_FALSE(xkeyboard
.caps_lock_is_enabled_
);
1612 // Release Caps Lock (on an external keyboard).
1613 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL
,
1615 ui::ET_KEY_RELEASED
,
1619 GetRewrittenEventAsString(&rewriter
,
1621 ui::EF_CAPS_LOCK_DOWN
,
1622 ui::ET_KEY_RELEASED
,
1625 EXPECT_FALSE(xkeyboard
.caps_lock_is_enabled_
);
1628 TEST_F(EventRewriterTest
, DISABLED_TestRewriteCapsLock
) {
1629 // It seems that the X server running on build servers is too old and does not
1630 // support F16 (i.e. 'XKeysymToKeycode(display_, XF86XK_Launch7)' call).
1631 // TODO(yusukes): Reenable the test once build servers are upgraded.
1633 TestingPrefServiceSyncable prefs
;
1634 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1636 chromeos::input_method::MockXKeyboard xkeyboard
;
1637 EventRewriter rewriter
;
1638 rewriter
.set_pref_service_for_testing(&prefs
);
1639 rewriter
.set_xkeyboard_for_testing(&xkeyboard
);
1640 EXPECT_FALSE(xkeyboard
.caps_lock_is_enabled_
);
1642 // On Chrome OS, CapsLock is mapped to F16 with Mod3Mask.
1643 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL
,
1644 ui::EF_CAPS_LOCK_DOWN
,
1649 GetRewrittenEventAsString(&rewriter
,
1655 EXPECT_TRUE(xkeyboard
.caps_lock_is_enabled_
);
1658 TEST_F(EventRewriterTest
, DISABLED_TestRewriteDiamondKey
) {
1659 // TODO(yusukes): Reenable the test once build servers are upgraded.
1661 TestingPrefServiceSyncable prefs
;
1662 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1664 chromeos::input_method::MockXKeyboard xkeyboard
;
1665 EventRewriter rewriter
;
1666 rewriter
.set_pref_service_for_testing(&prefs
);
1667 rewriter
.set_xkeyboard_for_testing(&xkeyboard
);
1669 // F15 should work as Ctrl when --has-chromeos-diamond-key is not specified.
1670 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL
,
1671 ui::EF_CONTROL_DOWN
,
1676 GetRewrittenEventAsString(&rewriter
,
1683 // However, Mod2Mask should not be rewritten to CtrlMask when
1684 // --has-chromeos-diamond-key is not specified.
1685 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A
,
1691 GetRewrittenEventAsString(&rewriter
,
1699 TEST_F(EventRewriterTest
, DISABLED_TestRewriteDiamondKeyWithFlag
) {
1700 // TODO(yusukes): Reenable the test once build servers are upgraded.
1702 const CommandLine
original_cl(*CommandLine::ForCurrentProcess());
1703 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1704 chromeos::switches::kHasChromeOSDiamondKey
, "");
1706 TestingPrefServiceSyncable prefs
;
1707 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1709 chromeos::input_method::MockXKeyboard xkeyboard
;
1710 EventRewriter rewriter
;
1711 rewriter
.set_pref_service_for_testing(&prefs
);
1712 rewriter
.set_xkeyboard_for_testing(&xkeyboard
);
1714 // By default, F15 should work as Control.
1715 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL
,
1716 ui::EF_CONTROL_DOWN
,
1721 GetRewrittenEventAsString(&rewriter
,
1728 IntegerPrefMember diamond
;
1729 diamond
.Init(prefs::kLanguageRemapDiamondKeyTo
, &prefs
);
1730 diamond
.SetValue(chromeos::input_method::kVoidKey
);
1732 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_UNKNOWN
,
1735 keycode_void_symbol_
,
1738 GetRewrittenEventAsString(&rewriter
,
1745 diamond
.SetValue(chromeos::input_method::kControlKey
);
1747 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL
,
1748 ui::EF_CONTROL_DOWN
,
1753 GetRewrittenEventAsString(&rewriter
,
1760 diamond
.SetValue(chromeos::input_method::kAltKey
);
1762 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU
,
1768 GetRewrittenEventAsString(&rewriter
,
1775 diamond
.SetValue(chromeos::input_method::kCapsLockKey
);
1777 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL
,
1778 ui::EF_CAPS_LOCK_DOWN
,
1783 GetRewrittenEventAsString(&rewriter
,
1790 *CommandLine::ForCurrentProcess() = original_cl
;
1793 TEST_F(EventRewriterTest
, TestRewriteCapsLockToControl
) {
1794 TestingPrefServiceSyncable prefs
;
1795 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1796 IntegerPrefMember control
;
1797 control
.Init(prefs::kLanguageRemapCapsLockKeyTo
, &prefs
);
1798 control
.SetValue(chromeos::input_method::kControlKey
);
1800 EventRewriter rewriter
;
1801 rewriter
.set_pref_service_for_testing(&prefs
);
1803 // Press CapsLock+a. Confirm that Mod3Mask is rewritten to ControlMask.
1804 // On Chrome OS, CapsLock works as a Mod3 modifier.
1805 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A
,
1806 ui::EF_CONTROL_DOWN
,
1811 GetRewrittenEventAsString(&rewriter
,
1818 // Press Control+CapsLock+a. Confirm that Mod3Mask is rewritten to ControlMask
1819 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A
,
1820 ui::EF_CONTROL_DOWN
,
1825 GetRewrittenEventAsString(&rewriter
,
1827 ui::EF_CONTROL_DOWN
,
1830 Mod3Mask
| ControlMask
));
1832 // Press Alt+CapsLock+a. Confirm that Mod3Mask is rewritten to ControlMask.
1833 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A
,
1834 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
,
1837 Mod1Mask
| ControlMask
,
1839 GetRewrittenEventAsString(&rewriter
,
1844 Mod1Mask
| Mod3Mask
));
1847 TEST_F(EventRewriterTest
, TestRewriteCapsLockMod3InUse
) {
1848 // Remap CapsLock to Control.
1849 TestingPrefServiceSyncable prefs
;
1850 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1851 IntegerPrefMember control
;
1852 control
.Init(prefs::kLanguageRemapCapsLockKeyTo
, &prefs
);
1853 control
.SetValue(chromeos::input_method::kControlKey
);
1855 EventRewriter rewriter
;
1856 rewriter
.set_pref_service_for_testing(&prefs
);
1857 input_method_manager_mock_
->SetCurrentInputMethodId("xkb:de:neo:ger");
1859 // Press CapsLock+a. Confirm that Mod3Mask is NOT rewritten to ControlMask
1860 // when Mod3Mask is already in use by the current XKB layout.
1861 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A
,
1867 GetRewrittenEventAsString(&rewriter
,
1874 input_method_manager_mock_
->SetCurrentInputMethodId("xkb:us::eng");
1877 TEST_F(EventRewriterTest
, TestRewriteExtendedKeys
) {
1878 TestingPrefServiceSyncable prefs
;
1879 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1880 EventRewriter rewriter
;
1881 rewriter
.set_pref_service_for_testing(&prefs
);
1884 ui::KeyboardCode input
;
1885 KeyCode input_native
;
1886 unsigned int input_mods
;
1887 unsigned int input_native_mods
;
1888 ui::KeyboardCode output
;
1889 KeyCode output_native
;
1890 unsigned int output_mods
;
1891 unsigned int output_native_mods
;
1892 } chromeos_tests
[] = {
1893 // Alt+Backspace -> Delete
1894 { ui::VKEY_BACK
, keycode_backspace_
,
1895 ui::EF_ALT_DOWN
, Mod1Mask
,
1896 ui::VKEY_DELETE
, keycode_delete_
,
1898 // Control+Alt+Backspace -> Control+Delete
1899 { ui::VKEY_BACK
, keycode_backspace_
,
1900 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
, Mod1Mask
| ControlMask
,
1901 ui::VKEY_DELETE
, keycode_delete_
,
1902 ui::EF_CONTROL_DOWN
, ControlMask
, },
1903 // Search+Alt+Backspace -> Alt+Backspace
1904 { ui::VKEY_BACK
, keycode_backspace_
,
1905 ui::EF_ALT_DOWN
, Mod1Mask
| Mod4Mask
,
1906 ui::VKEY_BACK
, keycode_backspace_
,
1907 ui::EF_ALT_DOWN
, Mod1Mask
, },
1908 // Search+Control+Alt+Backspace -> Control+Alt+Backspace
1909 { ui::VKEY_BACK
, keycode_backspace_
,
1910 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
, Mod1Mask
| ControlMask
| Mod4Mask
,
1911 ui::VKEY_BACK
, keycode_backspace_
,
1912 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
, Mod1Mask
| ControlMask
, },
1914 { ui::VKEY_UP
, keycode_up_
,
1915 ui::EF_ALT_DOWN
, Mod1Mask
,
1916 ui::VKEY_PRIOR
, keycode_prior_
,
1919 { ui::VKEY_DOWN
, keycode_down_
,
1920 ui::EF_ALT_DOWN
, Mod1Mask
,
1921 ui::VKEY_NEXT
, keycode_next_
,
1923 // Ctrl+Alt+Up -> Home
1924 { ui::VKEY_UP
, keycode_up_
,
1925 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
, Mod1Mask
| ControlMask
,
1926 ui::VKEY_HOME
, keycode_home_
,
1928 // Ctrl+Alt+Down -> End
1929 { ui::VKEY_DOWN
, keycode_down_
,
1930 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
, Mod1Mask
| ControlMask
,
1931 ui::VKEY_END
, keycode_end_
,
1934 // Search+Alt+Up -> Alt+Up
1935 { ui::VKEY_UP
, keycode_up_
,
1936 ui::EF_ALT_DOWN
, Mod1Mask
| Mod4Mask
,
1937 ui::VKEY_UP
, keycode_up_
,
1938 ui::EF_ALT_DOWN
, Mod1Mask
},
1939 // Search+Alt+Down -> Alt+Down
1940 { ui::VKEY_DOWN
, keycode_down_
,
1941 ui::EF_ALT_DOWN
, Mod1Mask
| Mod4Mask
,
1942 ui::VKEY_DOWN
, keycode_down_
,
1943 ui::EF_ALT_DOWN
, Mod1Mask
},
1944 // Search+Ctrl+Alt+Up -> Search+Ctrl+Alt+Up
1945 { ui::VKEY_UP
, keycode_up_
,
1946 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
, Mod1Mask
| ControlMask
| Mod4Mask
,
1947 ui::VKEY_UP
, keycode_up_
,
1948 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
, Mod1Mask
| ControlMask
},
1949 // Search+Ctrl+Alt+Down -> Ctrl+Alt+Down
1950 { ui::VKEY_DOWN
, keycode_down_
,
1951 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
, Mod1Mask
| ControlMask
| Mod4Mask
,
1952 ui::VKEY_DOWN
, keycode_down_
,
1953 ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
, Mod1Mask
| ControlMask
},
1956 { ui::VKEY_OEM_PERIOD
, keycode_period_
, 0, 0,
1957 ui::VKEY_OEM_PERIOD
, keycode_period_
, 0, 0 },
1959 // Search+Backspace -> Delete
1960 { ui::VKEY_BACK
, keycode_backspace_
,
1962 ui::VKEY_DELETE
, keycode_delete_
,
1964 // Search+Up -> Prior
1965 { ui::VKEY_UP
, keycode_up_
,
1967 ui::VKEY_PRIOR
, keycode_prior_
,
1969 // Search+Down -> Next
1970 { ui::VKEY_DOWN
, keycode_down_
,
1972 ui::VKEY_NEXT
, keycode_next_
,
1974 // Search+Left -> Home
1975 { ui::VKEY_LEFT
, keycode_left_
,
1977 ui::VKEY_HOME
, keycode_home_
,
1979 // Control+Search+Left -> Home
1980 { ui::VKEY_LEFT
, keycode_left_
,
1981 ui::EF_CONTROL_DOWN
, Mod4Mask
| ControlMask
,
1982 ui::VKEY_HOME
, keycode_home_
,
1983 ui::EF_CONTROL_DOWN
, ControlMask
},
1984 // Search+Right -> End
1985 { ui::VKEY_RIGHT
, keycode_right_
,
1987 ui::VKEY_END
, keycode_end_
,
1989 // Control+Search+Right -> End
1990 { ui::VKEY_RIGHT
, keycode_right_
,
1991 ui::EF_CONTROL_DOWN
, Mod4Mask
| ControlMask
,
1992 ui::VKEY_END
, keycode_end_
,
1993 ui::EF_CONTROL_DOWN
, ControlMask
},
1994 // Search+Period -> Insert
1995 { ui::VKEY_OEM_PERIOD
, keycode_period_
, 0, Mod4Mask
,
1996 ui::VKEY_INSERT
, keycode_insert_
, 0, 0 },
1997 // Control+Search+Period -> Control+Insert
1998 { ui::VKEY_OEM_PERIOD
, keycode_period_
,
1999 ui::EF_CONTROL_DOWN
, Mod4Mask
| ControlMask
,
2000 ui::VKEY_INSERT
, keycode_insert_
,
2001 ui::EF_CONTROL_DOWN
, ControlMask
}
2004 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(chromeos_tests
); ++i
) {
2005 EXPECT_EQ(GetExpectedResultAsString(chromeos_tests
[i
].output
,
2006 chromeos_tests
[i
].output_mods
,
2008 chromeos_tests
[i
].output_native
,
2009 chromeos_tests
[i
].output_native_mods
,
2011 GetRewrittenEventAsString(&rewriter
,
2012 chromeos_tests
[i
].input
,
2013 chromeos_tests
[i
].input_mods
,
2015 chromeos_tests
[i
].input_native
,
2016 chromeos_tests
[i
].input_native_mods
));
2020 TEST_F(EventRewriterTest
, TestRewriteFunctionKeys
) {
2021 TestingPrefServiceSyncable prefs
;
2022 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
2023 EventRewriter rewriter
;
2024 rewriter
.set_pref_service_for_testing(&prefs
);
2027 ui::KeyboardCode input
;
2028 KeyCode input_native
;
2029 unsigned int input_native_mods
;
2030 unsigned int input_mods
;
2031 ui::KeyboardCode output
;
2032 KeyCode output_native
;
2033 unsigned int output_native_mods
;
2034 unsigned int output_mods
;
2037 { ui::VKEY_F1
, keycode_f1_
, 0, 0,
2038 ui::VKEY_BROWSER_BACK
, keycode_browser_back_
, 0, 0 },
2039 { ui::VKEY_F1
, keycode_f1_
, ControlMask
, ui::EF_CONTROL_DOWN
,
2040 ui::VKEY_BROWSER_BACK
, keycode_browser_back_
,
2041 ControlMask
, ui::EF_CONTROL_DOWN
},
2042 { ui::VKEY_F1
, keycode_f1_
, Mod1Mask
, ui::EF_ALT_DOWN
,
2043 ui::VKEY_BROWSER_BACK
, keycode_browser_back_
,
2044 Mod1Mask
, ui::EF_ALT_DOWN
},
2046 { ui::VKEY_F2
, keycode_f2_
, 0, 0,
2047 ui::VKEY_BROWSER_FORWARD
, keycode_browser_forward_
, 0, 0 },
2048 { ui::VKEY_F2
, keycode_f2_
, ControlMask
, ui::EF_CONTROL_DOWN
,
2049 ui::VKEY_BROWSER_FORWARD
, keycode_browser_forward_
,
2050 ControlMask
, ui::EF_CONTROL_DOWN
},
2051 { ui::VKEY_F2
, keycode_f2_
, Mod1Mask
, ui::EF_ALT_DOWN
,
2052 ui::VKEY_BROWSER_FORWARD
, keycode_browser_forward_
,
2053 Mod1Mask
, ui::EF_ALT_DOWN
},
2055 { ui::VKEY_F3
, keycode_f3_
, 0, 0,
2056 ui::VKEY_BROWSER_REFRESH
, keycode_browser_refresh_
, 0, 0 },
2057 { ui::VKEY_F3
, keycode_f3_
, ControlMask
, ui::EF_CONTROL_DOWN
,
2058 ui::VKEY_BROWSER_REFRESH
, keycode_browser_refresh_
,
2059 ControlMask
, ui::EF_CONTROL_DOWN
},
2060 { ui::VKEY_F3
, keycode_f3_
, Mod1Mask
, ui::EF_ALT_DOWN
,
2061 ui::VKEY_BROWSER_REFRESH
, keycode_browser_refresh_
,
2062 Mod1Mask
, ui::EF_ALT_DOWN
},
2063 // F4 -> Launch App 2
2064 { ui::VKEY_F4
, keycode_f4_
, 0, 0,
2065 ui::VKEY_MEDIA_LAUNCH_APP2
, keycode_media_launch_app2_
, 0, 0 },
2066 { ui::VKEY_F4
, keycode_f4_
, ControlMask
, ui::EF_CONTROL_DOWN
,
2067 ui::VKEY_MEDIA_LAUNCH_APP2
, keycode_media_launch_app2_
,
2068 ControlMask
, ui::EF_CONTROL_DOWN
},
2069 { ui::VKEY_F4
, keycode_f4_
, Mod1Mask
, ui::EF_ALT_DOWN
,
2070 ui::VKEY_MEDIA_LAUNCH_APP2
, keycode_media_launch_app2_
,
2071 Mod1Mask
, ui::EF_ALT_DOWN
},
2072 // F5 -> Launch App 1
2073 { ui::VKEY_F5
, keycode_f5_
, 0, 0,
2074 ui::VKEY_MEDIA_LAUNCH_APP1
, keycode_media_launch_app1_
, 0, 0 },
2075 { ui::VKEY_F5
, keycode_f5_
, ControlMask
, ui::EF_CONTROL_DOWN
,
2076 ui::VKEY_MEDIA_LAUNCH_APP1
, keycode_media_launch_app1_
,
2077 ControlMask
, ui::EF_CONTROL_DOWN
},
2078 { ui::VKEY_F5
, keycode_f5_
, Mod1Mask
, ui::EF_ALT_DOWN
,
2079 ui::VKEY_MEDIA_LAUNCH_APP1
, keycode_media_launch_app1_
,
2080 Mod1Mask
, ui::EF_ALT_DOWN
},
2081 // F6 -> Brightness down
2082 { ui::VKEY_F6
, keycode_f6_
, 0, 0,
2083 ui::VKEY_BRIGHTNESS_DOWN
, keycode_brightness_down_
, 0, 0 },
2084 { ui::VKEY_F6
, keycode_f6_
, ControlMask
, ui::EF_CONTROL_DOWN
,
2085 ui::VKEY_BRIGHTNESS_DOWN
, keycode_brightness_down_
,
2086 ControlMask
, ui::EF_CONTROL_DOWN
},
2087 { ui::VKEY_F6
, keycode_f6_
, Mod1Mask
, ui::EF_ALT_DOWN
,
2088 ui::VKEY_BRIGHTNESS_DOWN
, keycode_brightness_down_
,
2089 Mod1Mask
, ui::EF_ALT_DOWN
},
2090 // F7 -> Brightness up
2091 { ui::VKEY_F7
, keycode_f7_
, 0, 0,
2092 ui::VKEY_BRIGHTNESS_UP
, keycode_brightness_up_
, 0, 0 },
2093 { ui::VKEY_F7
, keycode_f7_
, ControlMask
, ui::EF_CONTROL_DOWN
,
2094 ui::VKEY_BRIGHTNESS_UP
, keycode_brightness_up_
,
2095 ControlMask
, ui::EF_CONTROL_DOWN
},
2096 { ui::VKEY_F7
, keycode_f7_
, Mod1Mask
, ui::EF_ALT_DOWN
,
2097 ui::VKEY_BRIGHTNESS_UP
, keycode_brightness_up_
,
2098 Mod1Mask
, ui::EF_ALT_DOWN
},
2099 // F8 -> Volume Mute
2100 { ui::VKEY_F8
, keycode_f8_
, 0, 0,
2101 ui::VKEY_VOLUME_MUTE
, keycode_volume_mute_
, 0, 0 },
2102 { ui::VKEY_F8
, keycode_f8_
, ControlMask
, ui::EF_CONTROL_DOWN
,
2103 ui::VKEY_VOLUME_MUTE
, keycode_volume_mute_
,
2104 ControlMask
, ui::EF_CONTROL_DOWN
},
2105 { ui::VKEY_F8
, keycode_f8_
, Mod1Mask
, ui::EF_ALT_DOWN
,
2106 ui::VKEY_VOLUME_MUTE
, keycode_volume_mute_
,
2107 Mod1Mask
, ui::EF_ALT_DOWN
},
2108 // F9 -> Volume Down
2109 { ui::VKEY_F9
, keycode_f9_
, 0, 0,
2110 ui::VKEY_VOLUME_DOWN
, keycode_volume_down_
, 0, 0 },
2111 { ui::VKEY_F9
, keycode_f9_
, ControlMask
, ui::EF_CONTROL_DOWN
,
2112 ui::VKEY_VOLUME_DOWN
, keycode_volume_down_
,
2113 ControlMask
, ui::EF_CONTROL_DOWN
},
2114 { ui::VKEY_F9
, keycode_f9_
, Mod1Mask
, ui::EF_ALT_DOWN
,
2115 ui::VKEY_VOLUME_DOWN
, keycode_volume_down_
,
2116 Mod1Mask
, ui::EF_ALT_DOWN
},
2118 { ui::VKEY_F10
, keycode_f10_
, 0, 0,
2119 ui::VKEY_VOLUME_UP
, keycode_volume_up_
, 0, 0 },
2120 { ui::VKEY_F10
, keycode_f10_
, ControlMask
, ui::EF_CONTROL_DOWN
,
2121 ui::VKEY_VOLUME_UP
, keycode_volume_up_
,
2122 ControlMask
, ui::EF_CONTROL_DOWN
},
2123 { ui::VKEY_F10
, keycode_f10_
, Mod1Mask
, ui::EF_ALT_DOWN
,
2124 ui::VKEY_VOLUME_UP
, keycode_volume_up_
,
2125 Mod1Mask
, ui::EF_ALT_DOWN
},
2127 { ui::VKEY_F11
, keycode_f11_
, 0, 0,
2128 ui::VKEY_F11
, keycode_f11_
, 0, 0 },
2129 { ui::VKEY_F11
, keycode_f11_
, ControlMask
, ui::EF_CONTROL_DOWN
,
2130 ui::VKEY_F11
, keycode_f11_
, ControlMask
, ui::EF_CONTROL_DOWN
},
2131 { ui::VKEY_F11
, keycode_f11_
, Mod1Mask
, ui::EF_ALT_DOWN
,
2132 ui::VKEY_F11
, keycode_f11_
, Mod1Mask
, ui::EF_ALT_DOWN
},
2134 { ui::VKEY_F12
, keycode_f12_
, 0, 0,
2135 ui::VKEY_F12
, keycode_f12_
, 0, 0 },
2136 { ui::VKEY_F12
, keycode_f12_
, ControlMask
, ui::EF_CONTROL_DOWN
,
2137 ui::VKEY_F12
, keycode_f12_
, ControlMask
, ui::EF_CONTROL_DOWN
},
2138 { ui::VKEY_F12
, keycode_f12_
, Mod1Mask
, ui::EF_ALT_DOWN
,
2139 ui::VKEY_F12
, keycode_f12_
, Mod1Mask
, ui::EF_ALT_DOWN
},
2141 // The number row should not be rewritten without Search key.
2142 { ui::VKEY_1
, keycode_1_
, 0, 0,
2143 ui::VKEY_1
, keycode_1_
, 0, 0 },
2144 { ui::VKEY_2
, keycode_2_
, 0, 0,
2145 ui::VKEY_2
, keycode_2_
, 0, 0 },
2146 { ui::VKEY_3
, keycode_3_
, 0, 0,
2147 ui::VKEY_3
, keycode_3_
, 0, 0 },
2148 { ui::VKEY_4
, keycode_4_
, 0, 0,
2149 ui::VKEY_4
, keycode_4_
, 0, 0 },
2150 { ui::VKEY_5
, keycode_5_
, 0, 0,
2151 ui::VKEY_5
, keycode_5_
, 0, 0 },
2152 { ui::VKEY_6
, keycode_6_
, 0, 0,
2153 ui::VKEY_6
, keycode_6_
, 0, 0 },
2154 { ui::VKEY_7
, keycode_7_
, 0, 0,
2155 ui::VKEY_7
, keycode_7_
, 0, 0 },
2156 { ui::VKEY_8
, keycode_8_
, 0, 0,
2157 ui::VKEY_8
, keycode_8_
, 0, 0 },
2158 { ui::VKEY_9
, keycode_9_
, 0, 0,
2159 ui::VKEY_9
, keycode_9_
, 0, 0 },
2160 { ui::VKEY_0
, keycode_0_
, 0, 0,
2161 ui::VKEY_0
, keycode_0_
, 0, 0 },
2162 { ui::VKEY_OEM_MINUS
, keycode_minus_
, 0, 0,
2163 ui::VKEY_OEM_MINUS
, keycode_minus_
, 0, 0 },
2164 { ui::VKEY_OEM_PLUS
, keycode_equal_
, 0, 0,
2165 ui::VKEY_OEM_PLUS
, keycode_equal_
, 0, 0 },
2167 // The number row should be rewritten as the F<number> row with Search key.
2168 { ui::VKEY_1
, keycode_1_
, Mod4Mask
, 0,
2169 ui::VKEY_F1
, keycode_f1_
, 0, 0 },
2170 { ui::VKEY_2
, keycode_2_
, Mod4Mask
, 0,
2171 ui::VKEY_F2
, keycode_f2_
, 0, 0 },
2172 { ui::VKEY_3
, keycode_3_
, Mod4Mask
, 0,
2173 ui::VKEY_F3
, keycode_f3_
, 0, 0 },
2174 { ui::VKEY_4
, keycode_4_
, Mod4Mask
, 0,
2175 ui::VKEY_F4
, keycode_f4_
, 0, 0 },
2176 { ui::VKEY_5
, keycode_5_
, Mod4Mask
, 0,
2177 ui::VKEY_F5
, keycode_f5_
, 0, 0 },
2178 { ui::VKEY_6
, keycode_6_
, Mod4Mask
, 0,
2179 ui::VKEY_F6
, keycode_f6_
, 0, 0 },
2180 { ui::VKEY_7
, keycode_7_
, Mod4Mask
, 0,
2181 ui::VKEY_F7
, keycode_f7_
, 0, 0 },
2182 { ui::VKEY_8
, keycode_8_
, Mod4Mask
, 0,
2183 ui::VKEY_F8
, keycode_f8_
, 0, 0 },
2184 { ui::VKEY_9
, keycode_9_
, Mod4Mask
, 0,
2185 ui::VKEY_F9
, keycode_f9_
, 0, 0 },
2186 { ui::VKEY_0
, keycode_0_
, Mod4Mask
, 0,
2187 ui::VKEY_F10
, keycode_f10_
, 0, 0 },
2188 { ui::VKEY_OEM_MINUS
, keycode_minus_
, Mod4Mask
, 0,
2189 ui::VKEY_F11
, keycode_f11_
, 0, 0 },
2190 { ui::VKEY_OEM_PLUS
, keycode_equal_
, Mod4Mask
, 0,
2191 ui::VKEY_F12
, keycode_f12_
, 0, 0 },
2193 // The function keys should not be rewritten with Search key pressed.
2194 { ui::VKEY_F1
, keycode_f1_
, Mod4Mask
, 0,
2195 ui::VKEY_F1
, keycode_f1_
, 0, 0 },
2196 { ui::VKEY_F2
, keycode_f2_
, Mod4Mask
, 0,
2197 ui::VKEY_F2
, keycode_f2_
, 0, 0 },
2198 { ui::VKEY_F3
, keycode_f3_
, Mod4Mask
, 0,
2199 ui::VKEY_F3
, keycode_f3_
, 0, 0 },
2200 { ui::VKEY_F4
, keycode_f4_
, Mod4Mask
, 0,
2201 ui::VKEY_F4
, keycode_f4_
, 0, 0 },
2202 { ui::VKEY_F5
, keycode_f5_
, Mod4Mask
, 0,
2203 ui::VKEY_F5
, keycode_f5_
, 0, 0 },
2204 { ui::VKEY_F6
, keycode_f6_
, Mod4Mask
, 0,
2205 ui::VKEY_F6
, keycode_f6_
, 0, 0 },
2206 { ui::VKEY_F7
, keycode_f7_
, Mod4Mask
, 0,
2207 ui::VKEY_F7
, keycode_f7_
, 0, 0 },
2208 { ui::VKEY_F8
, keycode_f8_
, Mod4Mask
, 0,
2209 ui::VKEY_F8
, keycode_f8_
, 0, 0 },
2210 { ui::VKEY_F9
, keycode_f9_
, Mod4Mask
, 0,
2211 ui::VKEY_F9
, keycode_f9_
, 0, 0 },
2212 { ui::VKEY_F10
, keycode_f10_
, Mod4Mask
, 0,
2213 ui::VKEY_F10
, keycode_f10_
, 0, 0 },
2214 { ui::VKEY_F11
, keycode_f11_
, Mod4Mask
, 0,
2215 ui::VKEY_F11
, keycode_f11_
, 0, 0 },
2216 { ui::VKEY_F12
, keycode_f12_
, Mod4Mask
, 0,
2217 ui::VKEY_F12
, keycode_f12_
, 0, 0 },
2220 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(tests
); ++i
) {
2221 EXPECT_EQ(GetExpectedResultAsString(tests
[i
].output
,
2222 tests
[i
].output_mods
,
2224 tests
[i
].output_native
,
2225 tests
[i
].output_native_mods
,
2227 GetRewrittenEventAsString(&rewriter
,
2229 tests
[i
].input_mods
,
2231 tests
[i
].input_native
,
2232 tests
[i
].input_native_mods
));
2236 TEST_F(EventRewriterTest
, TestRewriteExtendedKeysWithSearchRemapped
) {
2237 const CommandLine
original_cl(*CommandLine::ForCurrentProcess());
2239 // Remap Search to Control.
2240 TestingPrefServiceSyncable prefs
;
2241 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
2242 IntegerPrefMember search
;
2243 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
2244 search
.SetValue(chromeos::input_method::kControlKey
);
2246 EventRewriter rewriter
;
2247 rewriter
.set_pref_service_for_testing(&prefs
);
2249 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
2250 chromeos::switches::kHasChromeOSKeyboard
, "");
2252 // Alt+Search+Down -> End
2253 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_END
,
2259 GetRewrittenEventAsString(&rewriter
,
2264 Mod1Mask
| Mod4Mask
));
2266 // Shift+Alt+Search+Down -> Shift+End
2267 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_END
,
2273 GetRewrittenEventAsString(&rewriter
,
2275 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
,
2278 ShiftMask
| Mod1Mask
| Mod4Mask
));
2280 *CommandLine::ForCurrentProcess() = original_cl
;
2283 TEST_F(EventRewriterTest
, TestRewriteKeyEventSentByXSendEvent
) {
2284 // Remap Control to Alt.
2285 TestingPrefServiceSyncable prefs
;
2286 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
2287 IntegerPrefMember control
;
2288 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
2289 control
.SetValue(chromeos::input_method::kAltKey
);
2291 EventRewriter rewriter
;
2292 rewriter
.set_pref_service_for_testing(&prefs
);
2294 // Send left control press.
2295 std::string rewritten_event
;
2297 ui::ScopedXI2Event xev
;
2298 xev
.InitKeyEvent(ui::ET_KEY_PRESSED
, ui::VKEY_CONTROL
, 0);
2299 XEvent
* xevent
= xev
;
2300 xevent
->xkey
.keycode
= keycode_control_l_
;
2301 xevent
->xkey
.send_event
= True
; // XSendEvent() always does this.
2302 ui::KeyEvent
keyevent(xev
, false /* is_char */);
2303 rewriter
.RewriteForTesting(&keyevent
);
2304 rewritten_event
= base::StringPrintf(
2305 "ui_keycode=%d ui_flags=%d ui_type=%d "
2306 "x_keycode=%u x_state=%u x_type=%d",
2307 keyevent
.key_code(), keyevent
.flags(), keyevent
.type(),
2308 xevent
->xkey
.keycode
, xevent
->xkey
.state
, xevent
->xkey
.type
);
2311 // XK_Control_L (left Control key) should NOT be remapped to Alt if send_event
2312 // flag in the event is True.
2313 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL
,
2314 ui::EF_CONTROL_DOWN
,
2322 // Tests of event rewriting that depend on the Ash window manager.
2323 class EventRewriterAshTest
: public ash::test::AshTestBase
{
2325 EventRewriterAshTest() {
2326 chromeos::Preferences::RegisterProfilePrefs(prefs_
.registry());
2327 rewriter_
.set_pref_service_for_testing(&prefs_
);
2329 virtual ~EventRewriterAshTest() {}
2331 bool RewriteFunctionKeys(ui::KeyEvent
* event
) {
2332 return rewriter_
.RewriteFunctionKeys(event
);
2336 TestingPrefServiceSyncable prefs_
;
2339 EventRewriter rewriter_
;
2341 DISALLOW_COPY_AND_ASSIGN(EventRewriterAshTest
);
2344 TEST_F(EventRewriterAshTest
, TopRowKeysAreFunctionKeys
) {
2345 scoped_ptr
<aura::Window
> window(CreateTestWindowInShellWithId(1));
2346 ash::wm::WindowState
* window_state
= ash::wm::GetWindowState(window
.get());
2347 window_state
->Activate();
2349 // Create a simulated keypress of F1 targetted at the window.
2350 ui::ScopedXI2Event xev_f1
;
2351 KeyCode keycode_f1
= XKeysymToKeycode(gfx::GetXDisplay(), XK_F1
);
2352 xev_f1
.InitKeyEvent(ui::ET_KEY_PRESSED
, ui::VKEY_F1
, 0);
2353 XEvent
* xevent
= xev_f1
;
2354 xevent
->xkey
.keycode
= keycode_f1
;
2355 ui::KeyEvent
press_f1(xev_f1
, false);
2356 ui::Event::DispatcherApi
dispatch_helper(&press_f1
);
2357 dispatch_helper
.set_target(window
.get());
2359 // Simulate an apps v2 window that has requested top row keys as function
2360 // keys. The event should not be rewritten.
2361 window_state
->set_top_row_keys_are_function_keys(true);
2362 ASSERT_FALSE(RewriteFunctionKeys(&press_f1
));
2363 ASSERT_EQ(ui::VKEY_F1
, press_f1
.key_code());
2365 // The event should also not be rewritten if the send-function-keys pref is
2366 // additionally set, for both apps v2 and regular windows.
2367 BooleanPrefMember send_function_keys_pref
;
2368 send_function_keys_pref
.Init(prefs::kLanguageSendFunctionKeys
, &prefs_
);
2369 send_function_keys_pref
.SetValue(true);
2370 ASSERT_FALSE(RewriteFunctionKeys(&press_f1
));
2371 ASSERT_EQ(ui::VKEY_F1
, press_f1
.key_code());
2372 window_state
->set_top_row_keys_are_function_keys(false);
2373 ASSERT_FALSE(RewriteFunctionKeys(&press_f1
));
2374 ASSERT_EQ(ui::VKEY_F1
, press_f1
.key_code());
2376 // If the pref isn't set when an event is sent to a regular window, F1 is
2377 // rewritten to the back key.
2378 send_function_keys_pref
.SetValue(false);
2379 ASSERT_TRUE(RewriteFunctionKeys(&press_f1
));
2380 ASSERT_EQ(ui::VKEY_BROWSER_BACK
, press_f1
.key_code());
2383 #endif // OS_CHROMEOS