1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/events/event_rewriter.h"
7 #include <X11/keysym.h>
8 #include <X11/XF86keysym.h>
14 #include "ash/test/ash_test_base.h"
15 #include "ash/wm/window_state.h"
16 #include "base/basictypes.h"
17 #include "base/command_line.h"
18 #include "base/prefs/pref_member.h"
19 #include "base/strings/stringprintf.h"
20 #include "chrome/browser/chromeos/input_method/input_method_configuration.h"
21 #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h"
22 #include "chrome/browser/chromeos/login/mock_user_manager.h"
23 #include "chrome/browser/chromeos/login/user_manager.h"
24 #include "chrome/browser/chromeos/preferences.h"
25 #include "chrome/common/pref_names.h"
26 #include "chrome/test/base/testing_pref_service_syncable.h"
27 #include "chromeos/chromeos_switches.h"
28 #include "chromeos/ime/fake_xkeyboard.h"
29 #include "testing/gtest/include/gtest/gtest.h"
30 #include "ui/aura/window.h"
31 #include "ui/events/event.h"
32 #include "ui/events/test/events_test_utils_x11.h"
33 #include "ui/events/x/touch_factory_x11.h"
34 #include "ui/gfx/x/x11_types.h"
38 std::string GetRewrittenEventAsString(chromeos::EventRewriter* rewriter,
39 ui::KeyboardCode ui_keycode,
41 ui::EventType ui_type,
43 unsigned int x_state) {
44 ui::ScopedXI2Event xev;
45 xev.InitKeyEvent(ui_type, ui_keycode, ui_flags);
47 xevent->xkey.keycode = x_keycode;
48 xevent->xkey.state = x_state;
49 rewriter->RewriteForTesting(xevent);
50 ui::KeyEvent keyevent(xevent, false /* is_char */);
51 return base::StringPrintf(
52 "ui_keycode=%d ui_flags=%d ui_type=%d x_keycode=%u x_state=%u x_type=%d",
53 keyevent.key_code(), keyevent.flags(), keyevent.type(),
54 xevent->xkey.keycode, xevent->xkey.state, xevent->xkey.type);
57 std::string GetExpectedResultAsString(ui::KeyboardCode ui_keycode,
59 ui::EventType ui_type,
63 return base::StringPrintf(
64 "ui_keycode=%d ui_flags=%d ui_type=%d x_keycode=%u x_state=%u x_type=%d",
65 ui_keycode, ui_flags, ui_type, x_keycode, x_state, x_type);
72 class EventRewriterTest : public ash::test::AshTestBase {
75 : display_(gfx::GetXDisplay()),
76 keycode_a_(XKeysymToKeycode(display_, XK_a)),
77 keycode_alt_l_(XKeysymToKeycode(display_, XK_Alt_L)),
78 keycode_alt_r_(XKeysymToKeycode(display_, XK_Alt_R)),
79 keycode_b_(XKeysymToKeycode(display_, XK_B)),
80 keycode_caps_lock_(XKeysymToKeycode(display_, XK_Caps_Lock)),
81 keycode_control_l_(XKeysymToKeycode(display_, XK_Control_L)),
82 keycode_control_r_(XKeysymToKeycode(display_, XK_Control_R)),
83 keycode_meta_l_(XKeysymToKeycode(display_, XK_Meta_L)),
84 keycode_meta_r_(XKeysymToKeycode(display_, XK_Meta_R)),
85 keycode_num_pad_0_(XKeysymToKeycode(display_, XK_KP_0)),
86 keycode_num_pad_1_(XKeysymToKeycode(display_, XK_KP_1)),
87 keycode_num_pad_2_(XKeysymToKeycode(display_, XK_KP_2)),
88 keycode_num_pad_3_(XKeysymToKeycode(display_, XK_KP_3)),
89 keycode_num_pad_4_(XKeysymToKeycode(display_, XK_KP_4)),
90 keycode_num_pad_5_(XKeysymToKeycode(display_, XK_KP_5)),
91 keycode_num_pad_6_(XKeysymToKeycode(display_, XK_KP_6)),
92 keycode_num_pad_7_(XKeysymToKeycode(display_, XK_KP_7)),
93 keycode_num_pad_8_(XKeysymToKeycode(display_, XK_KP_8)),
94 keycode_num_pad_9_(XKeysymToKeycode(display_, XK_KP_9)),
95 keycode_num_pad_begin_(XKeysymToKeycode(display_, XK_KP_Begin)),
96 keycode_num_pad_decimal_(XKeysymToKeycode(display_, XK_KP_Decimal)),
97 keycode_num_pad_delete_(XKeysymToKeycode(display_, XK_KP_Delete)),
98 keycode_num_pad_down_(XKeysymToKeycode(display_, XK_KP_Down)),
99 keycode_num_pad_end_(XKeysymToKeycode(display_, XK_KP_End)),
100 keycode_num_pad_home_(XKeysymToKeycode(display_, XK_KP_Home)),
101 keycode_num_pad_insert_(XKeysymToKeycode(display_, XK_KP_Insert)),
102 keycode_num_pad_left_(XKeysymToKeycode(display_, XK_KP_Left)),
103 keycode_num_pad_next_(XKeysymToKeycode(display_, XK_KP_Next)),
104 keycode_num_pad_prior_(XKeysymToKeycode(display_, XK_KP_Prior)),
105 keycode_num_pad_right_(XKeysymToKeycode(display_, XK_KP_Right)),
106 keycode_num_pad_up_(XKeysymToKeycode(display_, XK_KP_Up)),
107 keycode_super_l_(XKeysymToKeycode(display_, XK_Super_L)),
108 keycode_super_r_(XKeysymToKeycode(display_, XK_Super_R)),
109 keycode_void_symbol_(XKeysymToKeycode(display_, XK_VoidSymbol)),
110 keycode_delete_(XKeysymToKeycode(display_, XK_Delete)),
111 keycode_backspace_(XKeysymToKeycode(display_, XK_BackSpace)),
112 keycode_up_(XKeysymToKeycode(display_, XK_Up)),
113 keycode_down_(XKeysymToKeycode(display_, XK_Down)),
114 keycode_left_(XKeysymToKeycode(display_, XK_Left)),
115 keycode_right_(XKeysymToKeycode(display_, XK_Right)),
116 keycode_prior_(XKeysymToKeycode(display_, XK_Prior)),
117 keycode_next_(XKeysymToKeycode(display_, XK_Next)),
118 keycode_home_(XKeysymToKeycode(display_, XK_Home)),
119 keycode_end_(XKeysymToKeycode(display_, XK_End)),
120 keycode_escape_(XKeysymToKeycode(display_, XK_Escape)),
121 keycode_launch6_(XKeysymToKeycode(display_, XF86XK_Launch6)),
122 keycode_launch7_(XKeysymToKeycode(display_, XF86XK_Launch7)),
123 keycode_f1_(XKeysymToKeycode(display_, XK_F1)),
124 keycode_f2_(XKeysymToKeycode(display_, XK_F2)),
125 keycode_f3_(XKeysymToKeycode(display_, XK_F3)),
126 keycode_f4_(XKeysymToKeycode(display_, XK_F4)),
127 keycode_f5_(XKeysymToKeycode(display_, XK_F5)),
128 keycode_f6_(XKeysymToKeycode(display_, XK_F6)),
129 keycode_f7_(XKeysymToKeycode(display_, XK_F7)),
130 keycode_f8_(XKeysymToKeycode(display_, XK_F8)),
131 keycode_f9_(XKeysymToKeycode(display_, XK_F9)),
132 keycode_f10_(XKeysymToKeycode(display_, XK_F10)),
133 keycode_f11_(XKeysymToKeycode(display_, XK_F11)),
134 keycode_f12_(XKeysymToKeycode(display_, XK_F12)),
135 keycode_browser_back_(XKeysymToKeycode(display_, XF86XK_Back)),
136 keycode_browser_forward_(XKeysymToKeycode(display_, XF86XK_Forward)),
137 keycode_browser_refresh_(XKeysymToKeycode(display_, XF86XK_Reload)),
138 keycode_media_launch_app1_(XKeysymToKeycode(display_, XF86XK_LaunchA)),
139 keycode_media_launch_app2_(XKeysymToKeycode(display_, XF86XK_LaunchB)),
140 keycode_brightness_down_(XKeysymToKeycode(
141 display_, XF86XK_MonBrightnessDown)),
142 keycode_brightness_up_(XKeysymToKeycode(
143 display_, XF86XK_MonBrightnessUp)),
144 keycode_volume_mute_(XKeysymToKeycode(display_, XF86XK_AudioMute)),
145 keycode_volume_down_(XKeysymToKeycode(
146 display_, XF86XK_AudioLowerVolume)),
147 keycode_volume_up_(XKeysymToKeycode(
148 display_, XF86XK_AudioRaiseVolume)),
149 keycode_power_(XKeysymToKeycode(display_, XF86XK_PowerOff)),
150 keycode_1_(XKeysymToKeycode(display_, XK_1)),
151 keycode_2_(XKeysymToKeycode(display_, XK_2)),
152 keycode_3_(XKeysymToKeycode(display_, XK_3)),
153 keycode_4_(XKeysymToKeycode(display_, XK_4)),
154 keycode_5_(XKeysymToKeycode(display_, XK_5)),
155 keycode_6_(XKeysymToKeycode(display_, XK_6)),
156 keycode_7_(XKeysymToKeycode(display_, XK_7)),
157 keycode_8_(XKeysymToKeycode(display_, XK_8)),
158 keycode_9_(XKeysymToKeycode(display_, XK_9)),
159 keycode_0_(XKeysymToKeycode(display_, XK_0)),
160 keycode_minus_(XKeysymToKeycode(display_, XK_minus)),
161 keycode_equal_(XKeysymToKeycode(display_, XK_equal)),
162 keycode_period_(XKeysymToKeycode(display_, XK_period)),
163 keycode_insert_(XKeysymToKeycode(display_, XK_Insert)),
164 mock_user_manager_(new chromeos::MockUserManager),
165 user_manager_enabler_(mock_user_manager_),
166 input_method_manager_mock_(NULL) {
168 virtual ~EventRewriterTest() {}
170 virtual void SetUp() {
171 // Mocking user manager because the real one needs to be called on UI thread
172 EXPECT_CALL(*mock_user_manager_, IsLoggedInAsGuest())
173 .WillRepeatedly(testing::Return(false));
174 input_method_manager_mock_ =
175 new chromeos::input_method::MockInputMethodManager;
176 chromeos::input_method::InitializeForTesting(
177 input_method_manager_mock_); // pass ownership
179 AshTestBase::SetUp();
182 virtual void TearDown() {
183 AshTestBase::TearDown();
184 // Shutdown() deletes the IME mock object.
185 chromeos::input_method::Shutdown();
189 void TestRewriteNumPadKeys();
190 void TestRewriteNumPadKeysOnAppleKeyboard();
192 void RewriteMouseEvent(EventRewriter* rewriter,
193 ui::MouseEvent* event) {
194 XEvent* xevent = event->native_event();
195 rewriter->RewriteLocatedEvent(xevent);
196 *event = ui::MouseEvent(xevent);
200 const KeyCode keycode_a_;
201 const KeyCode keycode_alt_l_;
202 const KeyCode keycode_alt_r_;
203 const KeyCode keycode_b_;
204 const KeyCode keycode_caps_lock_;
205 const KeyCode keycode_control_l_;
206 const KeyCode keycode_control_r_;
207 const KeyCode keycode_meta_l_;
208 const KeyCode keycode_meta_r_;
209 const KeyCode keycode_num_pad_0_;
210 const KeyCode keycode_num_pad_1_;
211 const KeyCode keycode_num_pad_2_;
212 const KeyCode keycode_num_pad_3_;
213 const KeyCode keycode_num_pad_4_;
214 const KeyCode keycode_num_pad_5_;
215 const KeyCode keycode_num_pad_6_;
216 const KeyCode keycode_num_pad_7_;
217 const KeyCode keycode_num_pad_8_;
218 const KeyCode keycode_num_pad_9_;
219 const KeyCode keycode_num_pad_begin_;
220 const KeyCode keycode_num_pad_decimal_;
221 const KeyCode keycode_num_pad_delete_;
222 const KeyCode keycode_num_pad_down_;
223 const KeyCode keycode_num_pad_end_;
224 const KeyCode keycode_num_pad_home_;
225 const KeyCode keycode_num_pad_insert_;
226 const KeyCode keycode_num_pad_left_;
227 const KeyCode keycode_num_pad_next_;
228 const KeyCode keycode_num_pad_prior_;
229 const KeyCode keycode_num_pad_right_;
230 const KeyCode keycode_num_pad_up_;
231 const KeyCode keycode_super_l_;
232 const KeyCode keycode_super_r_;
233 const KeyCode keycode_void_symbol_;
234 const KeyCode keycode_delete_;
235 const KeyCode keycode_backspace_;
236 const KeyCode keycode_up_;
237 const KeyCode keycode_down_;
238 const KeyCode keycode_left_;
239 const KeyCode keycode_right_;
240 const KeyCode keycode_prior_;
241 const KeyCode keycode_next_;
242 const KeyCode keycode_home_;
243 const KeyCode keycode_end_;
244 const KeyCode keycode_escape_;
245 const KeyCode keycode_launch6_; // F15
246 const KeyCode keycode_launch7_; // F16
247 const KeyCode keycode_f1_;
248 const KeyCode keycode_f2_;
249 const KeyCode keycode_f3_;
250 const KeyCode keycode_f4_;
251 const KeyCode keycode_f5_;
252 const KeyCode keycode_f6_;
253 const KeyCode keycode_f7_;
254 const KeyCode keycode_f8_;
255 const KeyCode keycode_f9_;
256 const KeyCode keycode_f10_;
257 const KeyCode keycode_f11_;
258 const KeyCode keycode_f12_;
259 const KeyCode keycode_browser_back_;
260 const KeyCode keycode_browser_forward_;
261 const KeyCode keycode_browser_refresh_;
262 const KeyCode keycode_media_launch_app1_;
263 const KeyCode keycode_media_launch_app2_;
264 const KeyCode keycode_brightness_down_;
265 const KeyCode keycode_brightness_up_;
266 const KeyCode keycode_volume_mute_;
267 const KeyCode keycode_volume_down_;
268 const KeyCode keycode_volume_up_;
269 const KeyCode keycode_power_;
270 const KeyCode keycode_1_;
271 const KeyCode keycode_2_;
272 const KeyCode keycode_3_;
273 const KeyCode keycode_4_;
274 const KeyCode keycode_5_;
275 const KeyCode keycode_6_;
276 const KeyCode keycode_7_;
277 const KeyCode keycode_8_;
278 const KeyCode keycode_9_;
279 const KeyCode keycode_0_;
280 const KeyCode keycode_minus_;
281 const KeyCode keycode_equal_;
282 const KeyCode keycode_period_;
283 const KeyCode keycode_insert_;
284 chromeos::MockUserManager* mock_user_manager_; // Not owned.
285 chromeos::ScopedUserManagerEnabler user_manager_enabler_;
286 chromeos::input_method::MockInputMethodManager* input_method_manager_mock_;
289 TEST_F(EventRewriterTest, TestGetDeviceType) {
290 // This is the typical string which an Apple keyboard sends.
291 EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard,
292 EventRewriter::GetDeviceType("Apple Inc. Apple Keyboard"));
294 // Other cases we accept.
295 EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard,
296 EventRewriter::GetDeviceType("Apple Keyboard"));
297 EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard,
298 EventRewriter::GetDeviceType("apple keyboard"));
299 EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard,
300 EventRewriter::GetDeviceType("apple keyboard."));
301 EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard,
302 EventRewriter::GetDeviceType("apple.keyboard."));
303 EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard,
304 EventRewriter::GetDeviceType(".apple.keyboard."));
306 // Dell, Microsoft, Logitech, ... should be recognized as a kDeviceUnknown.
307 EXPECT_EQ(EventRewriter::kDeviceUnknown,
308 EventRewriter::GetDeviceType("Dell Dell USB Entry Keyboard"));
309 EXPECT_EQ(EventRewriter::kDeviceUnknown,
310 EventRewriter::GetDeviceType(
311 "Microsoft Natural Ergonomic Keyboard"));
312 EXPECT_EQ(EventRewriter::kDeviceUnknown,
313 EventRewriter::GetDeviceType("CHESEN USB Keyboard"));
315 // Some corner cases.
316 EXPECT_EQ(EventRewriter::kDeviceUnknown, EventRewriter::GetDeviceType(""));
317 EXPECT_EQ(EventRewriter::kDeviceUnknown,
318 EventRewriter::GetDeviceType("."));
319 EXPECT_EQ(EventRewriter::kDeviceUnknown,
320 EventRewriter::GetDeviceType(". "));
321 EXPECT_EQ(EventRewriter::kDeviceUnknown,
322 EventRewriter::GetDeviceType(" ."));
323 EXPECT_EQ(EventRewriter::kDeviceUnknown,
324 EventRewriter::GetDeviceType("not-an-apple keyboard"));
327 TEST_F(EventRewriterTest, TestDeviceAddedOrRemoved) {
328 EventRewriter rewriter;
329 EXPECT_TRUE(rewriter.device_id_to_type_for_testing().empty());
330 EXPECT_EQ(EventRewriter::kDeviceUnknown,
331 rewriter.DeviceAddedForTesting(0, "PC Keyboard"));
332 EXPECT_EQ(1U, rewriter.device_id_to_type_for_testing().size());
333 EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard,
334 rewriter.DeviceAddedForTesting(1, "Apple Keyboard"));
335 EXPECT_EQ(2U, rewriter.device_id_to_type_for_testing().size());
336 // Try to reuse the first ID.
337 EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard,
338 rewriter.DeviceAddedForTesting(0, "Apple Keyboard"));
339 EXPECT_EQ(2U, rewriter.device_id_to_type_for_testing().size());
342 TEST_F(EventRewriterTest, TestRewriteCommandToControl) {
343 // First, test with a PC keyboard.
344 TestingPrefServiceSyncable prefs;
345 EventRewriter rewriter;
346 rewriter.DeviceAddedForTesting(0, "PC Keyboard");
347 rewriter.set_last_device_id_for_testing(0);
348 rewriter.set_pref_service_for_testing(&prefs);
350 // XK_a, Alt modifier.
351 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
357 GetRewrittenEventAsString(&rewriter,
364 // XK_a, Win modifier.
365 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
371 GetRewrittenEventAsString(&rewriter,
378 // XK_a, Alt+Win modifier.
379 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
385 GetRewrittenEventAsString(&rewriter,
390 Mod1Mask | Mod4Mask));
392 // XK_Super_L (left Windows key), Alt modifier.
393 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN,
399 GetRewrittenEventAsString(&rewriter,
406 // XK_Super_R (right Windows key), Alt modifier.
407 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_RWIN,
413 GetRewrittenEventAsString(&rewriter,
420 // An Apple keyboard reusing the ID, zero.
421 rewriter.DeviceAddedForTesting(0, "Apple Keyboard");
422 rewriter.set_last_device_id_for_testing(0);
424 // XK_a, Alt modifier.
425 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
431 GetRewrittenEventAsString(&rewriter,
438 // XK_a, Win modifier.
439 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
445 GetRewrittenEventAsString(&rewriter,
452 // XK_a, Alt+Win modifier.
453 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
454 ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
457 Mod1Mask | ControlMask,
459 GetRewrittenEventAsString(&rewriter,
464 Mod1Mask | Mod4Mask));
466 // XK_Super_L (left Windows key), Alt modifier.
467 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
468 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
473 GetRewrittenEventAsString(&rewriter,
480 // XK_Super_R (right Windows key), Alt modifier.
481 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
482 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
487 GetRewrittenEventAsString(&rewriter,
495 // For crbug.com/133896.
496 TEST_F(EventRewriterTest, TestRewriteCommandToControlWithControlRemapped) {
497 // Remap Control to Alt.
498 TestingPrefServiceSyncable prefs;
499 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
500 IntegerPrefMember control;
501 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
502 control.SetValue(chromeos::input_method::kAltKey);
504 EventRewriter rewriter;
505 rewriter.set_pref_service_for_testing(&prefs);
506 rewriter.DeviceAddedForTesting(0, "PC Keyboard");
507 rewriter.set_last_device_id_for_testing(0);
509 // XK_Control_L (left Control key) should be remapped to Alt.
510 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
516 GetRewrittenEventAsString(&rewriter,
523 // An Apple keyboard reusing the ID, zero.
524 rewriter.DeviceAddedForTesting(0, "Apple Keyboard");
525 rewriter.set_last_device_id_for_testing(0);
527 // XK_Super_L (left Command key) with Alt modifier. The remapped Command key
528 // should never be re-remapped to Alt.
529 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
530 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
535 GetRewrittenEventAsString(&rewriter,
542 // XK_Super_R (right Command key) with Alt modifier. The remapped Command key
543 // should never be re-remapped to Alt.
544 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
545 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
550 GetRewrittenEventAsString(&rewriter,
558 void EventRewriterTest::TestRewriteNumPadKeys() {
559 TestingPrefServiceSyncable prefs;
560 EventRewriter rewriter;
561 rewriter.set_pref_service_for_testing(&prefs);
563 // XK_KP_Insert (= NumPad 0 without Num Lock), no modifier.
564 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD0,
568 Mod2Mask, // Num Lock
570 GetRewrittenEventAsString(&rewriter,
574 keycode_num_pad_insert_,
577 // XK_KP_Insert (= NumPad 0 without Num Lock), Alt modifier.
578 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD0,
579 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
584 GetRewrittenEventAsString(&rewriter,
588 keycode_num_pad_insert_,
591 // XK_KP_Delete (= NumPad . without Num Lock), Alt modifier.
592 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_DECIMAL,
593 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
595 keycode_num_pad_decimal_,
598 GetRewrittenEventAsString(&rewriter,
602 keycode_num_pad_delete_,
605 // XK_KP_End (= NumPad 1 without Num Lock), Alt modifier.
606 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD1,
607 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
612 GetRewrittenEventAsString(&rewriter,
616 keycode_num_pad_end_,
619 // XK_KP_Down (= NumPad 2 without Num Lock), Alt modifier.
620 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD2,
621 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
626 GetRewrittenEventAsString(&rewriter,
630 keycode_num_pad_down_,
633 // XK_KP_Next (= NumPad 3 without Num Lock), Alt modifier.
634 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD3,
635 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
640 GetRewrittenEventAsString(&rewriter,
644 keycode_num_pad_next_,
647 // XK_KP_Left (= NumPad 4 without Num Lock), Alt modifier.
648 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD4,
649 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
654 GetRewrittenEventAsString(&rewriter,
658 keycode_num_pad_left_,
661 // XK_KP_Begin (= NumPad 5 without Num Lock), Alt modifier.
662 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD5,
663 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
668 GetRewrittenEventAsString(&rewriter,
672 keycode_num_pad_begin_,
675 // XK_KP_Right (= NumPad 6 without Num Lock), Alt modifier.
676 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD6,
677 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
682 GetRewrittenEventAsString(&rewriter,
686 keycode_num_pad_right_,
689 // XK_KP_Home (= NumPad 7 without Num Lock), Alt modifier.
690 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD7,
691 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
696 GetRewrittenEventAsString(&rewriter,
700 keycode_num_pad_home_,
703 // XK_KP_Up (= NumPad 8 without Num Lock), Alt modifier.
704 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD8,
705 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
710 GetRewrittenEventAsString(&rewriter,
717 // XK_KP_Prior (= NumPad 9 without Num Lock), Alt modifier.
718 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD9,
719 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
724 GetRewrittenEventAsString(&rewriter,
728 keycode_num_pad_prior_,
731 // XK_KP_0 (= NumPad 0 with Num Lock), Num Lock modifier.
732 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD0,
738 GetRewrittenEventAsString(&rewriter,
745 // XK_KP_DECIMAL (= NumPad . with Num Lock), Num Lock modifier.
746 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_DECIMAL,
749 keycode_num_pad_decimal_,
752 GetRewrittenEventAsString(&rewriter,
756 keycode_num_pad_decimal_,
759 // XK_KP_1 (= NumPad 1 with Num Lock), Num Lock modifier.
760 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD1,
766 GetRewrittenEventAsString(&rewriter,
773 // XK_KP_2 (= NumPad 2 with Num Lock), Num Lock modifier.
774 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD2,
780 GetRewrittenEventAsString(&rewriter,
787 // XK_KP_3 (= NumPad 3 with Num Lock), Num Lock modifier.
788 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD3,
794 GetRewrittenEventAsString(&rewriter,
801 // XK_KP_4 (= NumPad 4 with Num Lock), Num Lock modifier.
802 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD4,
808 GetRewrittenEventAsString(&rewriter,
815 // XK_KP_5 (= NumPad 5 with Num Lock), Num Lock modifier.
816 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD5,
822 GetRewrittenEventAsString(&rewriter,
829 // XK_KP_6 (= NumPad 6 with Num Lock), Num Lock modifier.
830 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD6,
836 GetRewrittenEventAsString(&rewriter,
843 // XK_KP_7 (= NumPad 7 with Num Lock), Num Lock modifier.
844 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD7,
850 GetRewrittenEventAsString(&rewriter,
857 // XK_KP_8 (= NumPad 8 with Num Lock), Num Lock modifier.
858 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD8,
864 GetRewrittenEventAsString(&rewriter,
871 // XK_KP_9 (= NumPad 9 with Num Lock), Num Lock modifier.
872 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD9,
878 GetRewrittenEventAsString(&rewriter,
886 TEST_F(EventRewriterTest, TestRewriteNumPadKeys) {
887 TestRewriteNumPadKeys();
890 TEST_F(EventRewriterTest, TestRewriteNumPadKeysWithDiamondKeyFlag) {
891 // Make sure the num lock works correctly even when Diamond key exists.
892 const CommandLine original_cl(*CommandLine::ForCurrentProcess());
893 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
894 chromeos::switches::kHasChromeOSDiamondKey, "");
896 TestRewriteNumPadKeys();
897 *CommandLine::ForCurrentProcess() = original_cl;
900 // Tests if the rewriter can handle a Command + Num Pad event.
901 void EventRewriterTest::TestRewriteNumPadKeysOnAppleKeyboard() {
902 TestingPrefServiceSyncable prefs;
903 EventRewriter rewriter;
904 rewriter.DeviceAddedForTesting(0, "Apple Keyboard");
905 rewriter.set_last_device_id_for_testing(0);
906 rewriter.set_pref_service_for_testing(&prefs);
908 // XK_KP_End (= NumPad 1 without Num Lock), Win modifier.
909 // The result should be "Num Pad 1 with Control + Num Lock modifiers".
910 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD1,
911 ui::EF_CONTROL_DOWN | ui::EF_NUMPAD_KEY,
914 ControlMask | Mod2Mask,
916 GetRewrittenEventAsString(&rewriter,
920 keycode_num_pad_end_,
923 // XK_KP_1 (= NumPad 1 without Num Lock), Win modifier.
924 // The result should also be "Num Pad 1 with Control + Num Lock modifiers".
925 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD1,
926 ui::EF_CONTROL_DOWN | ui::EF_NUMPAD_KEY,
929 ControlMask | Mod2Mask,
931 GetRewrittenEventAsString(&rewriter,
935 keycode_num_pad_end_,
939 TEST_F(EventRewriterTest, TestRewriteNumPadKeysOnAppleKeyboard) {
940 TestRewriteNumPadKeysOnAppleKeyboard();
943 TEST_F(EventRewriterTest,
944 TestRewriteNumPadKeysOnAppleKeyboardWithDiamondKeyFlag) {
945 // Makes sure the num lock works correctly even when Diamond key exists.
946 const CommandLine original_cl(*CommandLine::ForCurrentProcess());
947 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
948 chromeos::switches::kHasChromeOSDiamondKey, "");
950 TestRewriteNumPadKeysOnAppleKeyboard();
951 *CommandLine::ForCurrentProcess() = original_cl;
954 TEST_F(EventRewriterTest, TestRewriteModifiersNoRemap) {
955 TestingPrefServiceSyncable prefs;
956 EventRewriter rewriter;
957 rewriter.set_pref_service_for_testing(&prefs);
959 // Press Search. Confirm the event is not rewritten.
960 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN,
966 GetRewrittenEventAsString(&rewriter,
973 // Press left Control. Confirm the event is not rewritten.
974 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
980 GetRewrittenEventAsString(&rewriter,
987 // Press right Control. Confirm the event is not rewritten.
988 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
994 GetRewrittenEventAsString(&rewriter,
1001 // Press left Alt. Confirm the event is not rewritten.
1002 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
1008 GetRewrittenEventAsString(&rewriter,
1015 // Press right Alt. Confirm the event is not rewritten.
1016 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
1022 GetRewrittenEventAsString(&rewriter,
1029 // Test KeyRelease event, just in case.
1030 // Release Search. Confirm the release event is not rewritten.
1031 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN,
1033 ui::ET_KEY_RELEASED,
1037 GetRewrittenEventAsString(&rewriter,
1040 ui::ET_KEY_RELEASED,
1045 TEST_F(EventRewriterTest, TestRewriteModifiersNoRemapMultipleKeys) {
1046 TestingPrefServiceSyncable prefs;
1047 EventRewriter rewriter;
1048 rewriter.set_pref_service_for_testing(&prefs);
1050 // Press left Alt with Shift. Confirm the event is not rewritten.
1051 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
1052 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
1057 GetRewrittenEventAsString(&rewriter,
1064 // Press right Alt with Shift. Confirm the event is not rewritten.
1065 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
1066 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
1071 GetRewrittenEventAsString(&rewriter,
1078 // Press Search with Caps Lock mask. Confirm the event is not rewritten.
1079 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN,
1080 ui::EF_CAPS_LOCK_DOWN,
1085 GetRewrittenEventAsString(&rewriter,
1087 ui::EF_CAPS_LOCK_DOWN,
1092 // Release Search with Caps Lock mask. Confirm the event is not rewritten.
1093 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN,
1094 ui::EF_CAPS_LOCK_DOWN,
1095 ui::ET_KEY_RELEASED,
1097 LockMask | Mod4Mask,
1099 GetRewrittenEventAsString(&rewriter,
1101 ui::EF_CAPS_LOCK_DOWN,
1102 ui::ET_KEY_RELEASED,
1104 LockMask | Mod4Mask));
1106 // Press Shift+Ctrl+Alt+Search+A. Confirm the event is not rewritten.
1107 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_B,
1109 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
1112 ShiftMask | ControlMask | Mod1Mask |
1115 GetRewrittenEventAsString(&rewriter,
1118 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
1121 ShiftMask | ControlMask | Mod1Mask |
1125 TEST_F(EventRewriterTest, TestRewriteModifiersDisableSome) {
1126 // Disable Search and Control keys.
1127 TestingPrefServiceSyncable prefs;
1128 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1129 IntegerPrefMember search;
1130 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
1131 search.SetValue(chromeos::input_method::kVoidKey);
1132 IntegerPrefMember control;
1133 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
1134 control.SetValue(chromeos::input_method::kVoidKey);
1136 EventRewriter rewriter;
1137 rewriter.set_pref_service_for_testing(&prefs);
1139 // Press left Alt with Shift. This key press shouldn't be affected by the
1140 // pref. Confirm the event is not rewritten.
1141 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
1142 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
1147 GetRewrittenEventAsString(&rewriter,
1154 // Press Search. Confirm the event is now VKEY_UNKNOWN + XK_VoidSymbol.
1155 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_UNKNOWN,
1158 keycode_void_symbol_,
1161 GetRewrittenEventAsString(&rewriter,
1168 // Press Control. Confirm the event is now VKEY_UNKNOWN + XK_VoidSymbol.
1169 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_UNKNOWN,
1172 keycode_void_symbol_,
1175 GetRewrittenEventAsString(&rewriter,
1182 // Press Control+Search. Confirm the event is now VKEY_UNKNOWN +
1183 // XK_VoidSymbol without any modifiers.
1184 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_UNKNOWN,
1187 keycode_void_symbol_,
1190 GetRewrittenEventAsString(&rewriter,
1192 ui::EF_CONTROL_DOWN,
1197 // Press Control+Search+a. Confirm the event is now VKEY_A without any
1199 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
1205 GetRewrittenEventAsString(&rewriter,
1207 ui::EF_CONTROL_DOWN,
1210 ControlMask | Mod4Mask));
1212 // Press Control+Search+Alt+a. Confirm the event is now VKEY_A only with
1213 // the Alt modifier.
1214 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
1220 GetRewrittenEventAsString(&rewriter,
1222 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
1225 ControlMask | Mod1Mask | Mod4Mask));
1227 // Remap Alt to Control.
1228 IntegerPrefMember alt;
1229 alt.Init(prefs::kLanguageRemapAltKeyTo, &prefs);
1230 alt.SetValue(chromeos::input_method::kControlKey);
1232 // Press left Alt. Confirm the event is now VKEY_CONTROL + XK_Control_L
1233 // even though the Control key itself is disabled.
1234 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
1235 ui::EF_CONTROL_DOWN,
1240 GetRewrittenEventAsString(&rewriter,
1247 // Press Alt+a. Confirm the event is now Control+a even though the Control
1248 // key itself is disabled.
1249 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
1250 ui::EF_CONTROL_DOWN,
1255 GetRewrittenEventAsString(&rewriter,
1263 TEST_F(EventRewriterTest, TestRewriteModifiersRemapToControl) {
1264 // Remap Search to Control.
1265 TestingPrefServiceSyncable prefs;
1266 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1267 IntegerPrefMember search;
1268 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
1269 search.SetValue(chromeos::input_method::kControlKey);
1271 EventRewriter rewriter;
1272 rewriter.set_pref_service_for_testing(&prefs);
1274 // Press Search. Confirm the event is now VKEY_CONTROL + XK_Control_L.
1275 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
1276 ui::EF_CONTROL_DOWN,
1281 GetRewrittenEventAsString(&rewriter,
1288 // Remap Alt to Control too.
1289 IntegerPrefMember alt;
1290 alt.Init(prefs::kLanguageRemapAltKeyTo, &prefs);
1291 alt.SetValue(chromeos::input_method::kControlKey);
1293 // Press left Alt. Confirm the event is now VKEY_CONTROL + XK_Control_L.
1294 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
1295 ui::EF_CONTROL_DOWN,
1300 GetRewrittenEventAsString(&rewriter,
1307 // Press right Alt. Confirm the event is now VKEY_CONTROL + XK_Control_R.
1308 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
1309 ui::EF_CONTROL_DOWN,
1314 GetRewrittenEventAsString(&rewriter,
1321 // Press Alt+Search. Confirm the event is now VKEY_CONTROL + XK_Control_L.
1322 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
1323 ui::EF_CONTROL_DOWN,
1328 GetRewrittenEventAsString(&rewriter,
1335 // Press Control+Alt+Search. Confirm the event is now VKEY_CONTROL +
1337 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
1338 ui::EF_CONTROL_DOWN,
1343 GetRewrittenEventAsString(&rewriter,
1345 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
1348 ControlMask | Mod1Mask));
1350 // Press Shift+Control+Alt+Search. Confirm the event is now Control with
1351 // Shift and Control modifiers.
1352 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
1353 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
1356 ShiftMask | ControlMask,
1358 GetRewrittenEventAsString(&rewriter,
1361 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
1364 ShiftMask | ControlMask | Mod1Mask));
1366 // Press Shift+Control+Alt+Search+B. Confirm the event is now B with Shift
1367 // and Control modifiers.
1368 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_B,
1369 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
1372 ShiftMask | ControlMask,
1374 GetRewrittenEventAsString(&rewriter,
1377 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
1380 ShiftMask | ControlMask | Mod1Mask));
1383 TEST_F(EventRewriterTest, TestRewriteModifiersRemapToEscape) {
1384 // Remap Search to ESC.
1385 TestingPrefServiceSyncable prefs;
1386 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1387 IntegerPrefMember search;
1388 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
1389 search.SetValue(chromeos::input_method::kEscapeKey);
1391 EventRewriter rewriter;
1392 rewriter.set_pref_service_for_testing(&prefs);
1394 // Press Search. Confirm the event is now VKEY_ESCAPE.
1395 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_ESCAPE,
1401 GetRewrittenEventAsString(&rewriter,
1409 TEST_F(EventRewriterTest, TestRewriteModifiersRemapMany) {
1410 // Remap Search to Alt.
1411 TestingPrefServiceSyncable prefs;
1412 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1413 IntegerPrefMember search;
1414 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
1415 search.SetValue(chromeos::input_method::kAltKey);
1417 EventRewriter rewriter;
1418 rewriter.set_pref_service_for_testing(&prefs);
1420 // Press Search. Confirm the event is now VKEY_MENU + XK_Alt_L.
1421 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
1427 GetRewrittenEventAsString(&rewriter,
1434 // Remap Alt to Control.
1435 IntegerPrefMember alt;
1436 alt.Init(prefs::kLanguageRemapAltKeyTo, &prefs);
1437 alt.SetValue(chromeos::input_method::kControlKey);
1439 // Press left Alt. Confirm the event is now VKEY_CONTROL + XK_Control_L.
1440 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
1441 ui::EF_CONTROL_DOWN,
1446 GetRewrittenEventAsString(&rewriter,
1453 // Remap Control to Search.
1454 IntegerPrefMember control;
1455 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
1456 control.SetValue(chromeos::input_method::kSearchKey);
1458 // Press left Control. Confirm the event is now VKEY_LWIN.
1459 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN,
1465 GetRewrittenEventAsString(&rewriter,
1472 // Then, press all of the three, Control+Alt+Search.
1473 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
1474 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
1477 ControlMask | Mod4Mask,
1479 GetRewrittenEventAsString(&rewriter,
1481 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
1484 ControlMask | Mod1Mask));
1486 // Press Shift+Control+Alt+Search.
1487 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
1488 (ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
1492 ShiftMask | ControlMask | Mod4Mask,
1494 GetRewrittenEventAsString(&rewriter,
1497 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
1500 ShiftMask | ControlMask | Mod1Mask));
1502 // Press Shift+Control+Alt+Search+B
1503 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_B,
1505 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
1508 ShiftMask | ControlMask | Mod1Mask |
1511 GetRewrittenEventAsString(&rewriter,
1514 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
1517 ShiftMask | ControlMask | Mod1Mask |
1521 TEST_F(EventRewriterTest, TestRewriteModifiersRemapToCapsLock) {
1522 // Remap Search to Caps Lock.
1523 TestingPrefServiceSyncable prefs;
1524 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1525 IntegerPrefMember search;
1526 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
1527 search.SetValue(chromeos::input_method::kCapsLockKey);
1529 chromeos::input_method::FakeXKeyboard xkeyboard;
1530 EventRewriter rewriter;
1531 rewriter.set_pref_service_for_testing(&prefs);
1532 rewriter.set_xkeyboard_for_testing(&xkeyboard);
1533 EXPECT_FALSE(xkeyboard.caps_lock_is_enabled_);
1536 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
1537 ui::EF_CAPS_LOCK_DOWN,
1542 GetRewrittenEventAsString(&rewriter,
1548 // Confirm that the Caps Lock status is changed.
1549 EXPECT_TRUE(xkeyboard.caps_lock_is_enabled_);
1552 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
1554 ui::ET_KEY_RELEASED,
1558 GetRewrittenEventAsString(&rewriter,
1560 ui::EF_CAPS_LOCK_DOWN,
1561 ui::ET_KEY_RELEASED,
1563 Mod4Mask | LockMask));
1564 // Confirm that the Caps Lock status is not changed.
1565 EXPECT_TRUE(xkeyboard.caps_lock_is_enabled_);
1568 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
1569 ui::EF_CAPS_LOCK_DOWN,
1574 GetRewrittenEventAsString(&rewriter,
1576 ui::EF_CAPS_LOCK_DOWN,
1580 // Confirm that the Caps Lock status is changed.
1581 EXPECT_FALSE(xkeyboard.caps_lock_is_enabled_);
1584 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
1586 ui::ET_KEY_RELEASED,
1590 GetRewrittenEventAsString(&rewriter,
1592 ui::EF_CAPS_LOCK_DOWN,
1593 ui::ET_KEY_RELEASED,
1595 Mod4Mask | LockMask));
1596 // Confirm that the Caps Lock status is not changed.
1597 EXPECT_FALSE(xkeyboard.caps_lock_is_enabled_);
1599 // Press Caps Lock (on an external keyboard).
1600 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
1601 ui::EF_CAPS_LOCK_DOWN,
1606 GetRewrittenEventAsString(&rewriter,
1613 // Confirm that calling RewriteForTesting() does not change the state of
1614 // |xkeyboard|. In this case, X Window system itself should change the
1615 // Caps Lock state, not ash::EventRewriter.
1616 EXPECT_FALSE(xkeyboard.caps_lock_is_enabled_);
1618 // Release Caps Lock (on an external keyboard).
1619 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
1621 ui::ET_KEY_RELEASED,
1625 GetRewrittenEventAsString(&rewriter,
1627 ui::EF_CAPS_LOCK_DOWN,
1628 ui::ET_KEY_RELEASED,
1631 EXPECT_FALSE(xkeyboard.caps_lock_is_enabled_);
1634 TEST_F(EventRewriterTest, DISABLED_TestRewriteCapsLock) {
1635 // It seems that the X server running on build servers is too old and does not
1636 // support F16 (i.e. 'XKeysymToKeycode(display_, XF86XK_Launch7)' call).
1637 // TODO(yusukes): Reenable the test once build servers are upgraded.
1639 TestingPrefServiceSyncable prefs;
1640 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1642 chromeos::input_method::FakeXKeyboard xkeyboard;
1643 EventRewriter rewriter;
1644 rewriter.set_pref_service_for_testing(&prefs);
1645 rewriter.set_xkeyboard_for_testing(&xkeyboard);
1646 EXPECT_FALSE(xkeyboard.caps_lock_is_enabled_);
1648 // On Chrome OS, CapsLock is mapped to F16 with Mod3Mask.
1649 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
1650 ui::EF_CAPS_LOCK_DOWN,
1655 GetRewrittenEventAsString(&rewriter,
1661 EXPECT_TRUE(xkeyboard.caps_lock_is_enabled_);
1664 TEST_F(EventRewriterTest, DISABLED_TestRewriteDiamondKey) {
1665 // TODO(yusukes): Reenable the test once build servers are upgraded.
1667 TestingPrefServiceSyncable prefs;
1668 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1670 chromeos::input_method::FakeXKeyboard xkeyboard;
1671 EventRewriter rewriter;
1672 rewriter.set_pref_service_for_testing(&prefs);
1673 rewriter.set_xkeyboard_for_testing(&xkeyboard);
1675 // F15 should work as Ctrl when --has-chromeos-diamond-key is not specified.
1676 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
1677 ui::EF_CONTROL_DOWN,
1682 GetRewrittenEventAsString(&rewriter,
1689 // However, Mod2Mask should not be rewritten to CtrlMask when
1690 // --has-chromeos-diamond-key is not specified.
1691 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
1697 GetRewrittenEventAsString(&rewriter,
1705 TEST_F(EventRewriterTest, DISABLED_TestRewriteDiamondKeyWithFlag) {
1706 // TODO(yusukes): Reenable the test once build servers are upgraded.
1708 const CommandLine original_cl(*CommandLine::ForCurrentProcess());
1709 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1710 chromeos::switches::kHasChromeOSDiamondKey, "");
1712 TestingPrefServiceSyncable prefs;
1713 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1715 chromeos::input_method::FakeXKeyboard xkeyboard;
1716 EventRewriter rewriter;
1717 rewriter.set_pref_service_for_testing(&prefs);
1718 rewriter.set_xkeyboard_for_testing(&xkeyboard);
1720 // By default, F15 should work as Control.
1721 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
1722 ui::EF_CONTROL_DOWN,
1727 GetRewrittenEventAsString(&rewriter,
1734 IntegerPrefMember diamond;
1735 diamond.Init(prefs::kLanguageRemapDiamondKeyTo, &prefs);
1736 diamond.SetValue(chromeos::input_method::kVoidKey);
1738 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_UNKNOWN,
1741 keycode_void_symbol_,
1744 GetRewrittenEventAsString(&rewriter,
1751 diamond.SetValue(chromeos::input_method::kControlKey);
1753 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
1754 ui::EF_CONTROL_DOWN,
1759 GetRewrittenEventAsString(&rewriter,
1766 diamond.SetValue(chromeos::input_method::kAltKey);
1768 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
1774 GetRewrittenEventAsString(&rewriter,
1781 diamond.SetValue(chromeos::input_method::kCapsLockKey);
1783 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
1784 ui::EF_CAPS_LOCK_DOWN,
1789 GetRewrittenEventAsString(&rewriter,
1796 *CommandLine::ForCurrentProcess() = original_cl;
1799 TEST_F(EventRewriterTest, TestRewriteCapsLockToControl) {
1800 TestingPrefServiceSyncable prefs;
1801 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1802 IntegerPrefMember control;
1803 control.Init(prefs::kLanguageRemapCapsLockKeyTo, &prefs);
1804 control.SetValue(chromeos::input_method::kControlKey);
1806 EventRewriter rewriter;
1807 rewriter.set_pref_service_for_testing(&prefs);
1809 // Press CapsLock+a. Confirm that Mod3Mask is rewritten to ControlMask.
1810 // On Chrome OS, CapsLock works as a Mod3 modifier.
1811 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
1812 ui::EF_CONTROL_DOWN,
1817 GetRewrittenEventAsString(&rewriter,
1824 // Press Control+CapsLock+a. Confirm that Mod3Mask is rewritten to ControlMask
1825 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
1826 ui::EF_CONTROL_DOWN,
1831 GetRewrittenEventAsString(&rewriter,
1833 ui::EF_CONTROL_DOWN,
1836 Mod3Mask | ControlMask));
1838 // Press Alt+CapsLock+a. Confirm that Mod3Mask is rewritten to ControlMask.
1839 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
1840 ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
1843 Mod1Mask | ControlMask,
1845 GetRewrittenEventAsString(&rewriter,
1850 Mod1Mask | Mod3Mask));
1853 TEST_F(EventRewriterTest, TestRewriteCapsLockMod3InUse) {
1854 // Remap CapsLock to Control.
1855 TestingPrefServiceSyncable prefs;
1856 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1857 IntegerPrefMember control;
1858 control.Init(prefs::kLanguageRemapCapsLockKeyTo, &prefs);
1859 control.SetValue(chromeos::input_method::kControlKey);
1861 EventRewriter rewriter;
1862 rewriter.set_pref_service_for_testing(&prefs);
1863 input_method_manager_mock_->set_mod3_used(true);
1865 // Press CapsLock+a. Confirm that Mod3Mask is NOT rewritten to ControlMask
1866 // when Mod3Mask is already in use by the current XKB layout.
1867 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
1873 GetRewrittenEventAsString(&rewriter,
1880 input_method_manager_mock_->set_mod3_used(false);
1883 TEST_F(EventRewriterTest, TestRewriteExtendedKeys) {
1884 TestingPrefServiceSyncable prefs;
1885 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1886 EventRewriter rewriter;
1887 rewriter.set_pref_service_for_testing(&prefs);
1890 ui::KeyboardCode input;
1891 KeyCode input_native;
1892 unsigned int input_mods;
1893 unsigned int input_native_mods;
1894 ui::KeyboardCode output;
1895 KeyCode output_native;
1896 unsigned int output_mods;
1897 unsigned int output_native_mods;
1898 } chromeos_tests[] = {
1899 // Alt+Backspace -> Delete
1900 { ui::VKEY_BACK, keycode_backspace_,
1901 ui::EF_ALT_DOWN, Mod1Mask,
1902 ui::VKEY_DELETE, keycode_delete_,
1904 // Control+Alt+Backspace -> Control+Delete
1905 { ui::VKEY_BACK, keycode_backspace_,
1906 ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, Mod1Mask | ControlMask,
1907 ui::VKEY_DELETE, keycode_delete_,
1908 ui::EF_CONTROL_DOWN, ControlMask, },
1909 // Search+Alt+Backspace -> Alt+Backspace
1910 { ui::VKEY_BACK, keycode_backspace_,
1911 ui::EF_ALT_DOWN, Mod1Mask | Mod4Mask,
1912 ui::VKEY_BACK, keycode_backspace_,
1913 ui::EF_ALT_DOWN, Mod1Mask, },
1914 // Search+Control+Alt+Backspace -> Control+Alt+Backspace
1915 { ui::VKEY_BACK, keycode_backspace_,
1916 ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, Mod1Mask | ControlMask | Mod4Mask,
1917 ui::VKEY_BACK, keycode_backspace_,
1918 ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, Mod1Mask | ControlMask, },
1920 { ui::VKEY_UP, keycode_up_,
1921 ui::EF_ALT_DOWN, Mod1Mask,
1922 ui::VKEY_PRIOR, keycode_prior_,
1925 { ui::VKEY_DOWN, keycode_down_,
1926 ui::EF_ALT_DOWN, Mod1Mask,
1927 ui::VKEY_NEXT, keycode_next_,
1929 // Ctrl+Alt+Up -> Home
1930 { ui::VKEY_UP, keycode_up_,
1931 ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, Mod1Mask | ControlMask,
1932 ui::VKEY_HOME, keycode_home_,
1934 // Ctrl+Alt+Down -> End
1935 { ui::VKEY_DOWN, keycode_down_,
1936 ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, Mod1Mask | ControlMask,
1937 ui::VKEY_END, keycode_end_,
1940 // Search+Alt+Up -> Alt+Up
1941 { ui::VKEY_UP, keycode_up_,
1942 ui::EF_ALT_DOWN, Mod1Mask | Mod4Mask,
1943 ui::VKEY_UP, keycode_up_,
1944 ui::EF_ALT_DOWN, Mod1Mask },
1945 // Search+Alt+Down -> Alt+Down
1946 { ui::VKEY_DOWN, keycode_down_,
1947 ui::EF_ALT_DOWN, Mod1Mask | Mod4Mask,
1948 ui::VKEY_DOWN, keycode_down_,
1949 ui::EF_ALT_DOWN, Mod1Mask },
1950 // Search+Ctrl+Alt+Up -> Search+Ctrl+Alt+Up
1951 { ui::VKEY_UP, keycode_up_,
1952 ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, Mod1Mask | ControlMask | Mod4Mask,
1953 ui::VKEY_UP, keycode_up_,
1954 ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, Mod1Mask | ControlMask },
1955 // Search+Ctrl+Alt+Down -> Ctrl+Alt+Down
1956 { ui::VKEY_DOWN, keycode_down_,
1957 ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, Mod1Mask | ControlMask | Mod4Mask,
1958 ui::VKEY_DOWN, keycode_down_,
1959 ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, Mod1Mask | ControlMask },
1962 { ui::VKEY_OEM_PERIOD, keycode_period_, 0, 0,
1963 ui::VKEY_OEM_PERIOD, keycode_period_, 0, 0 },
1965 // Search+Backspace -> Delete
1966 { ui::VKEY_BACK, keycode_backspace_,
1968 ui::VKEY_DELETE, keycode_delete_,
1970 // Search+Up -> Prior
1971 { ui::VKEY_UP, keycode_up_,
1973 ui::VKEY_PRIOR, keycode_prior_,
1975 // Search+Down -> Next
1976 { ui::VKEY_DOWN, keycode_down_,
1978 ui::VKEY_NEXT, keycode_next_,
1980 // Search+Left -> Home
1981 { ui::VKEY_LEFT, keycode_left_,
1983 ui::VKEY_HOME, keycode_home_,
1985 // Control+Search+Left -> Home
1986 { ui::VKEY_LEFT, keycode_left_,
1987 ui::EF_CONTROL_DOWN, Mod4Mask | ControlMask,
1988 ui::VKEY_HOME, keycode_home_,
1989 ui::EF_CONTROL_DOWN, ControlMask },
1990 // Search+Right -> End
1991 { ui::VKEY_RIGHT, keycode_right_,
1993 ui::VKEY_END, keycode_end_,
1995 // Control+Search+Right -> End
1996 { ui::VKEY_RIGHT, keycode_right_,
1997 ui::EF_CONTROL_DOWN, Mod4Mask | ControlMask,
1998 ui::VKEY_END, keycode_end_,
1999 ui::EF_CONTROL_DOWN, ControlMask },
2000 // Search+Period -> Insert
2001 { ui::VKEY_OEM_PERIOD, keycode_period_, 0, Mod4Mask,
2002 ui::VKEY_INSERT, keycode_insert_, 0, 0 },
2003 // Control+Search+Period -> Control+Insert
2004 { ui::VKEY_OEM_PERIOD, keycode_period_,
2005 ui::EF_CONTROL_DOWN, Mod4Mask | ControlMask,
2006 ui::VKEY_INSERT, keycode_insert_,
2007 ui::EF_CONTROL_DOWN, ControlMask }
2010 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(chromeos_tests); ++i) {
2011 EXPECT_EQ(GetExpectedResultAsString(chromeos_tests[i].output,
2012 chromeos_tests[i].output_mods,
2014 chromeos_tests[i].output_native,
2015 chromeos_tests[i].output_native_mods,
2017 GetRewrittenEventAsString(&rewriter,
2018 chromeos_tests[i].input,
2019 chromeos_tests[i].input_mods,
2021 chromeos_tests[i].input_native,
2022 chromeos_tests[i].input_native_mods));
2026 TEST_F(EventRewriterTest, TestRewriteFunctionKeys) {
2027 TestingPrefServiceSyncable prefs;
2028 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
2029 EventRewriter rewriter;
2030 rewriter.set_pref_service_for_testing(&prefs);
2033 ui::KeyboardCode input;
2034 KeyCode input_native;
2035 unsigned int input_native_mods;
2036 unsigned int input_mods;
2037 ui::KeyboardCode output;
2038 KeyCode output_native;
2039 unsigned int output_native_mods;
2040 unsigned int output_mods;
2043 { ui::VKEY_F1, keycode_f1_, 0, 0,
2044 ui::VKEY_BROWSER_BACK, keycode_browser_back_, 0, 0 },
2045 { ui::VKEY_F1, keycode_f1_, ControlMask, ui::EF_CONTROL_DOWN,
2046 ui::VKEY_BROWSER_BACK, keycode_browser_back_,
2047 ControlMask, ui::EF_CONTROL_DOWN },
2048 { ui::VKEY_F1, keycode_f1_, Mod1Mask, ui::EF_ALT_DOWN,
2049 ui::VKEY_BROWSER_BACK, keycode_browser_back_,
2050 Mod1Mask, ui::EF_ALT_DOWN },
2052 { ui::VKEY_F2, keycode_f2_, 0, 0,
2053 ui::VKEY_BROWSER_FORWARD, keycode_browser_forward_, 0, 0 },
2054 { ui::VKEY_F2, keycode_f2_, ControlMask, ui::EF_CONTROL_DOWN,
2055 ui::VKEY_BROWSER_FORWARD, keycode_browser_forward_,
2056 ControlMask, ui::EF_CONTROL_DOWN },
2057 { ui::VKEY_F2, keycode_f2_, Mod1Mask, ui::EF_ALT_DOWN,
2058 ui::VKEY_BROWSER_FORWARD, keycode_browser_forward_,
2059 Mod1Mask, ui::EF_ALT_DOWN },
2061 { ui::VKEY_F3, keycode_f3_, 0, 0,
2062 ui::VKEY_BROWSER_REFRESH, keycode_browser_refresh_, 0, 0 },
2063 { ui::VKEY_F3, keycode_f3_, ControlMask, ui::EF_CONTROL_DOWN,
2064 ui::VKEY_BROWSER_REFRESH, keycode_browser_refresh_,
2065 ControlMask, ui::EF_CONTROL_DOWN },
2066 { ui::VKEY_F3, keycode_f3_, Mod1Mask, ui::EF_ALT_DOWN,
2067 ui::VKEY_BROWSER_REFRESH, keycode_browser_refresh_,
2068 Mod1Mask, ui::EF_ALT_DOWN },
2069 // F4 -> Launch App 2
2070 { ui::VKEY_F4, keycode_f4_, 0, 0,
2071 ui::VKEY_MEDIA_LAUNCH_APP2, keycode_media_launch_app2_, 0, 0 },
2072 { ui::VKEY_F4, keycode_f4_, ControlMask, ui::EF_CONTROL_DOWN,
2073 ui::VKEY_MEDIA_LAUNCH_APP2, keycode_media_launch_app2_,
2074 ControlMask, ui::EF_CONTROL_DOWN },
2075 { ui::VKEY_F4, keycode_f4_, Mod1Mask, ui::EF_ALT_DOWN,
2076 ui::VKEY_MEDIA_LAUNCH_APP2, keycode_media_launch_app2_,
2077 Mod1Mask, ui::EF_ALT_DOWN },
2078 // F5 -> Launch App 1
2079 { ui::VKEY_F5, keycode_f5_, 0, 0,
2080 ui::VKEY_MEDIA_LAUNCH_APP1, keycode_media_launch_app1_, 0, 0 },
2081 { ui::VKEY_F5, keycode_f5_, ControlMask, ui::EF_CONTROL_DOWN,
2082 ui::VKEY_MEDIA_LAUNCH_APP1, keycode_media_launch_app1_,
2083 ControlMask, ui::EF_CONTROL_DOWN },
2084 { ui::VKEY_F5, keycode_f5_, Mod1Mask, ui::EF_ALT_DOWN,
2085 ui::VKEY_MEDIA_LAUNCH_APP1, keycode_media_launch_app1_,
2086 Mod1Mask, ui::EF_ALT_DOWN },
2087 // F6 -> Brightness down
2088 { ui::VKEY_F6, keycode_f6_, 0, 0,
2089 ui::VKEY_BRIGHTNESS_DOWN, keycode_brightness_down_, 0, 0 },
2090 { ui::VKEY_F6, keycode_f6_, ControlMask, ui::EF_CONTROL_DOWN,
2091 ui::VKEY_BRIGHTNESS_DOWN, keycode_brightness_down_,
2092 ControlMask, ui::EF_CONTROL_DOWN },
2093 { ui::VKEY_F6, keycode_f6_, Mod1Mask, ui::EF_ALT_DOWN,
2094 ui::VKEY_BRIGHTNESS_DOWN, keycode_brightness_down_,
2095 Mod1Mask, ui::EF_ALT_DOWN },
2096 // F7 -> Brightness up
2097 { ui::VKEY_F7, keycode_f7_, 0, 0,
2098 ui::VKEY_BRIGHTNESS_UP, keycode_brightness_up_, 0, 0 },
2099 { ui::VKEY_F7, keycode_f7_, ControlMask, ui::EF_CONTROL_DOWN,
2100 ui::VKEY_BRIGHTNESS_UP, keycode_brightness_up_,
2101 ControlMask, ui::EF_CONTROL_DOWN },
2102 { ui::VKEY_F7, keycode_f7_, Mod1Mask, ui::EF_ALT_DOWN,
2103 ui::VKEY_BRIGHTNESS_UP, keycode_brightness_up_,
2104 Mod1Mask, ui::EF_ALT_DOWN },
2105 // F8 -> Volume Mute
2106 { ui::VKEY_F8, keycode_f8_, 0, 0,
2107 ui::VKEY_VOLUME_MUTE, keycode_volume_mute_, 0, 0 },
2108 { ui::VKEY_F8, keycode_f8_, ControlMask, ui::EF_CONTROL_DOWN,
2109 ui::VKEY_VOLUME_MUTE, keycode_volume_mute_,
2110 ControlMask, ui::EF_CONTROL_DOWN },
2111 { ui::VKEY_F8, keycode_f8_, Mod1Mask, ui::EF_ALT_DOWN,
2112 ui::VKEY_VOLUME_MUTE, keycode_volume_mute_,
2113 Mod1Mask, ui::EF_ALT_DOWN },
2114 // F9 -> Volume Down
2115 { ui::VKEY_F9, keycode_f9_, 0, 0,
2116 ui::VKEY_VOLUME_DOWN, keycode_volume_down_, 0, 0 },
2117 { ui::VKEY_F9, keycode_f9_, ControlMask, ui::EF_CONTROL_DOWN,
2118 ui::VKEY_VOLUME_DOWN, keycode_volume_down_,
2119 ControlMask, ui::EF_CONTROL_DOWN },
2120 { ui::VKEY_F9, keycode_f9_, Mod1Mask, ui::EF_ALT_DOWN,
2121 ui::VKEY_VOLUME_DOWN, keycode_volume_down_,
2122 Mod1Mask, ui::EF_ALT_DOWN },
2124 { ui::VKEY_F10, keycode_f10_, 0, 0,
2125 ui::VKEY_VOLUME_UP, keycode_volume_up_, 0, 0 },
2126 { ui::VKEY_F10, keycode_f10_, ControlMask, ui::EF_CONTROL_DOWN,
2127 ui::VKEY_VOLUME_UP, keycode_volume_up_,
2128 ControlMask, ui::EF_CONTROL_DOWN },
2129 { ui::VKEY_F10, keycode_f10_, Mod1Mask, ui::EF_ALT_DOWN,
2130 ui::VKEY_VOLUME_UP, keycode_volume_up_,
2131 Mod1Mask, ui::EF_ALT_DOWN },
2133 { ui::VKEY_F11, keycode_f11_, 0, 0,
2134 ui::VKEY_F11, keycode_f11_, 0, 0 },
2135 { ui::VKEY_F11, keycode_f11_, ControlMask, ui::EF_CONTROL_DOWN,
2136 ui::VKEY_F11, keycode_f11_, ControlMask, ui::EF_CONTROL_DOWN },
2137 { ui::VKEY_F11, keycode_f11_, Mod1Mask, ui::EF_ALT_DOWN,
2138 ui::VKEY_F11, keycode_f11_, Mod1Mask, ui::EF_ALT_DOWN },
2140 { ui::VKEY_F12, keycode_f12_, 0, 0,
2141 ui::VKEY_F12, keycode_f12_, 0, 0 },
2142 { ui::VKEY_F12, keycode_f12_, ControlMask, ui::EF_CONTROL_DOWN,
2143 ui::VKEY_F12, keycode_f12_, ControlMask, ui::EF_CONTROL_DOWN },
2144 { ui::VKEY_F12, keycode_f12_, Mod1Mask, ui::EF_ALT_DOWN,
2145 ui::VKEY_F12, keycode_f12_, Mod1Mask, ui::EF_ALT_DOWN },
2147 // The number row should not be rewritten without Search key.
2148 { ui::VKEY_1, keycode_1_, 0, 0,
2149 ui::VKEY_1, keycode_1_, 0, 0 },
2150 { ui::VKEY_2, keycode_2_, 0, 0,
2151 ui::VKEY_2, keycode_2_, 0, 0 },
2152 { ui::VKEY_3, keycode_3_, 0, 0,
2153 ui::VKEY_3, keycode_3_, 0, 0 },
2154 { ui::VKEY_4, keycode_4_, 0, 0,
2155 ui::VKEY_4, keycode_4_, 0, 0 },
2156 { ui::VKEY_5, keycode_5_, 0, 0,
2157 ui::VKEY_5, keycode_5_, 0, 0 },
2158 { ui::VKEY_6, keycode_6_, 0, 0,
2159 ui::VKEY_6, keycode_6_, 0, 0 },
2160 { ui::VKEY_7, keycode_7_, 0, 0,
2161 ui::VKEY_7, keycode_7_, 0, 0 },
2162 { ui::VKEY_8, keycode_8_, 0, 0,
2163 ui::VKEY_8, keycode_8_, 0, 0 },
2164 { ui::VKEY_9, keycode_9_, 0, 0,
2165 ui::VKEY_9, keycode_9_, 0, 0 },
2166 { ui::VKEY_0, keycode_0_, 0, 0,
2167 ui::VKEY_0, keycode_0_, 0, 0 },
2168 { ui::VKEY_OEM_MINUS, keycode_minus_, 0, 0,
2169 ui::VKEY_OEM_MINUS, keycode_minus_, 0, 0 },
2170 { ui::VKEY_OEM_PLUS, keycode_equal_, 0, 0,
2171 ui::VKEY_OEM_PLUS, keycode_equal_, 0, 0 },
2173 // The number row should be rewritten as the F<number> row with Search key.
2174 { ui::VKEY_1, keycode_1_, Mod4Mask, 0,
2175 ui::VKEY_F1, keycode_f1_, 0, 0 },
2176 { ui::VKEY_2, keycode_2_, Mod4Mask, 0,
2177 ui::VKEY_F2, keycode_f2_, 0, 0 },
2178 { ui::VKEY_3, keycode_3_, Mod4Mask, 0,
2179 ui::VKEY_F3, keycode_f3_, 0, 0 },
2180 { ui::VKEY_4, keycode_4_, Mod4Mask, 0,
2181 ui::VKEY_F4, keycode_f4_, 0, 0 },
2182 { ui::VKEY_5, keycode_5_, Mod4Mask, 0,
2183 ui::VKEY_F5, keycode_f5_, 0, 0 },
2184 { ui::VKEY_6, keycode_6_, Mod4Mask, 0,
2185 ui::VKEY_F6, keycode_f6_, 0, 0 },
2186 { ui::VKEY_7, keycode_7_, Mod4Mask, 0,
2187 ui::VKEY_F7, keycode_f7_, 0, 0 },
2188 { ui::VKEY_8, keycode_8_, Mod4Mask, 0,
2189 ui::VKEY_F8, keycode_f8_, 0, 0 },
2190 { ui::VKEY_9, keycode_9_, Mod4Mask, 0,
2191 ui::VKEY_F9, keycode_f9_, 0, 0 },
2192 { ui::VKEY_0, keycode_0_, Mod4Mask, 0,
2193 ui::VKEY_F10, keycode_f10_, 0, 0 },
2194 { ui::VKEY_OEM_MINUS, keycode_minus_, Mod4Mask, 0,
2195 ui::VKEY_F11, keycode_f11_, 0, 0 },
2196 { ui::VKEY_OEM_PLUS, keycode_equal_, Mod4Mask, 0,
2197 ui::VKEY_F12, keycode_f12_, 0, 0 },
2199 // The function keys should not be rewritten with Search key pressed.
2200 { ui::VKEY_F1, keycode_f1_, Mod4Mask, 0,
2201 ui::VKEY_F1, keycode_f1_, 0, 0 },
2202 { ui::VKEY_F2, keycode_f2_, Mod4Mask, 0,
2203 ui::VKEY_F2, keycode_f2_, 0, 0 },
2204 { ui::VKEY_F3, keycode_f3_, Mod4Mask, 0,
2205 ui::VKEY_F3, keycode_f3_, 0, 0 },
2206 { ui::VKEY_F4, keycode_f4_, Mod4Mask, 0,
2207 ui::VKEY_F4, keycode_f4_, 0, 0 },
2208 { ui::VKEY_F5, keycode_f5_, Mod4Mask, 0,
2209 ui::VKEY_F5, keycode_f5_, 0, 0 },
2210 { ui::VKEY_F6, keycode_f6_, Mod4Mask, 0,
2211 ui::VKEY_F6, keycode_f6_, 0, 0 },
2212 { ui::VKEY_F7, keycode_f7_, Mod4Mask, 0,
2213 ui::VKEY_F7, keycode_f7_, 0, 0 },
2214 { ui::VKEY_F8, keycode_f8_, Mod4Mask, 0,
2215 ui::VKEY_F8, keycode_f8_, 0, 0 },
2216 { ui::VKEY_F9, keycode_f9_, Mod4Mask, 0,
2217 ui::VKEY_F9, keycode_f9_, 0, 0 },
2218 { ui::VKEY_F10, keycode_f10_, Mod4Mask, 0,
2219 ui::VKEY_F10, keycode_f10_, 0, 0 },
2220 { ui::VKEY_F11, keycode_f11_, Mod4Mask, 0,
2221 ui::VKEY_F11, keycode_f11_, 0, 0 },
2222 { ui::VKEY_F12, keycode_f12_, Mod4Mask, 0,
2223 ui::VKEY_F12, keycode_f12_, 0, 0 },
2226 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
2227 // XKeysymToKeycode returns zero for unknown keys. So ignore those.
2228 if (tests[i].output_native == 0)
2230 EXPECT_EQ(GetExpectedResultAsString(tests[i].output,
2231 tests[i].output_mods,
2233 tests[i].output_native,
2234 tests[i].output_native_mods,
2236 GetRewrittenEventAsString(&rewriter,
2238 tests[i].input_mods,
2240 tests[i].input_native,
2241 tests[i].input_native_mods));
2245 TEST_F(EventRewriterTest, TestRewriteExtendedKeysWithSearchRemapped) {
2246 const CommandLine original_cl(*CommandLine::ForCurrentProcess());
2248 // Remap Search to Control.
2249 TestingPrefServiceSyncable prefs;
2250 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
2251 IntegerPrefMember search;
2252 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
2253 search.SetValue(chromeos::input_method::kControlKey);
2255 EventRewriter rewriter;
2256 rewriter.set_pref_service_for_testing(&prefs);
2258 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
2259 chromeos::switches::kHasChromeOSKeyboard, "");
2261 // Alt+Search+Down -> End
2262 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_END,
2268 GetRewrittenEventAsString(&rewriter,
2273 Mod1Mask | Mod4Mask));
2275 // Shift+Alt+Search+Down -> Shift+End
2276 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_END,
2282 GetRewrittenEventAsString(&rewriter,
2284 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
2287 ShiftMask | Mod1Mask | Mod4Mask));
2289 *CommandLine::ForCurrentProcess() = original_cl;
2292 TEST_F(EventRewriterTest, TestRewriteKeyEventSentByXSendEvent) {
2293 // Remap Control to Alt.
2294 TestingPrefServiceSyncable prefs;
2295 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
2296 IntegerPrefMember control;
2297 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
2298 control.SetValue(chromeos::input_method::kAltKey);
2300 EventRewriter rewriter;
2301 rewriter.set_pref_service_for_testing(&prefs);
2303 // Send left control press.
2304 std::string rewritten_event;
2306 ui::ScopedXI2Event xev;
2307 xev.InitKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_CONTROL, 0);
2308 XEvent* xevent = xev;
2309 xevent->xkey.keycode = keycode_control_l_;
2310 xevent->xkey.send_event = True; // XSendEvent() always does this.
2311 rewriter.RewriteForTesting(xevent);
2312 ui::KeyEvent keyevent(xev, false /* is_char */);
2313 rewritten_event = base::StringPrintf(
2314 "ui_keycode=%d ui_flags=%d ui_type=%d "
2315 "x_keycode=%u x_state=%u x_type=%d",
2316 keyevent.key_code(), keyevent.flags(), keyevent.type(),
2317 xevent->xkey.keycode, xevent->xkey.state, xevent->xkey.type);
2320 // XK_Control_L (left Control key) should NOT be remapped to Alt if send_event
2321 // flag in the event is True.
2322 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
2323 ui::EF_CONTROL_DOWN,
2331 // Tests of event rewriting that depend on the Ash window manager.
2332 class EventRewriterAshTest : public ash::test::AshTestBase {
2334 EventRewriterAshTest() {
2335 chromeos::Preferences::RegisterProfilePrefs(prefs_.registry());
2336 rewriter_.set_pref_service_for_testing(&prefs_);
2338 virtual ~EventRewriterAshTest() {}
2340 bool RewriteFunctionKeys(XEvent* event) {
2341 return rewriter_.RewriteFunctionKeys(event);
2345 TestingPrefServiceSyncable prefs_;
2348 EventRewriter rewriter_;
2350 DISALLOW_COPY_AND_ASSIGN(EventRewriterAshTest);
2353 TEST_F(EventRewriterAshTest, TopRowKeysAreFunctionKeys) {
2354 scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(1));
2355 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window.get());
2356 window_state->Activate();
2358 // Create a simulated keypress of F1 targetted at the window.
2359 ui::ScopedXI2Event xev_f1;
2360 KeyCode keycode_f1 = XKeysymToKeycode(gfx::GetXDisplay(), XK_F1);
2361 xev_f1.InitKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_F1, 0);
2362 XEvent* xevent = xev_f1;
2363 xevent->xkey.keycode = keycode_f1;
2365 // Simulate an apps v2 window that has requested top row keys as function
2366 // keys. The event should not be rewritten.
2367 window_state->set_top_row_keys_are_function_keys(true);
2368 ASSERT_FALSE(RewriteFunctionKeys(xevent));
2369 ui::KeyEvent press_f1(xev_f1, false);
2370 ASSERT_EQ(ui::VKEY_F1, press_f1.key_code());
2372 // The event should also not be rewritten if the send-function-keys pref is
2373 // additionally set, for both apps v2 and regular windows.
2374 BooleanPrefMember send_function_keys_pref;
2375 send_function_keys_pref.Init(prefs::kLanguageSendFunctionKeys, &prefs_);
2376 send_function_keys_pref.SetValue(true);
2377 ASSERT_FALSE(RewriteFunctionKeys(xevent));
2378 press_f1 = ui::KeyEvent(xev_f1, false);
2379 ASSERT_EQ(ui::VKEY_F1, press_f1.key_code());
2380 window_state->set_top_row_keys_are_function_keys(false);
2381 ASSERT_FALSE(RewriteFunctionKeys(xevent));
2382 press_f1 = ui::KeyEvent(xev_f1, false);
2383 ASSERT_EQ(ui::VKEY_F1, press_f1.key_code());
2385 // If the pref isn't set when an event is sent to a regular window, F1 is
2386 // rewritten to the back key.
2387 send_function_keys_pref.SetValue(false);
2388 ASSERT_TRUE(RewriteFunctionKeys(xevent));
2389 press_f1 = ui::KeyEvent(xev_f1, false);
2390 ASSERT_EQ(ui::VKEY_BROWSER_BACK, press_f1.key_code());
2393 TEST_F(EventRewriterTest, DontRewriteIfNotRewritten) {
2394 std::vector<unsigned int> device_list;
2395 device_list.push_back(10);
2396 device_list.push_back(11);
2397 ui::TouchFactory::GetInstance()->SetPointerDeviceForTest(device_list);
2398 TestingPrefServiceSyncable prefs;
2399 EventRewriter rewriter;
2400 rewriter.set_pref_service_for_testing(&prefs);
2401 const int kLeftAndAltFlag = ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN;
2403 ui::ScopedXI2Event xev;
2404 xev.InitGenericButtonEvent(
2405 10, ui::ET_MOUSE_PRESSED, gfx::Point(), kLeftAndAltFlag);
2406 ui::MouseEvent press(xev);
2408 EXPECT_EQ(ui::ET_MOUSE_PRESSED, press.type());
2409 EXPECT_EQ(kLeftAndAltFlag, press.flags());
2411 RewriteMouseEvent(&rewriter, &press);
2413 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & press.flags());
2416 ui::ScopedXI2Event xev;
2417 xev.InitGenericButtonEvent(
2418 10, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
2419 ui::MouseEvent release(xev);
2420 RewriteMouseEvent(&rewriter, &release);
2421 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & release.flags());
2424 // No ALT in frst click.
2426 ui::ScopedXI2Event xev;
2427 xev.InitGenericButtonEvent(
2428 10, ui::ET_MOUSE_PRESSED, gfx::Point(), ui::EF_LEFT_MOUSE_BUTTON);
2429 ui::MouseEvent press(xev);
2430 RewriteMouseEvent(&rewriter, &press);
2431 EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & press.flags());
2434 ui::ScopedXI2Event xev;
2435 xev.InitGenericButtonEvent(
2436 10, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
2437 ui::MouseEvent release(xev);
2438 RewriteMouseEvent(&rewriter, &release);
2439 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN) &
2443 // ALT on different device.
2445 ui::ScopedXI2Event xev;
2446 xev.InitGenericButtonEvent(
2447 11, ui::ET_MOUSE_PRESSED, gfx::Point(), kLeftAndAltFlag);
2448 ui::MouseEvent press(xev);
2449 RewriteMouseEvent(&rewriter, &press);
2450 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & press.flags());
2453 ui::ScopedXI2Event xev;
2454 xev.InitGenericButtonEvent(
2455 10, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
2456 ui::MouseEvent release(xev);
2457 RewriteMouseEvent(&rewriter, &release);
2458 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN) &
2462 ui::ScopedXI2Event xev;
2463 xev.InitGenericButtonEvent(
2464 11, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
2465 ui::MouseEvent release(xev);
2466 RewriteMouseEvent(&rewriter, &release);
2467 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & release.flags());
2471 } // namespace chromeos