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>
16 #include "ash/test/ash_test_base.h"
17 #include "ash/wm/window_state.h"
18 #include "base/basictypes.h"
19 #include "base/command_line.h"
20 #include "base/prefs/pref_member.h"
21 #include "base/strings/stringprintf.h"
22 #include "chrome/browser/chromeos/input_method/input_method_configuration.h"
23 #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h"
24 #include "chrome/browser/chromeos/login/mock_user_manager.h"
25 #include "chrome/browser/chromeos/login/user_manager.h"
26 #include "chrome/browser/chromeos/preferences.h"
27 #include "chrome/common/pref_names.h"
28 #include "chrome/test/base/testing_pref_service_syncable.h"
29 #include "chromeos/chromeos_switches.h"
30 #include "chromeos/ime/fake_ime_keyboard.h"
31 #include "testing/gtest/include/gtest/gtest.h"
32 #include "ui/aura/window.h"
33 #include "ui/events/event.h"
34 #include "ui/events/event_rewriter.h"
35 #include "ui/events/test/events_test_utils_x11.h"
36 #include "ui/events/x/touch_factory_x11.h"
37 #include "ui/gfx/x/x11_types.h"
41 std::string GetKeyEventAsString(const ui::KeyEvent& keyevent) {
42 return base::StringPrintf("ui_keycode=0x%X ui_flags=0x%X ui_type=%d",
48 std::string GetRewrittenEventAsString(chromeos::EventRewriter* rewriter,
49 ui::KeyboardCode ui_keycode,
51 ui::EventType ui_type) {
52 const ui::KeyEvent event(ui_type, ui_keycode, ui_flags, false);
53 scoped_ptr<ui::Event> new_event;
54 rewriter->RewriteEvent(event, &new_event);
56 return GetKeyEventAsString(
57 static_cast<const ui::KeyEvent&>(*new_event.get()));
58 return GetKeyEventAsString(event);
61 std::string GetExpectedResultAsString(ui::KeyboardCode ui_keycode,
63 ui::EventType ui_type) {
64 return base::StringPrintf("ui_keycode=0x%X ui_flags=0x%X ui_type=%d",
70 std::string GetRewrittenEventNumbered(size_t i,
71 chromeos::EventRewriter* rewriter,
72 ui::KeyboardCode ui_keycode,
74 ui::EventType ui_type) {
75 return base::StringPrintf("(%zu) ", i) +
76 GetRewrittenEventAsString(rewriter, ui_keycode, ui_flags, ui_type);
79 std::string GetExpectedResultNumbered(size_t i,
80 ui::KeyboardCode ui_keycode,
82 ui::EventType ui_type) {
83 return base::StringPrintf("(%zu) ", i) +
84 GetExpectedResultAsString(ui_keycode, ui_flags, ui_type);
91 class EventRewriterTest : public ash::test::AshTestBase {
94 : display_(gfx::GetXDisplay()),
95 mock_user_manager_(new chromeos::MockUserManager),
96 user_manager_enabler_(mock_user_manager_),
97 input_method_manager_mock_(NULL) {
99 virtual ~EventRewriterTest() {}
101 virtual void SetUp() {
102 // Mocking user manager because the real one needs to be called on UI thread
103 EXPECT_CALL(*mock_user_manager_, IsLoggedInAsGuest())
104 .WillRepeatedly(testing::Return(false));
105 input_method_manager_mock_ =
106 new chromeos::input_method::MockInputMethodManager;
107 chromeos::input_method::InitializeForTesting(
108 input_method_manager_mock_); // pass ownership
110 AshTestBase::SetUp();
113 virtual void TearDown() {
114 AshTestBase::TearDown();
115 // Shutdown() deletes the IME mock object.
116 chromeos::input_method::Shutdown();
120 void TestRewriteNumPadKeys();
121 void TestRewriteNumPadKeysOnAppleKeyboard();
123 int RewriteMouseEvent(chromeos::EventRewriter* rewriter,
124 const ui::MouseEvent& event) {
125 int flags = event.flags();
126 rewriter->RewriteLocatedEventForTesting(event, &flags);
131 chromeos::MockUserManager* mock_user_manager_; // Not owned.
132 chromeos::ScopedUserManagerEnabler user_manager_enabler_;
133 chromeos::input_method::MockInputMethodManager* input_method_manager_mock_;
136 TEST_F(EventRewriterTest, TestRewriteCommandToControl) {
137 // First, test with a PC keyboard.
138 TestingPrefServiceSyncable prefs;
139 EventRewriter rewriter;
140 rewriter.DeviceAddedForTesting(0, "PC Keyboard");
141 rewriter.set_last_device_id_for_testing(0);
142 rewriter.set_pref_service_for_testing(&prefs);
144 // VKEY_A, Alt modifier.
145 EXPECT_EQ(GetExpectedResultAsString(
146 ui::VKEY_A, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED),
147 GetRewrittenEventAsString(
148 &rewriter, ui::VKEY_A, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED));
150 // VKEY_A, Win modifier.
152 GetExpectedResultAsString(
153 ui::VKEY_A, ui::EF_COMMAND_DOWN, ui::ET_KEY_PRESSED),
154 GetRewrittenEventAsString(
155 &rewriter, ui::VKEY_A, ui::EF_COMMAND_DOWN, ui::ET_KEY_PRESSED));
157 // VKEY_A, Alt+Win modifier.
158 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
159 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
161 GetRewrittenEventAsString(&rewriter,
163 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
164 ui::ET_KEY_PRESSED));
166 // VKEY_LWIN (left Windows key), Alt modifier.
167 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN,
168 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
170 GetRewrittenEventAsString(&rewriter,
172 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
173 ui::ET_KEY_PRESSED));
175 // VKEY_RWIN (right Windows key), Alt modifier.
176 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_RWIN,
177 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
179 GetRewrittenEventAsString(&rewriter,
181 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
182 ui::ET_KEY_PRESSED));
184 // An Apple keyboard reusing the ID, zero.
185 rewriter.DeviceAddedForTesting(0, "Apple Keyboard");
186 rewriter.set_last_device_id_for_testing(0);
188 // VKEY_A, Alt modifier.
189 EXPECT_EQ(GetExpectedResultAsString(
190 ui::VKEY_A, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED),
191 GetRewrittenEventAsString(
192 &rewriter, ui::VKEY_A, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED));
194 // VKEY_A, Win modifier.
196 GetExpectedResultAsString(
197 ui::VKEY_A, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
198 GetRewrittenEventAsString(
199 &rewriter, ui::VKEY_A, ui::EF_COMMAND_DOWN, ui::ET_KEY_PRESSED));
201 // VKEY_A, Alt+Win modifier.
202 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
203 ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
205 GetRewrittenEventAsString(&rewriter,
207 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
208 ui::ET_KEY_PRESSED));
210 // VKEY_LWIN (left Windows key), Alt modifier.
211 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
212 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
214 GetRewrittenEventAsString(&rewriter,
216 ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
217 ui::ET_KEY_PRESSED));
219 // VKEY_RWIN (right Windows key), Alt modifier.
220 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
221 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
223 GetRewrittenEventAsString(&rewriter,
225 ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
226 ui::ET_KEY_PRESSED));
229 // For crbug.com/133896.
230 TEST_F(EventRewriterTest, TestRewriteCommandToControlWithControlRemapped) {
231 // Remap Control to Alt.
232 TestingPrefServiceSyncable prefs;
233 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
234 IntegerPrefMember control;
235 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
236 control.SetValue(chromeos::input_method::kAltKey);
238 EventRewriter rewriter;
239 rewriter.set_pref_service_for_testing(&prefs);
240 rewriter.DeviceAddedForTesting(0, "PC Keyboard");
241 rewriter.set_last_device_id_for_testing(0);
243 // Control should be remapped to Alt.
244 EXPECT_EQ(GetExpectedResultAsString(
245 ui::VKEY_MENU, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED),
246 GetRewrittenEventAsString(&rewriter,
249 ui::ET_KEY_PRESSED));
251 // An Apple keyboard reusing the ID, zero.
252 rewriter.DeviceAddedForTesting(0, "Apple Keyboard");
253 rewriter.set_last_device_id_for_testing(0);
255 // VKEY_LWIN (left Command key) with Alt modifier. The remapped Command key
256 // should never be re-remapped to Alt.
257 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
258 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
260 GetRewrittenEventAsString(&rewriter,
262 ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
263 ui::ET_KEY_PRESSED));
265 // VKEY_RWIN (right Command key) with Alt modifier. The remapped Command key
266 // should never be re-remapped to Alt.
267 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
268 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
270 GetRewrittenEventAsString(&rewriter,
272 ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
273 ui::ET_KEY_PRESSED));
276 void EventRewriterTest::TestRewriteNumPadKeys() {
277 TestingPrefServiceSyncable prefs;
278 EventRewriter rewriter;
279 rewriter.set_pref_service_for_testing(&prefs);
281 // XK_KP_Insert (= NumPad 0 without Num Lock), no modifier.
283 GetExpectedResultAsString(
284 ui::VKEY_NUMPAD0, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
285 GetRewrittenEventAsString(
286 &rewriter, ui::VKEY_INSERT, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
288 // XK_KP_Insert (= NumPad 0 without Num Lock), Alt modifier.
289 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD0,
290 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
292 GetRewrittenEventAsString(&rewriter,
294 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
295 ui::ET_KEY_PRESSED));
297 // XK_KP_Delete (= NumPad . without Num Lock), Alt modifier.
298 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_DECIMAL,
299 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
301 GetRewrittenEventAsString(&rewriter,
303 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
304 ui::ET_KEY_PRESSED));
306 // XK_KP_End (= NumPad 1 without Num Lock), Alt modifier.
307 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD1,
308 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
310 GetRewrittenEventAsString(&rewriter,
312 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
313 ui::ET_KEY_PRESSED));
315 // XK_KP_Down (= NumPad 2 without Num Lock), Alt modifier.
316 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD2,
317 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
319 GetRewrittenEventAsString(&rewriter,
321 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
322 ui::ET_KEY_PRESSED));
324 // XK_KP_Next (= NumPad 3 without Num Lock), Alt modifier.
325 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD3,
326 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
328 GetRewrittenEventAsString(&rewriter,
330 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
331 ui::ET_KEY_PRESSED));
333 // XK_KP_Left (= NumPad 4 without Num Lock), Alt modifier.
334 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD4,
335 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
337 GetRewrittenEventAsString(&rewriter,
339 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
340 ui::ET_KEY_PRESSED));
342 // XK_KP_Begin (= NumPad 5 without Num Lock), Alt modifier.
343 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD5,
344 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
346 GetRewrittenEventAsString(&rewriter,
348 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
349 ui::ET_KEY_PRESSED));
351 // XK_KP_Right (= NumPad 6 without Num Lock), Alt modifier.
352 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD6,
353 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
355 GetRewrittenEventAsString(&rewriter,
357 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
358 ui::ET_KEY_PRESSED));
360 // XK_KP_Home (= NumPad 7 without Num Lock), Alt modifier.
361 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD7,
362 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
364 GetRewrittenEventAsString(&rewriter,
366 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
367 ui::ET_KEY_PRESSED));
369 // XK_KP_Up (= NumPad 8 without Num Lock), Alt modifier.
370 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD8,
371 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
373 GetRewrittenEventAsString(&rewriter,
375 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
376 ui::ET_KEY_PRESSED));
378 // XK_KP_Prior (= NumPad 9 without Num Lock), Alt modifier.
379 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD9,
380 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
382 GetRewrittenEventAsString(&rewriter,
384 ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
385 ui::ET_KEY_PRESSED));
387 // XK_KP_0 (= NumPad 0 with Num Lock), Num Lock modifier.
389 GetExpectedResultAsString(
390 ui::VKEY_NUMPAD0, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
391 GetRewrittenEventAsString(
392 &rewriter, ui::VKEY_NUMPAD0, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
394 // XK_KP_DECIMAL (= NumPad . with Num Lock), Num Lock modifier.
396 GetExpectedResultAsString(
397 ui::VKEY_DECIMAL, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
398 GetRewrittenEventAsString(
399 &rewriter, ui::VKEY_DECIMAL, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
401 // XK_KP_1 (= NumPad 1 with Num Lock), Num Lock modifier.
403 GetExpectedResultAsString(
404 ui::VKEY_NUMPAD1, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
405 GetRewrittenEventAsString(
406 &rewriter, ui::VKEY_NUMPAD1, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
408 // XK_KP_2 (= NumPad 2 with Num Lock), Num Lock modifier.
410 GetExpectedResultAsString(
411 ui::VKEY_NUMPAD2, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
412 GetRewrittenEventAsString(
413 &rewriter, ui::VKEY_NUMPAD2, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
415 // XK_KP_3 (= NumPad 3 with Num Lock), Num Lock modifier.
417 GetExpectedResultAsString(
418 ui::VKEY_NUMPAD3, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
419 GetRewrittenEventAsString(
420 &rewriter, ui::VKEY_NUMPAD3, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
422 // XK_KP_4 (= NumPad 4 with Num Lock), Num Lock modifier.
424 GetExpectedResultAsString(
425 ui::VKEY_NUMPAD4, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
426 GetRewrittenEventAsString(
427 &rewriter, ui::VKEY_NUMPAD4, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
429 // XK_KP_5 (= NumPad 5 with Num Lock), Num Lock modifier.
431 GetExpectedResultAsString(
432 ui::VKEY_NUMPAD5, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
433 GetRewrittenEventAsString(
434 &rewriter, ui::VKEY_NUMPAD5, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
436 // XK_KP_6 (= NumPad 6 with Num Lock), Num Lock modifier.
438 GetExpectedResultAsString(
439 ui::VKEY_NUMPAD6, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
440 GetRewrittenEventAsString(
441 &rewriter, ui::VKEY_NUMPAD6, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
443 // XK_KP_7 (= NumPad 7 with Num Lock), Num Lock modifier.
445 GetExpectedResultAsString(
446 ui::VKEY_NUMPAD7, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
447 GetRewrittenEventAsString(
448 &rewriter, ui::VKEY_NUMPAD7, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
450 // XK_KP_8 (= NumPad 8 with Num Lock), Num Lock modifier.
452 GetExpectedResultAsString(
453 ui::VKEY_NUMPAD8, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
454 GetRewrittenEventAsString(
455 &rewriter, ui::VKEY_NUMPAD8, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
457 // XK_KP_9 (= NumPad 9 with Num Lock), Num Lock modifier.
459 GetExpectedResultAsString(
460 ui::VKEY_NUMPAD9, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
461 GetRewrittenEventAsString(
462 &rewriter, ui::VKEY_NUMPAD9, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
465 TEST_F(EventRewriterTest, TestRewriteNumPadKeys) {
466 TestRewriteNumPadKeys();
469 TEST_F(EventRewriterTest, TestRewriteNumPadKeysWithDiamondKeyFlag) {
470 // Make sure the num lock works correctly even when Diamond key exists.
471 const CommandLine original_cl(*CommandLine::ForCurrentProcess());
472 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
473 chromeos::switches::kHasChromeOSDiamondKey, "");
475 TestRewriteNumPadKeys();
476 *CommandLine::ForCurrentProcess() = original_cl;
479 // Tests if the rewriter can handle a Command + Num Pad event.
480 void EventRewriterTest::TestRewriteNumPadKeysOnAppleKeyboard() {
481 TestingPrefServiceSyncable prefs;
482 EventRewriter rewriter;
483 rewriter.DeviceAddedForTesting(0, "Apple Keyboard");
484 rewriter.set_last_device_id_for_testing(0);
485 rewriter.set_pref_service_for_testing(&prefs);
487 // XK_KP_End (= NumPad 1 without Num Lock), Win modifier.
488 // The result should be "Num Pad 1 with Control + Num Lock modifiers".
489 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD1,
490 ui::EF_CONTROL_DOWN | ui::EF_NUMPAD_KEY,
492 GetRewrittenEventAsString(&rewriter,
494 ui::EF_COMMAND_DOWN | ui::EF_NUMPAD_KEY,
495 ui::ET_KEY_PRESSED));
497 // XK_KP_1 (= NumPad 1 with Num Lock), Win modifier.
498 // The result should also be "Num Pad 1 with Control + Num Lock modifiers".
499 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD1,
500 ui::EF_CONTROL_DOWN | ui::EF_NUMPAD_KEY,
502 GetRewrittenEventAsString(&rewriter,
504 ui::EF_COMMAND_DOWN | ui::EF_NUMPAD_KEY,
505 ui::ET_KEY_PRESSED));
508 TEST_F(EventRewriterTest, TestRewriteNumPadKeysOnAppleKeyboard) {
509 TestRewriteNumPadKeysOnAppleKeyboard();
512 TEST_F(EventRewriterTest,
513 TestRewriteNumPadKeysOnAppleKeyboardWithDiamondKeyFlag) {
514 // Makes sure the num lock works correctly even when Diamond key exists.
515 const CommandLine original_cl(*CommandLine::ForCurrentProcess());
516 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
517 chromeos::switches::kHasChromeOSDiamondKey, "");
519 TestRewriteNumPadKeysOnAppleKeyboard();
520 *CommandLine::ForCurrentProcess() = original_cl;
523 TEST_F(EventRewriterTest, TestRewriteModifiersNoRemap) {
524 TestingPrefServiceSyncable prefs;
525 EventRewriter rewriter;
526 rewriter.set_pref_service_for_testing(&prefs);
528 // Press Search. Confirm the event is not rewritten.
529 EXPECT_EQ(GetExpectedResultAsString(
530 ui::VKEY_LWIN, ui::EF_COMMAND_DOWN, ui::ET_KEY_PRESSED),
531 GetRewrittenEventAsString(
532 &rewriter, ui::VKEY_LWIN, ui::EF_NONE, ui::ET_KEY_PRESSED));
534 // Press left Control. Confirm the event is not rewritten.
535 EXPECT_EQ(GetExpectedResultAsString(
536 ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
537 GetRewrittenEventAsString(&rewriter,
540 ui::ET_KEY_PRESSED));
542 // Press right Control. Confirm the event is not rewritten.
543 EXPECT_EQ(GetExpectedResultAsString(
544 ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
545 GetRewrittenEventAsString(&rewriter,
548 ui::ET_KEY_PRESSED));
550 // Press left Alt. Confirm the event is not rewritten.
551 EXPECT_EQ(GetExpectedResultAsString(
552 ui::VKEY_MENU, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED),
553 GetRewrittenEventAsString(
554 &rewriter, ui::VKEY_MENU, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED));
556 // Press right Alt. Confirm the event is not rewritten.
557 EXPECT_EQ(GetExpectedResultAsString(
558 ui::VKEY_MENU, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED),
559 GetRewrittenEventAsString(
560 &rewriter, ui::VKEY_MENU, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED));
562 // Test KeyRelease event, just in case.
563 // Release Search. Confirm the release event is not rewritten.
564 EXPECT_EQ(GetExpectedResultAsString(
565 ui::VKEY_LWIN, ui::EF_NONE, ui::ET_KEY_RELEASED),
566 GetRewrittenEventAsString(
567 &rewriter, ui::VKEY_LWIN, ui::EF_NONE, ui::ET_KEY_RELEASED));
570 TEST_F(EventRewriterTest, TestRewriteModifiersNoRemapMultipleKeys) {
571 TestingPrefServiceSyncable prefs;
572 EventRewriter rewriter;
573 rewriter.set_pref_service_for_testing(&prefs);
575 // Press Alt with Shift. Confirm the event is not rewritten.
576 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
577 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
579 GetRewrittenEventAsString(&rewriter,
581 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
582 ui::ET_KEY_PRESSED));
584 // Press Search with Caps Lock mask. Confirm the event is not rewritten.
586 GetExpectedResultAsString(ui::VKEY_LWIN,
587 ui::EF_CAPS_LOCK_DOWN | ui::EF_COMMAND_DOWN,
589 GetRewrittenEventAsString(&rewriter,
591 ui::EF_CAPS_LOCK_DOWN | ui::EF_COMMAND_DOWN,
592 ui::ET_KEY_PRESSED));
594 // Release Search with Caps Lock mask. Confirm the event is not rewritten.
595 EXPECT_EQ(GetExpectedResultAsString(
596 ui::VKEY_LWIN, ui::EF_CAPS_LOCK_DOWN, ui::ET_KEY_RELEASED),
597 GetRewrittenEventAsString(&rewriter,
599 ui::EF_CAPS_LOCK_DOWN,
600 ui::ET_KEY_RELEASED));
602 // Press Shift+Ctrl+Alt+Search+A. Confirm the event is not rewritten.
603 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_B,
604 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
605 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
607 GetRewrittenEventAsString(&rewriter,
609 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
610 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
611 ui::ET_KEY_PRESSED));
614 TEST_F(EventRewriterTest, TestRewriteModifiersDisableSome) {
615 // Disable Search and Control keys.
616 TestingPrefServiceSyncable prefs;
617 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
618 IntegerPrefMember search;
619 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
620 search.SetValue(chromeos::input_method::kVoidKey);
621 IntegerPrefMember control;
622 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
623 control.SetValue(chromeos::input_method::kVoidKey);
625 EventRewriter rewriter;
626 rewriter.set_pref_service_for_testing(&prefs);
628 // Press Alt with Shift. This key press shouldn't be affected by the
629 // pref. Confirm the event is not rewritten.
630 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
631 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
633 GetRewrittenEventAsString(&rewriter,
635 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
636 ui::ET_KEY_PRESSED));
638 // Press Search. Confirm the event is now VKEY_UNKNOWN.
639 EXPECT_EQ(GetExpectedResultAsString(
640 ui::VKEY_UNKNOWN, ui::EF_NONE, ui::ET_KEY_PRESSED),
641 GetRewrittenEventAsString(
642 &rewriter, ui::VKEY_LWIN, ui::EF_NONE, ui::ET_KEY_PRESSED));
644 // Press Control. Confirm the event is now VKEY_UNKNOWN.
645 EXPECT_EQ(GetExpectedResultAsString(
646 ui::VKEY_UNKNOWN, ui::EF_NONE, ui::ET_KEY_PRESSED),
647 GetRewrittenEventAsString(
648 &rewriter, ui::VKEY_CONTROL, ui::EF_NONE, ui::ET_KEY_PRESSED));
650 // Press Control+Search. Confirm the event is now VKEY_UNKNOWN
651 // without any modifiers.
653 GetExpectedResultAsString(
654 ui::VKEY_UNKNOWN, ui::EF_NONE, ui::ET_KEY_PRESSED),
655 GetRewrittenEventAsString(
656 &rewriter, ui::VKEY_LWIN, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED));
658 // Press Control+Search+a. Confirm the event is now VKEY_A without any
661 GetExpectedResultAsString(ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED),
662 GetRewrittenEventAsString(
663 &rewriter, ui::VKEY_A, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED));
665 // Press Control+Search+Alt+a. Confirm the event is now VKEY_A only with
667 EXPECT_EQ(GetExpectedResultAsString(
668 ui::VKEY_A, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED),
669 GetRewrittenEventAsString(&rewriter,
671 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
672 ui::ET_KEY_PRESSED));
674 // Remap Alt to Control.
675 IntegerPrefMember alt;
676 alt.Init(prefs::kLanguageRemapAltKeyTo, &prefs);
677 alt.SetValue(chromeos::input_method::kControlKey);
679 // Press left Alt. Confirm the event is now VKEY_CONTROL
680 // even though the Control key itself is disabled.
681 EXPECT_EQ(GetExpectedResultAsString(
682 ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
683 GetRewrittenEventAsString(
684 &rewriter, ui::VKEY_MENU, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED));
686 // Press Alt+a. Confirm the event is now Control+a even though the Control
687 // key itself is disabled.
688 EXPECT_EQ(GetExpectedResultAsString(
689 ui::VKEY_A, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
690 GetRewrittenEventAsString(
691 &rewriter, ui::VKEY_A, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED));
694 TEST_F(EventRewriterTest, TestRewriteModifiersRemapToControl) {
695 // Remap Search to Control.
696 TestingPrefServiceSyncable prefs;
697 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
698 IntegerPrefMember search;
699 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
700 search.SetValue(chromeos::input_method::kControlKey);
702 EventRewriter rewriter;
703 rewriter.set_pref_service_for_testing(&prefs);
705 // Press Search. Confirm the event is now VKEY_CONTROL.
707 GetExpectedResultAsString(
708 ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
709 GetRewrittenEventAsString(
710 &rewriter, ui::VKEY_LWIN, ui::EF_COMMAND_DOWN, ui::ET_KEY_PRESSED));
712 // Remap Alt to Control too.
713 IntegerPrefMember alt;
714 alt.Init(prefs::kLanguageRemapAltKeyTo, &prefs);
715 alt.SetValue(chromeos::input_method::kControlKey);
717 // Press Alt. Confirm the event is now VKEY_CONTROL.
718 EXPECT_EQ(GetExpectedResultAsString(
719 ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
720 GetRewrittenEventAsString(
721 &rewriter, ui::VKEY_MENU, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED));
723 // Press Alt+Search. Confirm the event is now VKEY_CONTROL.
724 EXPECT_EQ(GetExpectedResultAsString(
725 ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
726 GetRewrittenEventAsString(&rewriter,
728 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
729 ui::ET_KEY_PRESSED));
731 // Press Control+Alt+Search. Confirm the event is now VKEY_CONTROL.
732 EXPECT_EQ(GetExpectedResultAsString(
733 ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
734 GetRewrittenEventAsString(
737 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
738 ui::ET_KEY_PRESSED));
740 // Press Shift+Control+Alt+Search. Confirm the event is now Control with
741 // Shift and Control modifiers.
742 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
743 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
745 GetRewrittenEventAsString(&rewriter,
747 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
748 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
749 ui::ET_KEY_PRESSED));
751 // Press Shift+Control+Alt+Search+B. Confirm the event is now B with Shift
752 // and Control modifiers.
753 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_B,
754 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
756 GetRewrittenEventAsString(&rewriter,
758 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
759 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
760 ui::ET_KEY_PRESSED));
763 TEST_F(EventRewriterTest, TestRewriteModifiersRemapToEscape) {
764 // Remap Search to ESC.
765 TestingPrefServiceSyncable prefs;
766 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
767 IntegerPrefMember search;
768 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
769 search.SetValue(chromeos::input_method::kEscapeKey);
771 EventRewriter rewriter;
772 rewriter.set_pref_service_for_testing(&prefs);
774 // Press Search. Confirm the event is now VKEY_ESCAPE.
776 GetExpectedResultAsString(
777 ui::VKEY_ESCAPE, ui::EF_NONE, ui::ET_KEY_PRESSED),
778 GetRewrittenEventAsString(
779 &rewriter, ui::VKEY_LWIN, ui::EF_COMMAND_DOWN, ui::ET_KEY_PRESSED));
782 TEST_F(EventRewriterTest, TestRewriteModifiersRemapMany) {
783 // Remap Search to Alt.
784 TestingPrefServiceSyncable prefs;
785 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
786 IntegerPrefMember search;
787 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
788 search.SetValue(chromeos::input_method::kAltKey);
790 EventRewriter rewriter;
791 rewriter.set_pref_service_for_testing(&prefs);
793 // Press Search. Confirm the event is now VKEY_MENU.
795 GetExpectedResultAsString(
796 ui::VKEY_MENU, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED),
797 GetRewrittenEventAsString(
798 &rewriter, ui::VKEY_LWIN, ui::EF_COMMAND_DOWN, ui::ET_KEY_PRESSED));
800 // Remap Alt to Control.
801 IntegerPrefMember alt;
802 alt.Init(prefs::kLanguageRemapAltKeyTo, &prefs);
803 alt.SetValue(chromeos::input_method::kControlKey);
805 // Press left Alt. Confirm the event is now VKEY_CONTROL.
806 EXPECT_EQ(GetExpectedResultAsString(
807 ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
808 GetRewrittenEventAsString(
809 &rewriter, ui::VKEY_MENU, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED));
811 // Remap Control to Search.
812 IntegerPrefMember control;
813 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
814 control.SetValue(chromeos::input_method::kSearchKey);
816 // Press left Control. Confirm the event is now VKEY_LWIN.
817 EXPECT_EQ(GetExpectedResultAsString(
818 ui::VKEY_LWIN, ui::EF_COMMAND_DOWN, ui::ET_KEY_PRESSED),
819 GetRewrittenEventAsString(&rewriter,
822 ui::ET_KEY_PRESSED));
824 // Then, press all of the three, Control+Alt+Search.
825 EXPECT_EQ(GetExpectedResultAsString(
827 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
829 GetRewrittenEventAsString(
832 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
833 ui::ET_KEY_PRESSED));
835 // Press Shift+Control+Alt+Search.
836 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
837 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
838 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
840 GetRewrittenEventAsString(&rewriter,
842 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
843 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
844 ui::ET_KEY_PRESSED));
846 // Press Shift+Control+Alt+Search+B
847 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_B,
848 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
849 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
851 GetRewrittenEventAsString(&rewriter,
853 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
854 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
855 ui::ET_KEY_PRESSED));
858 TEST_F(EventRewriterTest, TestRewriteModifiersRemapToCapsLock) {
859 // Remap Search to Caps Lock.
860 TestingPrefServiceSyncable prefs;
861 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
862 IntegerPrefMember search;
863 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
864 search.SetValue(chromeos::input_method::kCapsLockKey);
866 chromeos::input_method::FakeImeKeyboard ime_keyboard;
867 EventRewriter rewriter;
868 rewriter.set_pref_service_for_testing(&prefs);
869 rewriter.set_ime_keyboard_for_testing(&ime_keyboard);
870 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
874 GetExpectedResultAsString(
875 ui::VKEY_CAPITAL, ui::EF_CAPS_LOCK_DOWN, ui::ET_KEY_PRESSED),
876 GetRewrittenEventAsString(
877 &rewriter, ui::VKEY_LWIN, ui::EF_COMMAND_DOWN, ui::ET_KEY_PRESSED));
878 // Confirm that the Caps Lock status is changed.
879 EXPECT_TRUE(ime_keyboard.caps_lock_is_enabled_);
882 EXPECT_EQ(GetExpectedResultAsString(
883 ui::VKEY_CAPITAL, ui::EF_NONE, ui::ET_KEY_RELEASED),
884 GetRewrittenEventAsString(
885 &rewriter, ui::VKEY_LWIN, ui::EF_NONE, ui::ET_KEY_RELEASED));
886 // Confirm that the Caps Lock status is not changed.
887 EXPECT_TRUE(ime_keyboard.caps_lock_is_enabled_);
891 GetExpectedResultAsString(
892 ui::VKEY_CAPITAL, ui::EF_CAPS_LOCK_DOWN, ui::ET_KEY_PRESSED),
893 GetRewrittenEventAsString(&rewriter,
895 ui::EF_COMMAND_DOWN | ui::EF_CAPS_LOCK_DOWN,
896 ui::ET_KEY_PRESSED));
897 // Confirm that the Caps Lock status is changed.
898 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
901 EXPECT_EQ(GetExpectedResultAsString(
902 ui::VKEY_CAPITAL, ui::EF_NONE, ui::ET_KEY_RELEASED),
903 GetRewrittenEventAsString(
904 &rewriter, ui::VKEY_LWIN, ui::EF_NONE, ui::ET_KEY_RELEASED));
905 // Confirm that the Caps Lock status is not changed.
906 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
908 // Press Caps Lock (on an external keyboard).
909 EXPECT_EQ(GetExpectedResultAsString(
910 ui::VKEY_CAPITAL, ui::EF_CAPS_LOCK_DOWN, ui::ET_KEY_PRESSED),
911 GetRewrittenEventAsString(&rewriter,
913 ui::EF_CAPS_LOCK_DOWN,
914 ui::ET_KEY_PRESSED));
916 // Confirm that calling RewriteForTesting() does not change the state of
917 // |ime_keyboard|. In this case, X Window system itself should change the
918 // Caps Lock state, not ash::EventRewriter.
919 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
921 // Release Caps Lock (on an external keyboard).
922 EXPECT_EQ(GetExpectedResultAsString(
923 ui::VKEY_CAPITAL, ui::EF_NONE, ui::ET_KEY_RELEASED),
924 GetRewrittenEventAsString(
925 &rewriter, ui::VKEY_CAPITAL, ui::EF_NONE, ui::ET_KEY_RELEASED));
926 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
929 TEST_F(EventRewriterTest, TestRewriteCapsLock) {
930 TestingPrefServiceSyncable prefs;
931 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
933 chromeos::input_method::FakeImeKeyboard ime_keyboard;
934 EventRewriter rewriter;
935 rewriter.set_pref_service_for_testing(&prefs);
936 rewriter.set_ime_keyboard_for_testing(&ime_keyboard);
937 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
939 // On Chrome OS, CapsLock is mapped to F16 with Mod3Mask.
940 EXPECT_EQ(GetExpectedResultAsString(
941 ui::VKEY_CAPITAL, ui::EF_CAPS_LOCK_DOWN, ui::ET_KEY_PRESSED),
942 GetRewrittenEventAsString(
943 &rewriter, ui::VKEY_F16, ui::EF_NONE, ui::ET_KEY_PRESSED));
944 EXPECT_TRUE(ime_keyboard.caps_lock_is_enabled_);
947 TEST_F(EventRewriterTest, TestRewriteDiamondKey) {
948 TestingPrefServiceSyncable prefs;
949 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
951 chromeos::input_method::FakeImeKeyboard ime_keyboard;
952 EventRewriter rewriter;
953 rewriter.set_pref_service_for_testing(&prefs);
954 rewriter.set_ime_keyboard_for_testing(&ime_keyboard);
956 // F15 should work as Ctrl when --has-chromeos-diamond-key is not specified.
957 EXPECT_EQ(GetExpectedResultAsString(
958 ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
959 GetRewrittenEventAsString(
960 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_PRESSED));
962 // However, Mod2Mask should not be rewritten to CtrlMask when
963 // --has-chromeos-diamond-key is not specified.
965 GetExpectedResultAsString(ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED),
966 GetRewrittenEventAsString(
967 &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
970 TEST_F(EventRewriterTest, TestRewriteDiamondKeyWithFlag) {
971 const CommandLine original_cl(*CommandLine::ForCurrentProcess());
972 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
973 chromeos::switches::kHasChromeOSDiamondKey, "");
975 TestingPrefServiceSyncable prefs;
976 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
978 chromeos::input_method::FakeImeKeyboard ime_keyboard;
979 EventRewriter rewriter;
980 rewriter.set_pref_service_for_testing(&prefs);
981 rewriter.set_ime_keyboard_for_testing(&ime_keyboard);
983 // By default, F15 should work as Control.
984 EXPECT_EQ(GetExpectedResultAsString(
985 ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
986 GetRewrittenEventAsString(
987 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_PRESSED));
989 IntegerPrefMember diamond;
990 diamond.Init(prefs::kLanguageRemapDiamondKeyTo, &prefs);
991 diamond.SetValue(chromeos::input_method::kVoidKey);
993 EXPECT_EQ(GetExpectedResultAsString(
994 ui::VKEY_UNKNOWN, ui::EF_NONE, ui::ET_KEY_PRESSED),
995 GetRewrittenEventAsString(
996 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_PRESSED));
998 diamond.SetValue(chromeos::input_method::kControlKey);
1000 EXPECT_EQ(GetExpectedResultAsString(
1001 ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
1002 GetRewrittenEventAsString(
1003 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_PRESSED));
1005 diamond.SetValue(chromeos::input_method::kAltKey);
1007 EXPECT_EQ(GetExpectedResultAsString(
1008 ui::VKEY_MENU, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED),
1009 GetRewrittenEventAsString(
1010 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_PRESSED));
1012 diamond.SetValue(chromeos::input_method::kCapsLockKey);
1014 EXPECT_EQ(GetExpectedResultAsString(
1015 ui::VKEY_CAPITAL, ui::EF_CAPS_LOCK_DOWN, ui::ET_KEY_PRESSED),
1016 GetRewrittenEventAsString(
1017 &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_PRESSED));
1019 *CommandLine::ForCurrentProcess() = original_cl;
1022 TEST_F(EventRewriterTest, TestRewriteCapsLockToControl) {
1023 // Remap CapsLock to Control.
1024 TestingPrefServiceSyncable prefs;
1025 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1026 IntegerPrefMember control;
1027 control.Init(prefs::kLanguageRemapCapsLockKeyTo, &prefs);
1028 control.SetValue(chromeos::input_method::kControlKey);
1030 EventRewriter rewriter;
1031 rewriter.set_pref_service_for_testing(&prefs);
1033 // Press CapsLock+a. Confirm that Mod3Mask is rewritten to ControlMask.
1034 // On Chrome OS, CapsLock works as a Mod3 modifier.
1036 GetExpectedResultAsString(
1037 ui::VKEY_A, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
1038 GetRewrittenEventAsString(
1039 &rewriter, ui::VKEY_A, ui::EF_CAPS_LOCK_DOWN, ui::ET_KEY_PRESSED));
1041 // Press Control+CapsLock+a. Confirm that Mod3Mask is rewritten to ControlMask
1043 GetExpectedResultAsString(
1044 ui::VKEY_A, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
1045 GetRewrittenEventAsString(
1046 &rewriter, ui::VKEY_A, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED));
1048 // Press Alt+CapsLock+a. Confirm that Mod3Mask is rewritten to ControlMask.
1049 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
1050 ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
1051 ui::ET_KEY_PRESSED),
1052 GetRewrittenEventAsString(&rewriter,
1054 ui::EF_ALT_DOWN | ui::EF_CAPS_LOCK_DOWN,
1055 ui::ET_KEY_PRESSED));
1058 TEST_F(EventRewriterTest, TestRewriteCapsLockMod3InUse) {
1059 // Remap CapsLock to Control.
1060 TestingPrefServiceSyncable prefs;
1061 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1062 IntegerPrefMember control;
1063 control.Init(prefs::kLanguageRemapCapsLockKeyTo, &prefs);
1064 control.SetValue(chromeos::input_method::kControlKey);
1066 EventRewriter rewriter;
1067 rewriter.set_pref_service_for_testing(&prefs);
1068 input_method_manager_mock_->set_mod3_used(true);
1070 // Press CapsLock+a. Confirm that Mod3Mask is NOT rewritten to ControlMask
1071 // when Mod3Mask is already in use by the current XKB layout.
1073 GetExpectedResultAsString(ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED),
1074 GetRewrittenEventAsString(
1075 &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
1077 input_method_manager_mock_->set_mod3_used(false);
1080 TEST_F(EventRewriterTest, TestRewriteExtendedKeys) {
1081 TestingPrefServiceSyncable prefs;
1082 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1083 EventRewriter rewriter;
1084 rewriter.DeviceAddedForTesting(0, "PC Keyboard");
1085 rewriter.set_last_device_id_for_testing(0);
1086 rewriter.set_pref_service_for_testing(&prefs);
1089 ui::KeyboardCode input;
1090 unsigned int input_mods;
1091 ui::KeyboardCode output;
1092 unsigned int output_mods;
1093 } chromeos_tests[] = {
1094 // Alt+Backspace -> Delete
1095 {ui::VKEY_BACK, ui::EF_ALT_DOWN, ui::VKEY_DELETE, ui::EF_NONE},
1096 // Control+Alt+Backspace -> Control+Delete
1097 {ui::VKEY_BACK, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, ui::VKEY_DELETE,
1098 ui::EF_CONTROL_DOWN},
1099 // Search+Alt+Backspace -> Alt+Backspace
1100 {ui::VKEY_BACK, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::VKEY_BACK,
1102 // Search+Control+Alt+Backspace -> Control+Alt+Backspace
1104 ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
1105 ui::VKEY_BACK, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN},
1107 {ui::VKEY_UP, ui::EF_ALT_DOWN, ui::VKEY_PRIOR, ui::EF_NONE},
1109 {ui::VKEY_DOWN, ui::EF_ALT_DOWN, ui::VKEY_NEXT, ui::EF_NONE},
1110 // Ctrl+Alt+Up -> Home
1111 {ui::VKEY_UP, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, ui::VKEY_HOME,
1113 // Ctrl+Alt+Down -> End
1114 {ui::VKEY_DOWN, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, ui::VKEY_END,
1117 // Search+Alt+Up -> Alt+Up
1118 {ui::VKEY_UP, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::VKEY_UP,
1120 // Search+Alt+Down -> Alt+Down
1121 {ui::VKEY_DOWN, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::VKEY_DOWN,
1123 // Search+Ctrl+Alt+Up -> Search+Ctrl+Alt+Up
1125 ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
1126 ui::VKEY_UP, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN},
1127 // Search+Ctrl+Alt+Down -> Ctrl+Alt+Down
1129 ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
1130 ui::VKEY_DOWN, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN},
1133 {ui::VKEY_OEM_PERIOD, ui::EF_NONE, ui::VKEY_OEM_PERIOD, ui::EF_NONE},
1135 // Search+Backspace -> Delete
1136 {ui::VKEY_BACK, ui::EF_COMMAND_DOWN, ui::VKEY_DELETE, ui::EF_NONE},
1137 // Search+Up -> Prior
1138 {ui::VKEY_UP, ui::EF_COMMAND_DOWN, ui::VKEY_PRIOR, ui::EF_NONE},
1139 // Search+Down -> Next
1140 {ui::VKEY_DOWN, ui::EF_COMMAND_DOWN, ui::VKEY_NEXT, ui::EF_NONE},
1141 // Search+Left -> Home
1142 {ui::VKEY_LEFT, ui::EF_COMMAND_DOWN, ui::VKEY_HOME, ui::EF_NONE},
1143 // Control+Search+Left -> Home
1144 {ui::VKEY_LEFT, ui::EF_COMMAND_DOWN | ui::EF_CONTROL_DOWN,
1145 ui::VKEY_HOME, ui::EF_CONTROL_DOWN},
1146 // Search+Right -> End
1147 {ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN, ui::VKEY_END, ui::EF_NONE},
1148 // Control+Search+Right -> End
1149 {ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN | ui::EF_CONTROL_DOWN,
1150 ui::VKEY_END, ui::EF_CONTROL_DOWN},
1151 // Search+Period -> Insert
1152 {ui::VKEY_OEM_PERIOD, ui::EF_COMMAND_DOWN, ui::VKEY_INSERT,
1154 // Control+Search+Period -> Control+Insert
1155 {ui::VKEY_OEM_PERIOD, ui::EF_COMMAND_DOWN | ui::EF_CONTROL_DOWN,
1156 ui::VKEY_INSERT, ui::EF_CONTROL_DOWN}};
1158 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(chromeos_tests); ++i) {
1159 EXPECT_EQ(GetExpectedResultNumbered(i,
1160 chromeos_tests[i].output,
1161 chromeos_tests[i].output_mods,
1162 ui::ET_KEY_PRESSED),
1163 GetRewrittenEventNumbered(i,
1165 chromeos_tests[i].input,
1166 chromeos_tests[i].input_mods,
1167 ui::ET_KEY_PRESSED));
1171 TEST_F(EventRewriterTest, TestRewriteFunctionKeys) {
1172 TestingPrefServiceSyncable prefs;
1173 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1174 EventRewriter rewriter;
1175 rewriter.set_pref_service_for_testing(&prefs);
1178 ui::KeyboardCode input;
1179 unsigned int input_mods;
1180 ui::KeyboardCode output;
1181 unsigned int output_mods;
1184 {ui::VKEY_F1, ui::EF_NONE, ui::VKEY_BROWSER_BACK, ui::EF_NONE},
1185 {ui::VKEY_F1, ui::EF_CONTROL_DOWN, ui::VKEY_BROWSER_BACK,
1186 ui::EF_CONTROL_DOWN},
1187 {ui::VKEY_F1, ui::EF_ALT_DOWN, ui::VKEY_BROWSER_BACK, ui::EF_ALT_DOWN},
1189 {ui::VKEY_F2, ui::EF_NONE, ui::VKEY_BROWSER_FORWARD, ui::EF_NONE},
1190 {ui::VKEY_F2, ui::EF_CONTROL_DOWN, ui::VKEY_BROWSER_FORWARD,
1191 ui::EF_CONTROL_DOWN},
1192 {ui::VKEY_F2, ui::EF_ALT_DOWN, ui::VKEY_BROWSER_FORWARD,
1195 {ui::VKEY_F3, ui::EF_NONE, ui::VKEY_BROWSER_REFRESH, ui::EF_NONE},
1196 {ui::VKEY_F3, ui::EF_CONTROL_DOWN, ui::VKEY_BROWSER_REFRESH,
1197 ui::EF_CONTROL_DOWN},
1198 {ui::VKEY_F3, ui::EF_ALT_DOWN, ui::VKEY_BROWSER_REFRESH,
1200 // F4 -> Launch App 2
1201 {ui::VKEY_F4, ui::EF_NONE, ui::VKEY_MEDIA_LAUNCH_APP2, ui::EF_NONE},
1202 {ui::VKEY_F4, ui::EF_CONTROL_DOWN, ui::VKEY_MEDIA_LAUNCH_APP2,
1203 ui::EF_CONTROL_DOWN},
1204 {ui::VKEY_F4, ui::EF_ALT_DOWN, ui::VKEY_MEDIA_LAUNCH_APP2,
1206 // F5 -> Launch App 1
1207 {ui::VKEY_F5, ui::EF_NONE, ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_NONE},
1208 {ui::VKEY_F5, ui::EF_CONTROL_DOWN, ui::VKEY_MEDIA_LAUNCH_APP1,
1209 ui::EF_CONTROL_DOWN},
1210 {ui::VKEY_F5, ui::EF_ALT_DOWN, ui::VKEY_MEDIA_LAUNCH_APP1,
1212 // F6 -> Brightness down
1213 {ui::VKEY_F6, ui::EF_NONE, ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE},
1214 {ui::VKEY_F6, ui::EF_CONTROL_DOWN, ui::VKEY_BRIGHTNESS_DOWN,
1215 ui::EF_CONTROL_DOWN},
1216 {ui::VKEY_F6, ui::EF_ALT_DOWN, ui::VKEY_BRIGHTNESS_DOWN,
1218 // F7 -> Brightness up
1219 {ui::VKEY_F7, ui::EF_NONE, ui::VKEY_BRIGHTNESS_UP, ui::EF_NONE},
1220 {ui::VKEY_F7, ui::EF_CONTROL_DOWN, ui::VKEY_BRIGHTNESS_UP,
1221 ui::EF_CONTROL_DOWN},
1222 {ui::VKEY_F7, ui::EF_ALT_DOWN, ui::VKEY_BRIGHTNESS_UP, ui::EF_ALT_DOWN},
1223 // F8 -> Volume Mute
1224 {ui::VKEY_F8, ui::EF_NONE, ui::VKEY_VOLUME_MUTE, ui::EF_NONE},
1225 {ui::VKEY_F8, ui::EF_CONTROL_DOWN, ui::VKEY_VOLUME_MUTE,
1226 ui::EF_CONTROL_DOWN},
1227 {ui::VKEY_F8, ui::EF_ALT_DOWN, ui::VKEY_VOLUME_MUTE, ui::EF_ALT_DOWN},
1228 // F9 -> Volume Down
1229 {ui::VKEY_F9, ui::EF_NONE, ui::VKEY_VOLUME_DOWN, ui::EF_NONE},
1230 {ui::VKEY_F9, ui::EF_CONTROL_DOWN, ui::VKEY_VOLUME_DOWN,
1231 ui::EF_CONTROL_DOWN},
1232 {ui::VKEY_F9, ui::EF_ALT_DOWN, ui::VKEY_VOLUME_DOWN, ui::EF_ALT_DOWN},
1234 {ui::VKEY_F10, ui::EF_NONE, ui::VKEY_VOLUME_UP, ui::EF_NONE},
1235 {ui::VKEY_F10, ui::EF_CONTROL_DOWN, ui::VKEY_VOLUME_UP,
1236 ui::EF_CONTROL_DOWN},
1237 {ui::VKEY_F10, ui::EF_ALT_DOWN, ui::VKEY_VOLUME_UP, ui::EF_ALT_DOWN},
1239 {ui::VKEY_F11, ui::EF_NONE, ui::VKEY_F11, ui::EF_NONE},
1240 {ui::VKEY_F11, ui::EF_CONTROL_DOWN, ui::VKEY_F11, ui::EF_CONTROL_DOWN},
1241 {ui::VKEY_F11, ui::EF_ALT_DOWN, ui::VKEY_F11, ui::EF_ALT_DOWN},
1243 {ui::VKEY_F12, ui::EF_NONE, ui::VKEY_F12, ui::EF_NONE},
1244 {ui::VKEY_F12, ui::EF_CONTROL_DOWN, ui::VKEY_F12, ui::EF_CONTROL_DOWN},
1245 {ui::VKEY_F12, ui::EF_ALT_DOWN, ui::VKEY_F12, ui::EF_ALT_DOWN},
1247 // The number row should not be rewritten without Search key.
1248 {ui::VKEY_1, ui::EF_NONE, ui::VKEY_1, ui::EF_NONE},
1249 {ui::VKEY_2, ui::EF_NONE, ui::VKEY_2, ui::EF_NONE},
1250 {ui::VKEY_3, ui::EF_NONE, ui::VKEY_3, ui::EF_NONE},
1251 {ui::VKEY_4, ui::EF_NONE, ui::VKEY_4, ui::EF_NONE},
1252 {ui::VKEY_5, ui::EF_NONE, ui::VKEY_5, ui::EF_NONE},
1253 {ui::VKEY_6, ui::EF_NONE, ui::VKEY_6, ui::EF_NONE},
1254 {ui::VKEY_7, ui::EF_NONE, ui::VKEY_7, ui::EF_NONE},
1255 {ui::VKEY_8, ui::EF_NONE, ui::VKEY_8, ui::EF_NONE},
1256 {ui::VKEY_9, ui::EF_NONE, ui::VKEY_9, ui::EF_NONE},
1257 {ui::VKEY_0, ui::EF_NONE, ui::VKEY_0, ui::EF_NONE},
1258 {ui::VKEY_OEM_MINUS, ui::EF_NONE, ui::VKEY_OEM_MINUS, ui::EF_NONE},
1259 {ui::VKEY_OEM_PLUS, ui::EF_NONE, ui::VKEY_OEM_PLUS, ui::EF_NONE},
1261 // The number row should be rewritten as the F<number> row with Search
1263 {ui::VKEY_1, ui::EF_COMMAND_DOWN, ui::VKEY_F1, ui::EF_NONE},
1264 {ui::VKEY_2, ui::EF_COMMAND_DOWN, ui::VKEY_F2, ui::EF_NONE},
1265 {ui::VKEY_3, ui::EF_COMMAND_DOWN, ui::VKEY_F3, ui::EF_NONE},
1266 {ui::VKEY_4, ui::EF_COMMAND_DOWN, ui::VKEY_F4, ui::EF_NONE},
1267 {ui::VKEY_5, ui::EF_COMMAND_DOWN, ui::VKEY_F5, ui::EF_NONE},
1268 {ui::VKEY_6, ui::EF_COMMAND_DOWN, ui::VKEY_F6, ui::EF_NONE},
1269 {ui::VKEY_7, ui::EF_COMMAND_DOWN, ui::VKEY_F7, ui::EF_NONE},
1270 {ui::VKEY_8, ui::EF_COMMAND_DOWN, ui::VKEY_F8, ui::EF_NONE},
1271 {ui::VKEY_9, ui::EF_COMMAND_DOWN, ui::VKEY_F9, ui::EF_NONE},
1272 {ui::VKEY_0, ui::EF_COMMAND_DOWN, ui::VKEY_F10, ui::EF_NONE},
1273 {ui::VKEY_OEM_MINUS, ui::EF_COMMAND_DOWN, ui::VKEY_F11, ui::EF_NONE},
1274 {ui::VKEY_OEM_PLUS, ui::EF_COMMAND_DOWN, ui::VKEY_F12, ui::EF_NONE},
1276 // The function keys should not be rewritten with Search key pressed.
1277 {ui::VKEY_F1, ui::EF_COMMAND_DOWN, ui::VKEY_F1, ui::EF_NONE},
1278 {ui::VKEY_F2, ui::EF_COMMAND_DOWN, ui::VKEY_F2, ui::EF_NONE},
1279 {ui::VKEY_F3, ui::EF_COMMAND_DOWN, ui::VKEY_F3, ui::EF_NONE},
1280 {ui::VKEY_F4, ui::EF_COMMAND_DOWN, ui::VKEY_F4, ui::EF_NONE},
1281 {ui::VKEY_F5, ui::EF_COMMAND_DOWN, ui::VKEY_F5, ui::EF_NONE},
1282 {ui::VKEY_F6, ui::EF_COMMAND_DOWN, ui::VKEY_F6, ui::EF_NONE},
1283 {ui::VKEY_F7, ui::EF_COMMAND_DOWN, ui::VKEY_F7, ui::EF_NONE},
1284 {ui::VKEY_F8, ui::EF_COMMAND_DOWN, ui::VKEY_F8, ui::EF_NONE},
1285 {ui::VKEY_F9, ui::EF_COMMAND_DOWN, ui::VKEY_F9, ui::EF_NONE},
1286 {ui::VKEY_F10, ui::EF_COMMAND_DOWN, ui::VKEY_F10, ui::EF_NONE},
1287 {ui::VKEY_F11, ui::EF_COMMAND_DOWN, ui::VKEY_F11, ui::EF_NONE},
1288 {ui::VKEY_F12, ui::EF_COMMAND_DOWN, ui::VKEY_F12, ui::EF_NONE},
1291 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
1292 EXPECT_EQ(GetExpectedResultNumbered(
1293 i, tests[i].output, tests[i].output_mods, ui::ET_KEY_PRESSED),
1294 GetRewrittenEventNumbered(i,
1297 tests[i].input_mods,
1298 ui::ET_KEY_PRESSED));
1302 TEST_F(EventRewriterTest, TestRewriteExtendedKeysWithSearchRemapped) {
1303 const CommandLine original_cl(*CommandLine::ForCurrentProcess());
1305 // Remap Search to Control.
1306 TestingPrefServiceSyncable prefs;
1307 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1308 IntegerPrefMember search;
1309 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
1310 search.SetValue(chromeos::input_method::kControlKey);
1312 EventRewriter rewriter;
1313 rewriter.set_pref_service_for_testing(&prefs);
1315 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1316 chromeos::switches::kHasChromeOSKeyboard, "");
1318 // Alt+Search+Down -> End
1320 GetExpectedResultAsString(ui::VKEY_END, ui::EF_NONE, ui::ET_KEY_PRESSED),
1321 GetRewrittenEventAsString(&rewriter,
1323 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
1324 ui::ET_KEY_PRESSED));
1326 // Shift+Alt+Search+Down -> Shift+End
1327 EXPECT_EQ(GetExpectedResultAsString(
1328 ui::VKEY_END, ui::EF_SHIFT_DOWN, ui::ET_KEY_PRESSED),
1329 GetRewrittenEventAsString(
1332 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
1333 ui::ET_KEY_PRESSED));
1335 *CommandLine::ForCurrentProcess() = original_cl;
1338 TEST_F(EventRewriterTest, TestRewriteKeyEventSentByXSendEvent) {
1339 // Remap Control to Alt.
1340 TestingPrefServiceSyncable prefs;
1341 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1342 IntegerPrefMember control;
1343 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
1344 control.SetValue(chromeos::input_method::kAltKey);
1346 EventRewriter rewriter;
1347 rewriter.set_pref_service_for_testing(&prefs);
1349 // Send left control press.
1350 std::string rewritten_event;
1352 ui::ScopedXI2Event xev;
1353 xev.InitKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_CONTROL, 0);
1354 XEvent* xevent = xev;
1355 xevent->xkey.keycode = XKeysymToKeycode(gfx::GetXDisplay(), XK_Control_L);
1356 xevent->xkey.send_event = True; // XSendEvent() always does this.
1357 ui::KeyEvent keyevent(xev, false /* is_char */);
1358 scoped_ptr<ui::Event> new_event;
1359 // Control should NOT be remapped to Alt if send_event
1360 // flag in the event is True.
1361 EXPECT_EQ(ui::EVENT_REWRITE_CONTINUE,
1362 rewriter.RewriteEvent(keyevent, &new_event));
1363 EXPECT_FALSE(new_event);
1367 TEST_F(EventRewriterTest, TestRewriteNonNativeEvent) {
1368 // Remap Control to Alt.
1369 TestingPrefServiceSyncable prefs;
1370 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1371 IntegerPrefMember control;
1372 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
1373 control.SetValue(chromeos::input_method::kAltKey);
1375 EventRewriter rewriter;
1376 rewriter.set_pref_service_for_testing(&prefs);
1378 const int kTouchId = 2;
1379 gfx::Point location(0, 0);
1380 ui::TouchEvent press(
1381 ui::ET_TOUCH_PRESSED, location, kTouchId, base::TimeDelta());
1382 press.set_flags(ui::EF_CONTROL_DOWN);
1384 scoped_ptr<ui::Event> new_event;
1385 rewriter.RewriteEvent(press, &new_event);
1386 EXPECT_TRUE(new_event);
1387 // Control should be remapped to Alt.
1388 EXPECT_EQ(ui::EF_ALT_DOWN,
1389 new_event->flags() & (ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN));
1392 // Tests of event rewriting that depend on the Ash window manager.
1393 class EventRewriterAshTest : public ash::test::AshTestBase {
1395 EventRewriterAshTest()
1396 : mock_user_manager_(new chromeos::MockUserManager),
1397 user_manager_enabler_(mock_user_manager_) {}
1398 virtual ~EventRewriterAshTest() {}
1400 bool RewriteFunctionKeys(const ui::Event& event,
1401 scoped_ptr<ui::Event>* rewritten_event) {
1402 return rewriter_->RewriteEvent(event, rewritten_event);
1406 virtual void SetUp() OVERRIDE {
1407 AshTestBase::SetUp();
1408 rewriter_.reset(new EventRewriter());
1409 chromeos::Preferences::RegisterProfilePrefs(prefs_.registry());
1410 rewriter_->set_pref_service_for_testing(&prefs_);
1413 virtual void TearDown() OVERRIDE {
1415 AshTestBase::TearDown();
1418 TestingPrefServiceSyncable prefs_;
1421 scoped_ptr<EventRewriter> rewriter_;
1423 chromeos::MockUserManager* mock_user_manager_; // Not owned.
1424 chromeos::ScopedUserManagerEnabler user_manager_enabler_;
1426 DISALLOW_COPY_AND_ASSIGN(EventRewriterAshTest);
1429 TEST_F(EventRewriterAshTest, TopRowKeysAreFunctionKeys) {
1430 scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(1));
1431 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window.get());
1432 window_state->Activate();
1434 // Create a simulated keypress of F1 targetted at the window.
1435 ui::KeyEvent press_f1(ui::ET_KEY_PRESSED, ui::VKEY_F1, 0, false);
1437 // Simulate an apps v2 window that has requested top row keys as function
1438 // keys. The event should not be rewritten.
1439 window_state->set_top_row_keys_are_function_keys(true);
1440 scoped_ptr<ui::Event> rewritten_event;
1441 ASSERT_FALSE(RewriteFunctionKeys(press_f1, &rewritten_event));
1442 ASSERT_FALSE(rewritten_event);
1444 GetExpectedResultAsString(ui::VKEY_F1, ui::EF_NONE, ui::ET_KEY_PRESSED),
1445 GetKeyEventAsString(press_f1));
1447 // The event should also not be rewritten if the send-function-keys pref is
1448 // additionally set, for both apps v2 and regular windows.
1449 BooleanPrefMember send_function_keys_pref;
1450 send_function_keys_pref.Init(prefs::kLanguageSendFunctionKeys, &prefs_);
1451 send_function_keys_pref.SetValue(true);
1452 window_state->set_top_row_keys_are_function_keys(false);
1453 ASSERT_FALSE(RewriteFunctionKeys(press_f1, &rewritten_event));
1454 ASSERT_FALSE(rewritten_event);
1456 GetExpectedResultAsString(ui::VKEY_F1, ui::EF_NONE, ui::ET_KEY_PRESSED),
1457 GetKeyEventAsString(press_f1));
1459 // If the pref isn't set when an event is sent to a regular window, F1 is
1460 // rewritten to the back key.
1461 send_function_keys_pref.SetValue(false);
1462 ASSERT_TRUE(RewriteFunctionKeys(press_f1, &rewritten_event));
1463 ASSERT_TRUE(rewritten_event);
1464 EXPECT_EQ(GetExpectedResultAsString(
1465 ui::VKEY_BROWSER_BACK, ui::EF_NONE, ui::ET_KEY_PRESSED),
1466 GetKeyEventAsString(
1467 *static_cast<const ui::KeyEvent*>(rewritten_event.get())));
1470 TEST_F(EventRewriterTest, DontRewriteIfNotRewritten) {
1471 std::vector<unsigned int> device_list;
1472 device_list.push_back(10);
1473 device_list.push_back(11);
1474 ui::TouchFactory::GetInstance()->SetPointerDeviceForTest(device_list);
1475 TestingPrefServiceSyncable prefs;
1476 EventRewriter rewriter;
1477 rewriter.set_pref_service_for_testing(&prefs);
1478 const int kLeftAndAltFlag = ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN;
1480 ui::ScopedXI2Event xev;
1481 xev.InitGenericButtonEvent(
1482 10, ui::ET_MOUSE_PRESSED, gfx::Point(), kLeftAndAltFlag);
1483 ui::MouseEvent press(xev);
1485 EXPECT_EQ(ui::ET_MOUSE_PRESSED, press.type());
1486 EXPECT_EQ(kLeftAndAltFlag, press.flags());
1487 int flags = RewriteMouseEvent(&rewriter, press);
1488 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & flags);
1491 ui::ScopedXI2Event xev;
1492 xev.InitGenericButtonEvent(
1493 10, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
1494 ui::MouseEvent release(xev);
1495 int flags = RewriteMouseEvent(&rewriter, release);
1496 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & flags);
1499 // No ALT in frst click.
1501 ui::ScopedXI2Event xev;
1502 xev.InitGenericButtonEvent(
1503 10, ui::ET_MOUSE_PRESSED, gfx::Point(), ui::EF_LEFT_MOUSE_BUTTON);
1504 ui::MouseEvent press(xev);
1505 int flags = RewriteMouseEvent(&rewriter, press);
1506 EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & flags);
1509 ui::ScopedXI2Event xev;
1510 xev.InitGenericButtonEvent(
1511 10, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
1512 ui::MouseEvent release(xev);
1513 int flags = RewriteMouseEvent(&rewriter, release);
1514 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN) & flags);
1517 // ALT on different device.
1519 ui::ScopedXI2Event xev;
1520 xev.InitGenericButtonEvent(
1521 11, ui::ET_MOUSE_PRESSED, gfx::Point(), kLeftAndAltFlag);
1522 ui::MouseEvent press(xev);
1523 int flags = RewriteMouseEvent(&rewriter, press);
1524 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & flags);
1527 ui::ScopedXI2Event xev;
1528 xev.InitGenericButtonEvent(
1529 10, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
1530 ui::MouseEvent release(xev);
1531 int flags = RewriteMouseEvent(&rewriter, release);
1532 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN) & flags);
1535 ui::ScopedXI2Event xev;
1536 xev.InitGenericButtonEvent(
1537 11, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
1538 ui::MouseEvent release(xev);
1539 int flags = RewriteMouseEvent(&rewriter, release);
1540 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & flags);
1544 } // namespace chromeos