1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/events/event_rewriter.h"
10 #include "ash/sticky_keys/sticky_keys_controller.h"
11 #include "ash/sticky_keys/sticky_keys_overlay.h"
12 #include "ash/test/ash_test_base.h"
13 #include "ash/wm/window_state.h"
14 #include "base/basictypes.h"
15 #include "base/command_line.h"
16 #include "base/prefs/pref_member.h"
17 #include "base/strings/stringprintf.h"
18 #include "chrome/browser/chromeos/input_method/input_method_configuration.h"
19 #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h"
20 #include "chrome/browser/chromeos/login/users/fake_user_manager.h"
21 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
22 #include "chrome/browser/chromeos/preferences.h"
23 #include "chrome/common/pref_names.h"
24 #include "chrome/test/base/testing_pref_service_syncable.h"
25 #include "chromeos/chromeos_switches.h"
26 #include "chromeos/ime/fake_ime_keyboard.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "ui/aura/window.h"
29 #include "ui/aura/window_tree_host.h"
30 #include "ui/events/event.h"
31 #include "ui/events/event_rewriter.h"
32 #include "ui/events/test/events_test_utils.h"
33 #include "ui/events/test/test_event_processor.h"
36 #include <X11/keysym.h>
38 #include "ui/events/event_utils.h"
39 #include "ui/events/test/events_test_utils_x11.h"
40 #include "ui/events/x/touch_factory_x11.h"
41 #include "ui/gfx/x/x11_types.h"
46 // The device id of the test touchpad device.
47 const unsigned int kTouchPadDeviceId
= 1;
48 const int kKeyboardDeviceId
= 2;
49 const int kMasterKeyboardDeviceId
= 3;
51 std::string
GetExpectedResultAsString(ui::KeyboardCode ui_keycode
,
53 ui::EventType ui_type
) {
54 return base::StringPrintf("ui_keycode=0x%X ui_flags=0x%X ui_type=%d",
56 ui_flags
& ~ui::EF_IS_REPEAT
,
60 std::string
GetKeyEventAsString(const ui::KeyEvent
& keyevent
) {
61 return GetExpectedResultAsString(
62 keyevent
.key_code(), keyevent
.flags(), keyevent
.type());
65 std::string
GetRewrittenEventAsString(chromeos::EventRewriter
* rewriter
,
66 ui::KeyboardCode ui_keycode
,
68 ui::EventType ui_type
) {
69 const ui::KeyEvent
event(ui_type
, ui_keycode
, ui_flags
);
70 scoped_ptr
<ui::Event
> new_event
;
71 rewriter
->RewriteEvent(event
, &new_event
);
73 return GetKeyEventAsString(
74 static_cast<const ui::KeyEvent
&>(*new_event
.get()));
75 return GetKeyEventAsString(event
);
78 // Table entry for simple single key event rewriting tests.
82 TEST_VKEY
= 1 << 0, // Test ui::KeyEvent with no native event
83 TEST_X11
= 1 << 1, // Test ui::KeyEvent with native XKeyEvent
84 TEST_ALL
= TEST_VKEY
|TEST_X11
,
85 // Special test flags:
86 NUMPAD
= 1 << 8, // Set EF_NUMPAD_KEY on native-based event, because
87 // |XKeysymForWindowsKeyCode()| can not distinguish
88 // between pairs like XK_Insert and XK_KP_Insert.
93 ui::KeyboardCode key_code
;
99 // Check rewriting of an X11-based key event.
100 void CheckX11KeyTestCase(const std::string
& expected
,
101 chromeos::EventRewriter
* rewriter
,
102 const KeyTestCase
& test
,
104 ui::KeyEvent
xkey_event(xevent
);
105 if (test
.test
& KeyTestCase::NUMPAD
)
106 xkey_event
.set_flags(xkey_event
.flags() | ui::EF_NUMPAD_KEY
);
107 // Verify that the X11-based key event is as expected.
108 EXPECT_EQ(GetExpectedResultAsString(
109 test
.input
.key_code
, test
.input
.flags
, test
.type
),
110 GetKeyEventAsString(xkey_event
));
111 // Rewrite the event and check the result.
112 scoped_ptr
<ui::Event
> new_event
;
113 rewriter
->RewriteEvent(xkey_event
, &new_event
);
114 ui::KeyEvent
& rewritten_key_event
=
115 new_event
? *static_cast<ui::KeyEvent
*>(new_event
.get()) : xkey_event
;
116 EXPECT_EQ(expected
, GetKeyEventAsString(rewritten_key_event
));
117 if ((rewritten_key_event
.key_code() != ui::VKEY_UNKNOWN
) &&
118 (rewritten_key_event
.native_event()->xkey
.keycode
!= 0)) {
119 // Build a new ui::KeyEvent from the rewritten native component,
120 // and check that it also matches the rewritten event.
121 EXPECT_TRUE(rewritten_key_event
.native_event());
122 ui::KeyEvent
from_native_event(rewritten_key_event
.native_event());
123 EXPECT_EQ(expected
, GetKeyEventAsString(from_native_event
));
128 // Tests a single stateless key rewrite operation.
129 // |i| is a an identifying number to locate failing tests in the tables.
130 void CheckKeyTestCase(chromeos::EventRewriter
* rewriter
,
131 const KeyTestCase
& test
) {
132 std::string expected
=
133 GetExpectedResultAsString(
134 test
.expected
.key_code
, test
.expected
.flags
, test
.type
);
136 if (test
.test
& KeyTestCase::TEST_VKEY
) {
137 // Check rewriting of a non-native-based key event.
140 GetRewrittenEventAsString(
141 rewriter
, test
.input
.key_code
, test
.input
.flags
, test
.type
));
145 if (test
.test
& KeyTestCase::TEST_X11
) {
146 ui::ScopedXI2Event xev
;
147 // Test an XKeyEvent.
148 xev
.InitKeyEvent(test
.type
, test
.input
.key_code
, test
.input
.flags
);
149 XEvent
* xevent
= xev
;
150 DCHECK((xevent
->type
== KeyPress
) || (xevent
->type
== KeyRelease
));
151 if (xevent
->xkey
.keycode
)
152 CheckX11KeyTestCase(expected
, rewriter
, test
, xevent
);
153 // Test an XI2 GenericEvent.
154 xev
.InitGenericKeyEvent(kMasterKeyboardDeviceId
,
160 DCHECK(xevent
->type
== GenericEvent
);
161 XIDeviceEvent
* xievent
= static_cast<XIDeviceEvent
*>(xevent
->xcookie
.data
);
162 DCHECK((xievent
->evtype
== XI_KeyPress
) ||
163 (xievent
->evtype
== XI_KeyRelease
));
165 CheckX11KeyTestCase(expected
, rewriter
, test
, xevent
);
170 // Table entry for simple single function key event rewriting tests.
171 struct FunctionKeyTestCase
{
174 ui::KeyboardCode key_code
;
176 } input
, vkey_expected
, native_expected
;
179 // Tests a single stateless function key rewrite operation.
180 // |i| is a an identifying number to locate failing tests in the tables.
181 // Function key mapping differs from the other key mappings because the
182 // EF_FUNCTION_KEY flag is set during ui::KeyEvent construction when passing in
183 // a native X11 event and the flag is not set when using other constructors.
184 void CheckFunctionKeyTestCase(chromeos::EventRewriter
* rewriter
,
185 const FunctionKeyTestCase
& test
) {
186 std::string vkey_expected
=
187 GetExpectedResultAsString(
188 test
.vkey_expected
.key_code
,
189 test
.vkey_expected
.flags
,
191 // Check rewriting of a non-native-based key event.
194 GetRewrittenEventAsString(
195 rewriter
, test
.input
.key_code
, test
.input
.flags
, test
.type
));
198 ui::ScopedXI2Event xev
;
199 xev
.InitKeyEvent(test
.type
, test
.input
.key_code
, test
.input
.flags
);
200 XEvent
* xevent
= xev
;
201 if (xevent
->xkey
.keycode
) {
202 ui::KeyEvent
xkey_event(xevent
);
203 // Rewrite the event and check the result.
204 scoped_ptr
<ui::Event
> new_event
;
205 rewriter
->RewriteEvent(xkey_event
, &new_event
);
206 ui::KeyEvent
& rewritten_key_event
=
207 new_event
? *static_cast<ui::KeyEvent
*>(new_event
.get()) : xkey_event
;
208 std::string native_expected
=
209 GetExpectedResultAsString(
210 test
.native_expected
.key_code
,
211 test
.native_expected
.flags
,
213 EXPECT_EQ(native_expected
, GetKeyEventAsString(rewritten_key_event
));
222 class EventRewriterTest
: public ash::test::AshTestBase
{
225 : fake_user_manager_(new chromeos::FakeUserManager
),
226 user_manager_enabler_(fake_user_manager_
),
227 input_method_manager_mock_(NULL
) {}
228 virtual ~EventRewriterTest() {}
230 virtual void SetUp() {
231 input_method_manager_mock_
=
232 new chromeos::input_method::MockInputMethodManager
;
233 chromeos::input_method::InitializeForTesting(
234 input_method_manager_mock_
); // pass ownership
236 AshTestBase::SetUp();
239 virtual void TearDown() {
240 AshTestBase::TearDown();
241 // Shutdown() deletes the IME mock object.
242 chromeos::input_method::Shutdown();
246 void TestRewriteNumPadKeys();
247 void TestRewriteNumPadKeysOnAppleKeyboard();
249 const ui::MouseEvent
* RewriteMouseButtonEvent(
250 chromeos::EventRewriter
* rewriter
,
251 const ui::MouseEvent
& event
,
252 scoped_ptr
<ui::Event
>* new_event
) {
253 rewriter
->RewriteMouseButtonEventForTesting(event
, new_event
);
254 return *new_event
? static_cast<const ui::MouseEvent
*>(new_event
->get())
258 chromeos::FakeUserManager
* fake_user_manager_
; // Not owned.
259 chromeos::ScopedUserManagerEnabler user_manager_enabler_
;
260 chromeos::input_method::MockInputMethodManager
* input_method_manager_mock_
;
263 TEST_F(EventRewriterTest
, TestRewriteCommandToControl
) {
264 // First, test with a PC keyboard.
265 TestingPrefServiceSyncable prefs
;
266 EventRewriter
rewriter(NULL
);
267 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
268 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
269 rewriter
.set_pref_service_for_testing(&prefs
);
271 KeyTestCase pc_keyboard_tests
[] = {
272 // VKEY_A, Alt modifier.
273 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
274 {ui::VKEY_A
, ui::EF_ALT_DOWN
},
275 {ui::VKEY_A
, ui::EF_ALT_DOWN
}},
277 // VKEY_A, Win modifier.
278 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
279 {ui::VKEY_A
, ui::EF_COMMAND_DOWN
},
280 {ui::VKEY_A
, ui::EF_COMMAND_DOWN
}},
282 // VKEY_A, Alt+Win modifier.
283 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
284 {ui::VKEY_A
, ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
},
285 {ui::VKEY_A
, ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
}},
287 // VKEY_LWIN (left Windows key), Alt modifier.
288 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
289 {ui::VKEY_LWIN
, ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
},
290 {ui::VKEY_LWIN
, ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
}},
292 // VKEY_RWIN (right Windows key), Alt modifier.
293 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
294 {ui::VKEY_RWIN
, ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
},
295 {ui::VKEY_RWIN
, ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
}},
298 for (size_t i
= 0; i
< arraysize(pc_keyboard_tests
); ++i
) {
300 CheckKeyTestCase(&rewriter
, pc_keyboard_tests
[i
]);
303 // An Apple keyboard reusing the ID, zero.
304 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "Apple Keyboard");
305 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
307 KeyTestCase apple_keyboard_tests
[] = {
308 // VKEY_A, Alt modifier.
309 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
310 {ui::VKEY_A
, ui::EF_ALT_DOWN
},
311 {ui::VKEY_A
, ui::EF_ALT_DOWN
}},
313 // VKEY_A, Win modifier.
314 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
315 {ui::VKEY_A
, ui::EF_COMMAND_DOWN
},
316 {ui::VKEY_A
, ui::EF_CONTROL_DOWN
}},
318 // VKEY_A, Alt+Win modifier.
319 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
320 {ui::VKEY_A
, ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
},
321 {ui::VKEY_A
, ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
}},
323 // VKEY_LWIN (left Windows key), Alt modifier.
324 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
325 {ui::VKEY_LWIN
, ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
},
326 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
}},
328 // VKEY_RWIN (right Windows key), Alt modifier.
329 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
330 {ui::VKEY_RWIN
, ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
},
331 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
}},
334 for (size_t i
= 0; i
< arraysize(apple_keyboard_tests
); ++i
) {
336 CheckKeyTestCase(&rewriter
, apple_keyboard_tests
[i
]);
340 // For crbug.com/133896.
341 TEST_F(EventRewriterTest
, TestRewriteCommandToControlWithControlRemapped
) {
342 // Remap Control to Alt.
343 TestingPrefServiceSyncable prefs
;
344 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
345 IntegerPrefMember control
;
346 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
347 control
.SetValue(chromeos::input_method::kAltKey
);
349 EventRewriter
rewriter(NULL
);
350 rewriter
.set_pref_service_for_testing(&prefs
);
351 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
352 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
354 KeyTestCase pc_keyboard_tests
[] = {// Control should be remapped to Alt.
355 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
356 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
},
357 {ui::VKEY_MENU
, ui::EF_ALT_DOWN
}},
360 for (size_t i
= 0; i
< arraysize(pc_keyboard_tests
); ++i
) {
362 CheckKeyTestCase(&rewriter
, pc_keyboard_tests
[i
]);
365 // An Apple keyboard reusing the ID, zero.
366 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "Apple Keyboard");
367 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
369 KeyTestCase apple_keyboard_tests
[] = {
370 // VKEY_LWIN (left Command key) with Alt modifier. The remapped Command
371 // key should never be re-remapped to Alt.
372 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
373 {ui::VKEY_LWIN
, ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
},
374 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
}},
376 // VKEY_RWIN (right Command key) with Alt modifier. The remapped Command
377 // key should never be re-remapped to Alt.
378 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
379 {ui::VKEY_RWIN
, ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
},
380 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
}},
383 for (size_t i
= 0; i
< arraysize(apple_keyboard_tests
); ++i
) {
385 CheckKeyTestCase(&rewriter
, apple_keyboard_tests
[i
]);
389 void EventRewriterTest::TestRewriteNumPadKeys() {
390 TestingPrefServiceSyncable prefs
;
391 EventRewriter
rewriter(NULL
);
392 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
393 rewriter
.set_pref_service_for_testing(&prefs
);
395 KeyTestCase tests
[] = {
396 // XK_KP_Insert (= NumPad 0 without Num Lock), no modifier.
397 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
398 {ui::VKEY_INSERT
, ui::EF_NUMPAD_KEY
},
399 {ui::VKEY_NUMPAD0
, ui::EF_NUMPAD_KEY
}},
401 // XK_KP_Insert (= NumPad 0 without Num Lock), Alt modifier.
402 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
403 {ui::VKEY_INSERT
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
},
404 {ui::VKEY_NUMPAD0
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
}},
406 // XK_KP_Delete (= NumPad . without Num Lock), Alt modifier.
407 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
408 {ui::VKEY_DELETE
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
},
409 {ui::VKEY_DECIMAL
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
}},
411 // XK_KP_End (= NumPad 1 without Num Lock), Alt modifier.
412 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
413 {ui::VKEY_END
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
},
414 {ui::VKEY_NUMPAD1
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
}},
416 // XK_KP_Down (= NumPad 2 without Num Lock), Alt modifier.
417 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
418 {ui::VKEY_DOWN
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
},
419 {ui::VKEY_NUMPAD2
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
}},
421 // XK_KP_Next (= NumPad 3 without Num Lock), Alt modifier.
422 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
423 {ui::VKEY_NEXT
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
},
424 {ui::VKEY_NUMPAD3
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
}},
426 // XK_KP_Left (= NumPad 4 without Num Lock), Alt modifier.
427 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
428 {ui::VKEY_LEFT
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
},
429 {ui::VKEY_NUMPAD4
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
}},
431 // XK_KP_Begin (= NumPad 5 without Num Lock), Alt modifier.
432 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
433 {ui::VKEY_CLEAR
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
},
434 {ui::VKEY_NUMPAD5
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
}},
436 // XK_KP_Right (= NumPad 6 without Num Lock), Alt modifier.
437 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
438 {ui::VKEY_RIGHT
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
},
439 {ui::VKEY_NUMPAD6
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
}},
441 // XK_KP_Home (= NumPad 7 without Num Lock), Alt modifier.
442 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
443 {ui::VKEY_HOME
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
},
444 {ui::VKEY_NUMPAD7
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
}},
446 // XK_KP_Up (= NumPad 8 without Num Lock), Alt modifier.
447 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
448 {ui::VKEY_UP
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
},
449 {ui::VKEY_NUMPAD8
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
}},
451 // XK_KP_Prior (= NumPad 9 without Num Lock), Alt modifier.
452 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
453 {ui::VKEY_PRIOR
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
},
454 {ui::VKEY_NUMPAD9
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
}},
456 // XK_KP_0 (= NumPad 0 with Num Lock), Num Lock modifier.
457 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
458 {ui::VKEY_NUMPAD0
, ui::EF_NUMPAD_KEY
},
459 {ui::VKEY_NUMPAD0
, ui::EF_NUMPAD_KEY
}},
461 // XK_KP_DECIMAL (= NumPad . with Num Lock), Num Lock modifier.
462 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
463 {ui::VKEY_DECIMAL
, ui::EF_NUMPAD_KEY
},
464 {ui::VKEY_DECIMAL
, ui::EF_NUMPAD_KEY
}},
466 // XK_KP_1 (= NumPad 1 with Num Lock), Num Lock modifier.
467 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
468 {ui::VKEY_NUMPAD1
, ui::EF_NUMPAD_KEY
},
469 {ui::VKEY_NUMPAD1
, ui::EF_NUMPAD_KEY
}},
471 // XK_KP_2 (= NumPad 2 with Num Lock), Num Lock modifier.
472 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
473 {ui::VKEY_NUMPAD2
, ui::EF_NUMPAD_KEY
},
474 {ui::VKEY_NUMPAD2
, ui::EF_NUMPAD_KEY
}},
476 // XK_KP_3 (= NumPad 3 with Num Lock), Num Lock modifier.
477 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
478 {ui::VKEY_NUMPAD3
, ui::EF_NUMPAD_KEY
},
479 {ui::VKEY_NUMPAD3
, ui::EF_NUMPAD_KEY
}},
481 // XK_KP_4 (= NumPad 4 with Num Lock), Num Lock modifier.
482 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
483 {ui::VKEY_NUMPAD4
, ui::EF_NUMPAD_KEY
},
484 {ui::VKEY_NUMPAD4
, ui::EF_NUMPAD_KEY
}},
486 // XK_KP_5 (= NumPad 5 with Num Lock), Num Lock modifier.
487 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
488 {ui::VKEY_NUMPAD5
, ui::EF_NUMPAD_KEY
},
489 {ui::VKEY_NUMPAD5
, ui::EF_NUMPAD_KEY
}},
491 // XK_KP_6 (= NumPad 6 with Num Lock), Num Lock modifier.
492 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
493 {ui::VKEY_NUMPAD6
, ui::EF_NUMPAD_KEY
},
494 {ui::VKEY_NUMPAD6
, ui::EF_NUMPAD_KEY
}},
496 // XK_KP_7 (= NumPad 7 with Num Lock), Num Lock modifier.
497 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
498 {ui::VKEY_NUMPAD7
, ui::EF_NUMPAD_KEY
},
499 {ui::VKEY_NUMPAD7
, ui::EF_NUMPAD_KEY
}},
501 // XK_KP_8 (= NumPad 8 with Num Lock), Num Lock modifier.
502 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
503 {ui::VKEY_NUMPAD8
, ui::EF_NUMPAD_KEY
},
504 {ui::VKEY_NUMPAD8
, ui::EF_NUMPAD_KEY
}},
506 // XK_KP_9 (= NumPad 9 with Num Lock), Num Lock modifier.
507 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
508 {ui::VKEY_NUMPAD9
, ui::EF_NUMPAD_KEY
},
509 {ui::VKEY_NUMPAD9
, ui::EF_NUMPAD_KEY
}},
512 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
514 CheckKeyTestCase(&rewriter
, tests
[i
]);
518 TEST_F(EventRewriterTest
, TestRewriteNumPadKeys
) {
519 TestRewriteNumPadKeys();
522 TEST_F(EventRewriterTest
, TestRewriteNumPadKeysWithDiamondKeyFlag
) {
523 // Make sure the num lock works correctly even when Diamond key exists.
524 const CommandLine
original_cl(*CommandLine::ForCurrentProcess());
525 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
526 chromeos::switches::kHasChromeOSDiamondKey
, "");
528 TestRewriteNumPadKeys();
529 *CommandLine::ForCurrentProcess() = original_cl
;
532 // Tests if the rewriter can handle a Command + Num Pad event.
533 void EventRewriterTest::TestRewriteNumPadKeysOnAppleKeyboard() {
534 TestingPrefServiceSyncable prefs
;
535 EventRewriter
rewriter(NULL
);
536 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "Apple Keyboard");
537 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
538 rewriter
.set_pref_service_for_testing(&prefs
);
540 KeyTestCase tests
[] = {
541 // XK_KP_End (= NumPad 1 without Num Lock), Win modifier.
542 // The result should be "Num Pad 1 with Control + Num Lock modifiers".
543 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
544 {ui::VKEY_END
, ui::EF_COMMAND_DOWN
| ui::EF_NUMPAD_KEY
},
545 {ui::VKEY_NUMPAD1
, ui::EF_CONTROL_DOWN
| ui::EF_NUMPAD_KEY
}},
547 // XK_KP_1 (= NumPad 1 with Num Lock), Win modifier.
548 // The result should also be "Num Pad 1 with Control + Num Lock
550 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
551 {ui::VKEY_NUMPAD1
, ui::EF_COMMAND_DOWN
| ui::EF_NUMPAD_KEY
},
552 {ui::VKEY_NUMPAD1
, ui::EF_CONTROL_DOWN
| ui::EF_NUMPAD_KEY
}},
555 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
557 CheckKeyTestCase(&rewriter
, tests
[i
]);
561 TEST_F(EventRewriterTest
, TestRewriteNumPadKeysOnAppleKeyboard
) {
562 TestRewriteNumPadKeysOnAppleKeyboard();
565 TEST_F(EventRewriterTest
,
566 TestRewriteNumPadKeysOnAppleKeyboardWithDiamondKeyFlag
) {
567 // Makes sure the num lock works correctly even when Diamond key exists.
568 const CommandLine
original_cl(*CommandLine::ForCurrentProcess());
569 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
570 chromeos::switches::kHasChromeOSDiamondKey
, "");
572 TestRewriteNumPadKeysOnAppleKeyboard();
573 *CommandLine::ForCurrentProcess() = original_cl
;
576 TEST_F(EventRewriterTest
, TestRewriteModifiersNoRemap
) {
577 TestingPrefServiceSyncable prefs
;
578 EventRewriter
rewriter(NULL
);
579 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
580 rewriter
.set_pref_service_for_testing(&prefs
);
582 KeyTestCase tests
[] = {
583 // Press Search. Confirm the event is not rewritten.
584 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
585 {ui::VKEY_LWIN
, ui::EF_NONE
},
586 {ui::VKEY_LWIN
, ui::EF_COMMAND_DOWN
}},
588 // Press left Control. Confirm the event is not rewritten.
589 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
590 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
},
591 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
}},
593 // Press right Control. Confirm the event is not rewritten.
594 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
595 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
},
596 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
}},
598 // Press left Alt. Confirm the event is not rewritten.
599 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
600 {ui::VKEY_MENU
, ui::EF_ALT_DOWN
},
601 {ui::VKEY_MENU
, ui::EF_ALT_DOWN
}},
603 // Press right Alt. Confirm the event is not rewritten.
604 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
605 {ui::VKEY_MENU
, ui::EF_ALT_DOWN
},
606 {ui::VKEY_MENU
, ui::EF_ALT_DOWN
}},
608 // Test KeyRelease event, just in case.
609 // Release Search. Confirm the release event is not rewritten.
610 {KeyTestCase::TEST_ALL
, ui::ET_KEY_RELEASED
,
611 {ui::VKEY_LWIN
, ui::EF_NONE
},
612 {ui::VKEY_LWIN
, ui::EF_NONE
}},
615 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
617 CheckKeyTestCase(&rewriter
, tests
[i
]);
621 TEST_F(EventRewriterTest
, TestRewriteModifiersNoRemapMultipleKeys
) {
622 TestingPrefServiceSyncable prefs
;
623 EventRewriter
rewriter(NULL
);
624 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
625 rewriter
.set_pref_service_for_testing(&prefs
);
627 KeyTestCase tests
[] = {
628 // Press Alt with Shift. Confirm the event is not rewritten.
629 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
630 {ui::VKEY_MENU
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
},
631 {ui::VKEY_MENU
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
}},
633 // Press Search with Caps Lock mask. Confirm the event is not rewritten.
634 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
635 {ui::VKEY_LWIN
, ui::EF_CAPS_LOCK_DOWN
| ui::EF_COMMAND_DOWN
},
636 {ui::VKEY_LWIN
, ui::EF_CAPS_LOCK_DOWN
| ui::EF_COMMAND_DOWN
}},
638 // Release Search with Caps Lock mask. Confirm the event is not rewritten.
639 {KeyTestCase::TEST_ALL
, ui::ET_KEY_RELEASED
,
640 {ui::VKEY_LWIN
, ui::EF_CAPS_LOCK_DOWN
},
641 {ui::VKEY_LWIN
, ui::EF_CAPS_LOCK_DOWN
}},
643 // Press Shift+Ctrl+Alt+Search+A. Confirm the event is not rewritten.
644 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
645 {ui::VKEY_B
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
646 ui::EF_COMMAND_DOWN
},
647 {ui::VKEY_B
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
648 ui::EF_COMMAND_DOWN
}},
651 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
653 CheckKeyTestCase(&rewriter
, tests
[i
]);
657 TEST_F(EventRewriterTest
, TestRewriteModifiersDisableSome
) {
658 // Disable Search and Control keys.
659 TestingPrefServiceSyncable prefs
;
660 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
661 IntegerPrefMember search
;
662 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
663 search
.SetValue(chromeos::input_method::kVoidKey
);
664 IntegerPrefMember control
;
665 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
666 control
.SetValue(chromeos::input_method::kVoidKey
);
668 EventRewriter
rewriter(NULL
);
669 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
670 rewriter
.set_pref_service_for_testing(&prefs
);
672 KeyTestCase disabled_modifier_tests
[] = {
673 // Press Alt with Shift. This key press shouldn't be affected by the
674 // pref. Confirm the event is not rewritten.
675 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
676 {ui::VKEY_MENU
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
},
677 {ui::VKEY_MENU
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
}},
679 // Press Search. Confirm the event is now VKEY_UNKNOWN.
680 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
681 {ui::VKEY_LWIN
, ui::EF_NONE
},
682 {ui::VKEY_UNKNOWN
, ui::EF_NONE
}},
684 // Press Control. Confirm the event is now VKEY_UNKNOWN.
685 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
686 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
},
687 {ui::VKEY_UNKNOWN
, ui::EF_NONE
}},
689 // Press Control+Search. Confirm the event is now VKEY_UNKNOWN
690 // without any modifiers.
691 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
692 {ui::VKEY_LWIN
, ui::EF_CONTROL_DOWN
},
693 {ui::VKEY_UNKNOWN
, ui::EF_NONE
}},
695 // Press Control+Search+a. Confirm the event is now VKEY_A without any
697 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
698 {ui::VKEY_A
, ui::EF_CONTROL_DOWN
},
699 {ui::VKEY_A
, ui::EF_NONE
}},
701 // Press Control+Search+Alt+a. Confirm the event is now VKEY_A only with
703 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
704 {ui::VKEY_A
, ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
},
705 {ui::VKEY_A
, ui::EF_ALT_DOWN
}},
708 for (size_t i
= 0; i
< arraysize(disabled_modifier_tests
); ++i
) {
710 CheckKeyTestCase(&rewriter
, disabled_modifier_tests
[i
]);
713 // Remap Alt to Control.
714 IntegerPrefMember alt
;
715 alt
.Init(prefs::kLanguageRemapAltKeyTo
, &prefs
);
716 alt
.SetValue(chromeos::input_method::kControlKey
);
718 KeyTestCase tests
[] = {
719 // Press left Alt. Confirm the event is now VKEY_CONTROL
720 // even though the Control key itself is disabled.
721 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
722 {ui::VKEY_MENU
, ui::EF_ALT_DOWN
},
723 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
}},
725 // Press Alt+a. Confirm the event is now Control+a even though the Control
726 // key itself is disabled.
727 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
728 {ui::VKEY_A
, ui::EF_ALT_DOWN
},
729 {ui::VKEY_A
, ui::EF_CONTROL_DOWN
}},
732 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
734 CheckKeyTestCase(&rewriter
, tests
[i
]);
738 TEST_F(EventRewriterTest
, TestRewriteModifiersRemapToControl
) {
739 // Remap Search to Control.
740 TestingPrefServiceSyncable prefs
;
741 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
742 IntegerPrefMember search
;
743 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
744 search
.SetValue(chromeos::input_method::kControlKey
);
746 EventRewriter
rewriter(NULL
);
747 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
748 rewriter
.set_pref_service_for_testing(&prefs
);
750 KeyTestCase s_tests
[] = {
751 // Press Search. Confirm the event is now VKEY_CONTROL.
752 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
753 {ui::VKEY_LWIN
, ui::EF_COMMAND_DOWN
},
754 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
}},
757 for (size_t i
= 0; i
< arraysize(s_tests
); ++i
) {
759 CheckKeyTestCase(&rewriter
, s_tests
[i
]);
762 // Remap Alt to Control too.
763 IntegerPrefMember alt
;
764 alt
.Init(prefs::kLanguageRemapAltKeyTo
, &prefs
);
765 alt
.SetValue(chromeos::input_method::kControlKey
);
767 KeyTestCase sa_tests
[] = {
768 // Press Alt. Confirm the event is now VKEY_CONTROL.
769 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
770 {ui::VKEY_MENU
, ui::EF_ALT_DOWN
},
771 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
}},
773 // Press Alt+Search. Confirm the event is now VKEY_CONTROL.
774 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
775 {ui::VKEY_LWIN
, ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
},
776 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
}},
778 // Press Control+Alt+Search. Confirm the event is now VKEY_CONTROL.
779 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
781 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
},
782 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
}},
784 // Press Shift+Control+Alt+Search. Confirm the event is now Control with
785 // Shift and Control modifiers.
786 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
787 {ui::VKEY_LWIN
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
|
788 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
},
789 {ui::VKEY_CONTROL
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
}},
791 // Press Shift+Control+Alt+Search+B. Confirm the event is now B with Shift
792 // and Control modifiers.
793 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
794 {ui::VKEY_B
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
795 ui::EF_COMMAND_DOWN
},
796 {ui::VKEY_B
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
}},
799 for (size_t i
= 0; i
< arraysize(sa_tests
); ++i
) {
801 CheckKeyTestCase(&rewriter
, sa_tests
[i
]);
805 TEST_F(EventRewriterTest
, TestRewriteModifiersRemapToEscape
) {
806 // Remap Search to ESC.
807 TestingPrefServiceSyncable prefs
;
808 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
809 IntegerPrefMember search
;
810 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
811 search
.SetValue(chromeos::input_method::kEscapeKey
);
813 EventRewriter
rewriter(NULL
);
814 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
815 rewriter
.set_pref_service_for_testing(&prefs
);
817 KeyTestCase tests
[] = {// Press Search. Confirm the event is now VKEY_ESCAPE.
818 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
819 {ui::VKEY_LWIN
, ui::EF_COMMAND_DOWN
},
820 {ui::VKEY_ESCAPE
, ui::EF_NONE
}},
823 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
825 CheckKeyTestCase(&rewriter
, tests
[i
]);
829 TEST_F(EventRewriterTest
, TestRewriteModifiersRemapMany
) {
830 // Remap Search to Alt.
831 TestingPrefServiceSyncable prefs
;
832 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
833 IntegerPrefMember search
;
834 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
835 search
.SetValue(chromeos::input_method::kAltKey
);
837 EventRewriter
rewriter(NULL
);
838 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
839 rewriter
.set_pref_service_for_testing(&prefs
);
841 KeyTestCase s2a_tests
[] = {
842 // Press Search. Confirm the event is now VKEY_MENU.
843 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
844 {ui::VKEY_LWIN
, ui::EF_COMMAND_DOWN
},
845 {ui::VKEY_MENU
, ui::EF_ALT_DOWN
}},
848 for (size_t i
= 0; i
< arraysize(s2a_tests
); ++i
) {
850 CheckKeyTestCase(&rewriter
, s2a_tests
[i
]);
853 // Remap Alt to Control.
854 IntegerPrefMember alt
;
855 alt
.Init(prefs::kLanguageRemapAltKeyTo
, &prefs
);
856 alt
.SetValue(chromeos::input_method::kControlKey
);
858 KeyTestCase a2c_tests
[] = {
859 // Press left Alt. Confirm the event is now VKEY_CONTROL.
860 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
861 {ui::VKEY_MENU
, ui::EF_ALT_DOWN
},
862 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
}},
863 // Press Shift+comma. Verify that only the flags are changed.
864 // The X11 portion of the test addresses crbug.com/390263 by verifying
865 // that the X keycode remains that for ',<' and not for 105-key '<>'.
866 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
867 {ui::VKEY_OEM_COMMA
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
},
868 {ui::VKEY_OEM_COMMA
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
}},
869 // Press Shift+9. Verify that only the flags are changed.
870 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
871 {ui::VKEY_9
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
},
872 {ui::VKEY_9
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
}},
875 for (size_t i
= 0; i
< arraysize(a2c_tests
); ++i
) {
877 CheckKeyTestCase(&rewriter
, a2c_tests
[i
]);
880 // Remap Control to Search.
881 IntegerPrefMember control
;
882 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
883 control
.SetValue(chromeos::input_method::kSearchKey
);
885 KeyTestCase c2s_tests
[] = {
886 // Press left Control. Confirm the event is now VKEY_LWIN.
887 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
888 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
},
889 {ui::VKEY_LWIN
, ui::EF_COMMAND_DOWN
}},
891 // Then, press all of the three, Control+Alt+Search.
892 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
894 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
},
896 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
}},
898 // Press Shift+Control+Alt+Search.
899 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
900 {ui::VKEY_LWIN
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
|
901 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
},
902 {ui::VKEY_MENU
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
|
903 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
}},
905 // Press Shift+Control+Alt+Search+B
906 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
907 {ui::VKEY_B
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
908 ui::EF_COMMAND_DOWN
},
909 {ui::VKEY_B
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
910 ui::EF_COMMAND_DOWN
}},
913 for (size_t i
= 0; i
< arraysize(c2s_tests
); ++i
) {
915 CheckKeyTestCase(&rewriter
, c2s_tests
[i
]);
919 TEST_F(EventRewriterTest
, TestRewriteModifiersRemapToCapsLock
) {
920 // Remap Search to Caps Lock.
921 TestingPrefServiceSyncable prefs
;
922 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
923 IntegerPrefMember search
;
924 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
925 search
.SetValue(chromeos::input_method::kCapsLockKey
);
927 chromeos::input_method::FakeImeKeyboard ime_keyboard
;
928 EventRewriter
rewriter(NULL
);
929 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
930 rewriter
.set_pref_service_for_testing(&prefs
);
931 rewriter
.set_ime_keyboard_for_testing(&ime_keyboard
);
932 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
936 GetExpectedResultAsString(ui::VKEY_CAPITAL
,
937 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
939 GetRewrittenEventAsString(
940 &rewriter
, ui::VKEY_LWIN
, ui::EF_COMMAND_DOWN
, ui::ET_KEY_PRESSED
));
941 // Confirm that the Caps Lock status is changed.
942 EXPECT_TRUE(ime_keyboard
.caps_lock_is_enabled_
);
945 EXPECT_EQ(GetExpectedResultAsString(
946 ui::VKEY_CAPITAL
, ui::EF_NONE
, ui::ET_KEY_RELEASED
),
947 GetRewrittenEventAsString(
948 &rewriter
, ui::VKEY_LWIN
, ui::EF_NONE
, ui::ET_KEY_RELEASED
));
949 // Confirm that the Caps Lock status is not changed.
950 EXPECT_TRUE(ime_keyboard
.caps_lock_is_enabled_
);
954 GetExpectedResultAsString(ui::VKEY_CAPITAL
,
955 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
957 GetRewrittenEventAsString(&rewriter
,
959 ui::EF_COMMAND_DOWN
| ui::EF_CAPS_LOCK_DOWN
,
960 ui::ET_KEY_PRESSED
));
961 // Confirm that the Caps Lock status is changed.
962 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
965 EXPECT_EQ(GetExpectedResultAsString(
966 ui::VKEY_CAPITAL
, ui::EF_NONE
, ui::ET_KEY_RELEASED
),
967 GetRewrittenEventAsString(
968 &rewriter
, ui::VKEY_LWIN
, ui::EF_NONE
, ui::ET_KEY_RELEASED
));
969 // Confirm that the Caps Lock status is not changed.
970 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
972 // Press Caps Lock (on an external keyboard).
973 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL
,
974 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
976 GetRewrittenEventAsString(&rewriter
,
978 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
979 ui::ET_KEY_PRESSED
));
981 // Confirm that calling RewriteForTesting() does not change the state of
982 // |ime_keyboard|. In this case, X Window system itself should change the
983 // Caps Lock state, not ash::EventRewriter.
984 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
986 // Release Caps Lock (on an external keyboard).
987 EXPECT_EQ(GetExpectedResultAsString(
988 ui::VKEY_CAPITAL
, ui::EF_NONE
, ui::ET_KEY_RELEASED
),
989 GetRewrittenEventAsString(
990 &rewriter
, ui::VKEY_CAPITAL
, ui::EF_NONE
, ui::ET_KEY_RELEASED
));
991 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
994 TEST_F(EventRewriterTest
, TestRewriteCapsLock
) {
995 TestingPrefServiceSyncable prefs
;
996 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
998 chromeos::input_method::FakeImeKeyboard ime_keyboard
;
999 EventRewriter
rewriter(NULL
);
1000 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1001 rewriter
.set_pref_service_for_testing(&prefs
);
1002 rewriter
.set_ime_keyboard_for_testing(&ime_keyboard
);
1003 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
1005 // On Chrome OS, CapsLock is mapped to F16 with Mod3Mask.
1006 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL
,
1007 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
1008 ui::ET_KEY_PRESSED
),
1009 GetRewrittenEventAsString(
1010 &rewriter
, ui::VKEY_F16
, ui::EF_MOD3_DOWN
, ui::ET_KEY_PRESSED
));
1011 EXPECT_TRUE(ime_keyboard
.caps_lock_is_enabled_
);
1014 TEST_F(EventRewriterTest
, TestRewriteDiamondKey
) {
1015 TestingPrefServiceSyncable prefs
;
1016 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1018 chromeos::input_method::FakeImeKeyboard ime_keyboard
;
1019 EventRewriter
rewriter(NULL
);
1020 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1021 rewriter
.set_pref_service_for_testing(&prefs
);
1022 rewriter
.set_ime_keyboard_for_testing(&ime_keyboard
);
1024 KeyTestCase tests
[] = {
1025 // F15 should work as Ctrl when --has-chromeos-diamond-key is not
1027 {KeyTestCase::TEST_VKEY
,
1029 {ui::VKEY_F15
, ui::EF_NONE
},
1030 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
}},
1032 {KeyTestCase::TEST_VKEY
,
1033 ui::ET_KEY_RELEASED
,
1034 {ui::VKEY_F15
, ui::EF_NONE
},
1035 {ui::VKEY_CONTROL
, ui::EF_NONE
}},
1037 // However, Mod2Mask should not be rewritten to CtrlMask when
1038 // --has-chromeos-diamond-key is not specified.
1039 {KeyTestCase::TEST_VKEY
,
1041 {ui::VKEY_A
, ui::EF_NONE
},
1042 {ui::VKEY_A
, ui::EF_NONE
}},
1045 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
1047 CheckKeyTestCase(&rewriter
, tests
[i
]);
1051 TEST_F(EventRewriterTest
, TestRewriteDiamondKeyWithFlag
) {
1052 const CommandLine
original_cl(*CommandLine::ForCurrentProcess());
1053 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1054 chromeos::switches::kHasChromeOSDiamondKey
, "");
1056 TestingPrefServiceSyncable prefs
;
1057 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1059 chromeos::input_method::FakeImeKeyboard ime_keyboard
;
1060 EventRewriter
rewriter(NULL
);
1061 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1062 rewriter
.set_pref_service_for_testing(&prefs
);
1063 rewriter
.set_ime_keyboard_for_testing(&ime_keyboard
);
1065 // By default, F15 should work as Control.
1066 EXPECT_EQ(GetExpectedResultAsString(
1067 ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
, ui::ET_KEY_PRESSED
),
1068 GetRewrittenEventAsString(
1069 &rewriter
, ui::VKEY_F15
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1070 // Check that Control is applied to a subsequent key press.
1071 EXPECT_EQ(GetExpectedResultAsString(
1072 ui::VKEY_A
, ui::EF_CONTROL_DOWN
, ui::ET_KEY_PRESSED
),
1073 GetRewrittenEventAsString(
1074 &rewriter
, ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1076 EXPECT_EQ(GetExpectedResultAsString(
1077 ui::VKEY_CONTROL
, ui::EF_NONE
, ui::ET_KEY_RELEASED
),
1078 GetRewrittenEventAsString(
1079 &rewriter
, ui::VKEY_F15
, ui::EF_NONE
, ui::ET_KEY_RELEASED
));
1080 // Check that Control is no longer applied to a subsequent key press.
1082 GetExpectedResultAsString(ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
),
1083 GetRewrittenEventAsString(
1084 &rewriter
, ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1086 IntegerPrefMember diamond
;
1087 diamond
.Init(prefs::kLanguageRemapDiamondKeyTo
, &prefs
);
1088 diamond
.SetValue(chromeos::input_method::kVoidKey
);
1090 EXPECT_EQ(GetExpectedResultAsString(
1091 ui::VKEY_UNKNOWN
, ui::EF_NONE
, ui::ET_KEY_PRESSED
),
1092 GetRewrittenEventAsString(
1093 &rewriter
, ui::VKEY_F15
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1094 // Check that no modifier is applied to another key.
1096 GetExpectedResultAsString(ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
),
1097 GetRewrittenEventAsString(
1098 &rewriter
, ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1100 diamond
.SetValue(chromeos::input_method::kControlKey
);
1102 EXPECT_EQ(GetExpectedResultAsString(
1103 ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
, ui::ET_KEY_PRESSED
),
1104 GetRewrittenEventAsString(
1105 &rewriter
, ui::VKEY_F15
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1106 // Check that Control is applied to a subsequent key press.
1107 EXPECT_EQ(GetExpectedResultAsString(
1108 ui::VKEY_A
, ui::EF_CONTROL_DOWN
, ui::ET_KEY_PRESSED
),
1109 GetRewrittenEventAsString(
1110 &rewriter
, ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1112 EXPECT_EQ(GetExpectedResultAsString(
1113 ui::VKEY_CONTROL
, ui::EF_NONE
, ui::ET_KEY_RELEASED
),
1114 GetRewrittenEventAsString(
1115 &rewriter
, ui::VKEY_F15
, ui::EF_NONE
, ui::ET_KEY_RELEASED
));
1116 // Check that Control is no longer applied to a subsequent key press.
1118 GetExpectedResultAsString(ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
),
1119 GetRewrittenEventAsString(
1120 &rewriter
, ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1122 diamond
.SetValue(chromeos::input_method::kAltKey
);
1124 EXPECT_EQ(GetExpectedResultAsString(
1125 ui::VKEY_MENU
, ui::EF_ALT_DOWN
, ui::ET_KEY_PRESSED
),
1126 GetRewrittenEventAsString(
1127 &rewriter
, ui::VKEY_F15
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1128 // Check that Alt is applied to a subsequent key press.
1129 EXPECT_EQ(GetExpectedResultAsString(
1130 ui::VKEY_A
, ui::EF_ALT_DOWN
, ui::ET_KEY_PRESSED
),
1131 GetRewrittenEventAsString(
1132 &rewriter
, ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1134 EXPECT_EQ(GetExpectedResultAsString(
1135 ui::VKEY_MENU
, ui::EF_NONE
, ui::ET_KEY_RELEASED
),
1136 GetRewrittenEventAsString(
1137 &rewriter
, ui::VKEY_F15
, ui::EF_NONE
, ui::ET_KEY_RELEASED
));
1138 // Check that Alt is no longer applied to a subsequent key press.
1140 GetExpectedResultAsString(ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
),
1141 GetRewrittenEventAsString(
1142 &rewriter
, ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1144 diamond
.SetValue(chromeos::input_method::kCapsLockKey
);
1146 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL
,
1147 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
1148 ui::ET_KEY_PRESSED
),
1149 GetRewrittenEventAsString(
1150 &rewriter
, ui::VKEY_F15
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1151 // Check that Caps is applied to a subsequent key press.
1152 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A
,
1153 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
1154 ui::ET_KEY_PRESSED
),
1155 GetRewrittenEventAsString(
1156 &rewriter
, ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1158 EXPECT_EQ(GetExpectedResultAsString(
1159 ui::VKEY_CAPITAL
, ui::EF_NONE
, ui::ET_KEY_RELEASED
),
1160 GetRewrittenEventAsString(
1161 &rewriter
, ui::VKEY_F15
, ui::EF_NONE
, ui::ET_KEY_RELEASED
));
1162 // Check that Control is no longer applied to a subsequent key press.
1164 GetExpectedResultAsString(ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
),
1165 GetRewrittenEventAsString(
1166 &rewriter
, ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1168 *CommandLine::ForCurrentProcess() = original_cl
;
1171 TEST_F(EventRewriterTest
, TestRewriteCapsLockToControl
) {
1172 // Remap CapsLock to Control.
1173 TestingPrefServiceSyncable prefs
;
1174 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1175 IntegerPrefMember control
;
1176 control
.Init(prefs::kLanguageRemapCapsLockKeyTo
, &prefs
);
1177 control
.SetValue(chromeos::input_method::kControlKey
);
1179 EventRewriter
rewriter(NULL
);
1180 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1181 rewriter
.set_pref_service_for_testing(&prefs
);
1183 KeyTestCase tests
[] = {
1184 // Press CapsLock+a. Confirm that Mod3Mask is rewritten to ControlMask.
1185 // On Chrome OS, CapsLock works as a Mod3 modifier.
1186 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1187 {ui::VKEY_A
, ui::EF_MOD3_DOWN
},
1188 {ui::VKEY_A
, ui::EF_CONTROL_DOWN
}},
1190 // Press Control+CapsLock+a. Confirm that Mod3Mask is rewritten to
1192 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1193 {ui::VKEY_A
, ui::EF_CONTROL_DOWN
| ui::EF_MOD3_DOWN
},
1194 {ui::VKEY_A
, ui::EF_CONTROL_DOWN
}},
1196 // Press Alt+CapsLock+a. Confirm that Mod3Mask is rewritten to
1198 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1199 {ui::VKEY_A
, ui::EF_ALT_DOWN
| ui::EF_MOD3_DOWN
},
1200 {ui::VKEY_A
, ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
}},
1203 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
1205 CheckKeyTestCase(&rewriter
, tests
[i
]);
1209 TEST_F(EventRewriterTest
, TestRewriteCapsLockMod3InUse
) {
1210 // Remap CapsLock to Control.
1211 TestingPrefServiceSyncable prefs
;
1212 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1213 IntegerPrefMember control
;
1214 control
.Init(prefs::kLanguageRemapCapsLockKeyTo
, &prefs
);
1215 control
.SetValue(chromeos::input_method::kControlKey
);
1217 EventRewriter
rewriter(NULL
);
1218 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1219 rewriter
.set_pref_service_for_testing(&prefs
);
1220 input_method_manager_mock_
->set_mod3_used(true);
1222 // Press CapsLock+a. Confirm that Mod3Mask is NOT rewritten to ControlMask
1223 // when Mod3Mask is already in use by the current XKB layout.
1225 GetExpectedResultAsString(ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
),
1226 GetRewrittenEventAsString(
1227 &rewriter
, ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1229 input_method_manager_mock_
->set_mod3_used(false);
1232 TEST_F(EventRewriterTest
, TestRewriteExtendedKeys
) {
1233 TestingPrefServiceSyncable prefs
;
1234 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1235 EventRewriter
rewriter(NULL
);
1236 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1237 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
1238 rewriter
.set_pref_service_for_testing(&prefs
);
1240 KeyTestCase tests
[] = {
1241 // Alt+Backspace -> Delete
1242 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1243 {ui::VKEY_BACK
, ui::EF_ALT_DOWN
},
1244 {ui::VKEY_DELETE
, ui::EF_NONE
}},
1245 // Control+Alt+Backspace -> Control+Delete
1246 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1247 {ui::VKEY_BACK
, ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
},
1248 {ui::VKEY_DELETE
, ui::EF_CONTROL_DOWN
}},
1249 // Search+Alt+Backspace -> Alt+Backspace
1250 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1251 {ui::VKEY_BACK
, ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
},
1252 {ui::VKEY_BACK
, ui::EF_ALT_DOWN
}},
1253 // Search+Control+Alt+Backspace -> Control+Alt+Backspace
1254 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1256 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
},
1257 {ui::VKEY_BACK
, ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
}},
1259 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1260 {ui::VKEY_UP
, ui::EF_ALT_DOWN
},
1261 {ui::VKEY_PRIOR
, ui::EF_NONE
}},
1263 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1264 {ui::VKEY_DOWN
, ui::EF_ALT_DOWN
},
1265 {ui::VKEY_NEXT
, ui::EF_NONE
}},
1266 // Ctrl+Alt+Up -> Home
1267 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1268 {ui::VKEY_UP
, ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
},
1269 {ui::VKEY_HOME
, ui::EF_NONE
}},
1270 // Ctrl+Alt+Down -> End
1271 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1272 {ui::VKEY_DOWN
, ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
},
1273 {ui::VKEY_END
, ui::EF_NONE
}},
1275 // Search+Alt+Up -> Alt+Up
1276 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1277 {ui::VKEY_UP
, ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
},
1278 {ui::VKEY_UP
, ui::EF_ALT_DOWN
}},
1279 // Search+Alt+Down -> Alt+Down
1280 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1281 {ui::VKEY_DOWN
, ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
},
1282 {ui::VKEY_DOWN
, ui::EF_ALT_DOWN
}},
1283 // Search+Ctrl+Alt+Up -> Search+Ctrl+Alt+Up
1284 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1286 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
},
1287 {ui::VKEY_UP
, ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
}},
1288 // Search+Ctrl+Alt+Down -> Ctrl+Alt+Down
1289 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1291 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
},
1292 {ui::VKEY_DOWN
, ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
}},
1295 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1296 {ui::VKEY_OEM_PERIOD
, ui::EF_NONE
},
1297 {ui::VKEY_OEM_PERIOD
, ui::EF_NONE
}},
1299 // Search+Backspace -> Delete
1300 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1301 {ui::VKEY_BACK
, ui::EF_COMMAND_DOWN
},
1302 {ui::VKEY_DELETE
, ui::EF_NONE
}},
1303 // Search+Up -> Prior
1304 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1305 {ui::VKEY_UP
, ui::EF_COMMAND_DOWN
},
1306 {ui::VKEY_PRIOR
, ui::EF_NONE
}},
1307 // Search+Down -> Next
1308 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1309 {ui::VKEY_DOWN
, ui::EF_COMMAND_DOWN
},
1310 {ui::VKEY_NEXT
, ui::EF_NONE
}},
1311 // Search+Left -> Home
1312 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1313 {ui::VKEY_LEFT
, ui::EF_COMMAND_DOWN
},
1314 {ui::VKEY_HOME
, ui::EF_NONE
}},
1315 // Control+Search+Left -> Home
1316 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1317 {ui::VKEY_LEFT
, ui::EF_COMMAND_DOWN
| ui::EF_CONTROL_DOWN
},
1318 {ui::VKEY_HOME
, ui::EF_CONTROL_DOWN
}},
1319 // Search+Right -> End
1320 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1321 {ui::VKEY_RIGHT
, ui::EF_COMMAND_DOWN
},
1322 {ui::VKEY_END
, ui::EF_NONE
}},
1323 // Control+Search+Right -> End
1324 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1325 {ui::VKEY_RIGHT
, ui::EF_COMMAND_DOWN
| ui::EF_CONTROL_DOWN
},
1326 {ui::VKEY_END
, ui::EF_CONTROL_DOWN
}},
1327 // Search+Period -> Insert
1328 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1329 {ui::VKEY_OEM_PERIOD
, ui::EF_COMMAND_DOWN
},
1330 {ui::VKEY_INSERT
, ui::EF_NONE
}},
1331 // Control+Search+Period -> Control+Insert
1332 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1333 {ui::VKEY_OEM_PERIOD
, ui::EF_COMMAND_DOWN
| ui::EF_CONTROL_DOWN
},
1334 {ui::VKEY_INSERT
, ui::EF_CONTROL_DOWN
}}};
1336 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
1338 CheckKeyTestCase(&rewriter
, tests
[i
]);
1342 TEST_F(EventRewriterTest
, TestRewriteFunctionKeys
) {
1343 TestingPrefServiceSyncable prefs
;
1344 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1345 EventRewriter
rewriter(NULL
);
1346 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1347 rewriter
.set_pref_service_for_testing(&prefs
);
1349 FunctionKeyTestCase tests
[] = {
1351 {ui::ET_KEY_PRESSED
,
1352 {ui::VKEY_F1
, ui::EF_NONE
},
1353 {ui::VKEY_BROWSER_BACK
, ui::EF_NONE
},
1354 {ui::VKEY_BROWSER_BACK
, ui::EF_FUNCTION_KEY
}},
1355 {ui::ET_KEY_PRESSED
,
1356 {ui::VKEY_F1
, ui::EF_CONTROL_DOWN
},
1357 {ui::VKEY_BROWSER_BACK
, ui::EF_CONTROL_DOWN
},
1358 {ui::VKEY_BROWSER_BACK
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1359 {ui::ET_KEY_PRESSED
,
1360 {ui::VKEY_F1
, ui::EF_ALT_DOWN
},
1361 {ui::VKEY_BROWSER_BACK
, ui::EF_ALT_DOWN
},
1362 {ui::VKEY_BROWSER_BACK
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1364 {ui::ET_KEY_PRESSED
,
1365 {ui::VKEY_F2
, ui::EF_NONE
},
1366 {ui::VKEY_BROWSER_FORWARD
, ui::EF_NONE
},
1367 {ui::VKEY_BROWSER_FORWARD
, ui::EF_FUNCTION_KEY
}},
1368 {ui::ET_KEY_PRESSED
,
1369 {ui::VKEY_F2
, ui::EF_CONTROL_DOWN
},
1370 {ui::VKEY_BROWSER_FORWARD
, ui::EF_CONTROL_DOWN
},
1371 {ui::VKEY_BROWSER_FORWARD
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1372 {ui::ET_KEY_PRESSED
,
1373 {ui::VKEY_F2
, ui::EF_ALT_DOWN
},
1374 {ui::VKEY_BROWSER_FORWARD
, ui::EF_ALT_DOWN
},
1375 {ui::VKEY_BROWSER_FORWARD
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1377 {ui::ET_KEY_PRESSED
,
1378 {ui::VKEY_F3
, ui::EF_NONE
},
1379 {ui::VKEY_BROWSER_REFRESH
, ui::EF_NONE
},
1380 {ui::VKEY_BROWSER_REFRESH
, ui::EF_FUNCTION_KEY
}},
1381 {ui::ET_KEY_PRESSED
,
1382 {ui::VKEY_F3
, ui::EF_CONTROL_DOWN
},
1383 {ui::VKEY_BROWSER_REFRESH
, ui::EF_CONTROL_DOWN
},
1384 {ui::VKEY_BROWSER_REFRESH
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1385 {ui::ET_KEY_PRESSED
,
1386 {ui::VKEY_F3
, ui::EF_ALT_DOWN
},
1387 {ui::VKEY_BROWSER_REFRESH
, ui::EF_ALT_DOWN
},
1388 {ui::VKEY_BROWSER_REFRESH
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1389 // F4 -> Launch App 2
1390 {ui::ET_KEY_PRESSED
,
1391 {ui::VKEY_F4
, ui::EF_NONE
},
1392 {ui::VKEY_MEDIA_LAUNCH_APP2
, ui::EF_NONE
},
1393 {ui::VKEY_MEDIA_LAUNCH_APP2
, ui::EF_FUNCTION_KEY
}},
1394 {ui::ET_KEY_PRESSED
,
1395 {ui::VKEY_F4
, ui::EF_CONTROL_DOWN
},
1396 {ui::VKEY_MEDIA_LAUNCH_APP2
, ui::EF_CONTROL_DOWN
},
1397 {ui::VKEY_MEDIA_LAUNCH_APP2
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1398 {ui::ET_KEY_PRESSED
,
1399 {ui::VKEY_F4
, ui::EF_ALT_DOWN
},
1400 {ui::VKEY_MEDIA_LAUNCH_APP2
, ui::EF_ALT_DOWN
},
1401 {ui::VKEY_MEDIA_LAUNCH_APP2
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1402 // F5 -> Launch App 1
1403 {ui::ET_KEY_PRESSED
,
1404 {ui::VKEY_F5
, ui::EF_NONE
},
1405 {ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_NONE
},
1406 {ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_FUNCTION_KEY
}},
1407 {ui::ET_KEY_PRESSED
,
1408 {ui::VKEY_F5
, ui::EF_CONTROL_DOWN
},
1409 {ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_CONTROL_DOWN
},
1410 {ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1411 {ui::ET_KEY_PRESSED
,
1412 {ui::VKEY_F5
, ui::EF_ALT_DOWN
},
1413 {ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_ALT_DOWN
},
1414 {ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1415 // F6 -> Brightness down
1416 {ui::ET_KEY_PRESSED
,
1417 {ui::VKEY_F6
, ui::EF_NONE
},
1418 {ui::VKEY_BRIGHTNESS_DOWN
, ui::EF_NONE
},
1419 {ui::VKEY_BRIGHTNESS_DOWN
, ui::EF_FUNCTION_KEY
}},
1420 {ui::ET_KEY_PRESSED
,
1421 {ui::VKEY_F6
, ui::EF_CONTROL_DOWN
},
1422 {ui::VKEY_BRIGHTNESS_DOWN
, ui::EF_CONTROL_DOWN
},
1423 {ui::VKEY_BRIGHTNESS_DOWN
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1424 {ui::ET_KEY_PRESSED
,
1425 {ui::VKEY_F6
, ui::EF_ALT_DOWN
},
1426 {ui::VKEY_BRIGHTNESS_DOWN
, ui::EF_ALT_DOWN
},
1427 {ui::VKEY_BRIGHTNESS_DOWN
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1428 // F7 -> Brightness up
1429 {ui::ET_KEY_PRESSED
,
1430 {ui::VKEY_F7
, ui::EF_NONE
},
1431 {ui::VKEY_BRIGHTNESS_UP
, ui::EF_NONE
},
1432 {ui::VKEY_BRIGHTNESS_UP
, ui::EF_FUNCTION_KEY
}},
1433 {ui::ET_KEY_PRESSED
,
1434 {ui::VKEY_F7
, ui::EF_CONTROL_DOWN
},
1435 {ui::VKEY_BRIGHTNESS_UP
, ui::EF_CONTROL_DOWN
},
1436 {ui::VKEY_BRIGHTNESS_UP
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1437 {ui::ET_KEY_PRESSED
,
1438 {ui::VKEY_F7
, ui::EF_ALT_DOWN
},
1439 {ui::VKEY_BRIGHTNESS_UP
, ui::EF_ALT_DOWN
},
1440 {ui::VKEY_BRIGHTNESS_UP
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1441 // F8 -> Volume Mute
1442 {ui::ET_KEY_PRESSED
,
1443 {ui::VKEY_F8
, ui::EF_NONE
},
1444 {ui::VKEY_VOLUME_MUTE
, ui::EF_NONE
},
1445 {ui::VKEY_VOLUME_MUTE
, ui::EF_FUNCTION_KEY
}},
1446 {ui::ET_KEY_PRESSED
,
1447 {ui::VKEY_F8
, ui::EF_CONTROL_DOWN
},
1448 {ui::VKEY_VOLUME_MUTE
, ui::EF_CONTROL_DOWN
},
1449 {ui::VKEY_VOLUME_MUTE
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1450 {ui::ET_KEY_PRESSED
,
1451 {ui::VKEY_F8
, ui::EF_ALT_DOWN
},
1452 {ui::VKEY_VOLUME_MUTE
, ui::EF_ALT_DOWN
},
1453 {ui::VKEY_VOLUME_MUTE
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1454 // F9 -> Volume Down
1455 {ui::ET_KEY_PRESSED
,
1456 {ui::VKEY_F9
, ui::EF_NONE
},
1457 {ui::VKEY_VOLUME_DOWN
, ui::EF_NONE
},
1458 {ui::VKEY_VOLUME_DOWN
, ui::EF_FUNCTION_KEY
}},
1459 {ui::ET_KEY_PRESSED
,
1460 {ui::VKEY_F9
, ui::EF_CONTROL_DOWN
},
1461 {ui::VKEY_VOLUME_DOWN
, ui::EF_CONTROL_DOWN
},
1462 {ui::VKEY_VOLUME_DOWN
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1463 {ui::ET_KEY_PRESSED
,
1464 {ui::VKEY_F9
, ui::EF_ALT_DOWN
},
1465 {ui::VKEY_VOLUME_DOWN
, ui::EF_ALT_DOWN
},
1466 {ui::VKEY_VOLUME_DOWN
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1468 {ui::ET_KEY_PRESSED
,
1469 {ui::VKEY_F10
, ui::EF_NONE
},
1470 {ui::VKEY_VOLUME_UP
, ui::EF_NONE
},
1471 {ui::VKEY_VOLUME_UP
, ui::EF_FUNCTION_KEY
}},
1472 {ui::ET_KEY_PRESSED
,
1473 {ui::VKEY_F10
, ui::EF_CONTROL_DOWN
},
1474 {ui::VKEY_VOLUME_UP
, ui::EF_CONTROL_DOWN
},
1475 {ui::VKEY_VOLUME_UP
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1476 {ui::ET_KEY_PRESSED
,
1477 {ui::VKEY_F10
, ui::EF_ALT_DOWN
},
1478 {ui::VKEY_VOLUME_UP
, ui::EF_ALT_DOWN
},
1479 {ui::VKEY_VOLUME_UP
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1481 {ui::ET_KEY_PRESSED
,
1482 {ui::VKEY_F11
, ui::EF_NONE
},
1483 {ui::VKEY_F11
, ui::EF_NONE
},
1484 {ui::VKEY_F11
, ui::EF_FUNCTION_KEY
}},
1485 {ui::ET_KEY_PRESSED
,
1486 {ui::VKEY_F11
, ui::EF_CONTROL_DOWN
},
1487 {ui::VKEY_F11
, ui::EF_CONTROL_DOWN
},
1488 {ui::VKEY_F11
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1489 {ui::ET_KEY_PRESSED
,
1490 {ui::VKEY_F11
, ui::EF_ALT_DOWN
},
1491 {ui::VKEY_F11
, ui::EF_ALT_DOWN
},
1492 {ui::VKEY_F11
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1494 {ui::ET_KEY_PRESSED
,
1495 {ui::VKEY_F12
, ui::EF_NONE
},
1496 {ui::VKEY_F12
, ui::EF_NONE
},
1497 {ui::VKEY_F12
, ui::EF_FUNCTION_KEY
}},
1498 {ui::ET_KEY_PRESSED
,
1499 {ui::VKEY_F12
, ui::EF_CONTROL_DOWN
},
1500 {ui::VKEY_F12
, ui::EF_CONTROL_DOWN
},
1501 {ui::VKEY_F12
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1502 {ui::ET_KEY_PRESSED
,
1503 {ui::VKEY_F12
, ui::EF_ALT_DOWN
},
1504 {ui::VKEY_F12
, ui::EF_ALT_DOWN
},
1505 {ui::VKEY_F12
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1507 // The number row should not be rewritten without Search key.
1508 {ui::ET_KEY_PRESSED
,
1509 {ui::VKEY_1
, ui::EF_NONE
},
1510 {ui::VKEY_1
, ui::EF_NONE
},
1511 {ui::VKEY_1
, ui::EF_NONE
}},
1512 {ui::ET_KEY_PRESSED
,
1513 {ui::VKEY_2
, ui::EF_NONE
},
1514 {ui::VKEY_2
, ui::EF_NONE
},
1515 {ui::VKEY_2
, ui::EF_NONE
}},
1516 {ui::ET_KEY_PRESSED
,
1517 {ui::VKEY_3
, ui::EF_NONE
},
1518 {ui::VKEY_3
, ui::EF_NONE
},
1519 {ui::VKEY_3
, ui::EF_NONE
}},
1520 {ui::ET_KEY_PRESSED
,
1521 {ui::VKEY_4
, ui::EF_NONE
},
1522 {ui::VKEY_4
, ui::EF_NONE
},
1523 {ui::VKEY_4
, ui::EF_NONE
}},
1524 {ui::ET_KEY_PRESSED
,
1525 {ui::VKEY_5
, ui::EF_NONE
},
1526 {ui::VKEY_5
, ui::EF_NONE
},
1527 {ui::VKEY_5
, ui::EF_NONE
}},
1528 {ui::ET_KEY_PRESSED
,
1529 {ui::VKEY_6
, ui::EF_NONE
},
1530 {ui::VKEY_6
, ui::EF_NONE
},
1531 {ui::VKEY_6
, ui::EF_NONE
}},
1532 {ui::ET_KEY_PRESSED
,
1533 {ui::VKEY_7
, ui::EF_NONE
},
1534 {ui::VKEY_7
, ui::EF_NONE
},
1535 {ui::VKEY_7
, ui::EF_NONE
}},
1536 {ui::ET_KEY_PRESSED
,
1537 {ui::VKEY_8
, ui::EF_NONE
},
1538 {ui::VKEY_8
, ui::EF_NONE
},
1539 {ui::VKEY_8
, ui::EF_NONE
}},
1540 {ui::ET_KEY_PRESSED
,
1541 {ui::VKEY_9
, ui::EF_NONE
},
1542 {ui::VKEY_9
, ui::EF_NONE
},
1543 {ui::VKEY_9
, ui::EF_NONE
}},
1544 {ui::ET_KEY_PRESSED
,
1545 {ui::VKEY_0
, ui::EF_NONE
},
1546 {ui::VKEY_0
, ui::EF_NONE
},
1547 {ui::VKEY_0
, ui::EF_NONE
}},
1548 {ui::ET_KEY_PRESSED
,
1549 {ui::VKEY_OEM_MINUS
, ui::EF_NONE
},
1550 {ui::VKEY_OEM_MINUS
, ui::EF_NONE
},
1551 {ui::VKEY_OEM_MINUS
, ui::EF_NONE
}},
1552 {ui::ET_KEY_PRESSED
,
1553 {ui::VKEY_OEM_PLUS
, ui::EF_NONE
},
1554 {ui::VKEY_OEM_PLUS
, ui::EF_NONE
},
1555 {ui::VKEY_OEM_PLUS
, ui::EF_NONE
}},
1557 // The number row should be rewritten as the F<number> row with Search
1559 {ui::ET_KEY_PRESSED
,
1560 {ui::VKEY_1
, ui::EF_COMMAND_DOWN
},
1561 {ui::VKEY_F1
, ui::EF_NONE
},
1562 {ui::VKEY_F1
, ui::EF_NONE
}},
1563 {ui::ET_KEY_PRESSED
,
1564 {ui::VKEY_2
, ui::EF_COMMAND_DOWN
},
1565 {ui::VKEY_F2
, ui::EF_NONE
},
1566 {ui::VKEY_F2
, ui::EF_NONE
}},
1567 {ui::ET_KEY_PRESSED
,
1568 {ui::VKEY_3
, ui::EF_COMMAND_DOWN
},
1569 {ui::VKEY_F3
, ui::EF_NONE
},
1570 {ui::VKEY_F3
, ui::EF_NONE
}},
1571 {ui::ET_KEY_PRESSED
,
1572 {ui::VKEY_4
, ui::EF_COMMAND_DOWN
},
1573 {ui::VKEY_F4
, ui::EF_NONE
},
1574 {ui::VKEY_F4
, ui::EF_NONE
}},
1575 {ui::ET_KEY_PRESSED
,
1576 {ui::VKEY_5
, ui::EF_COMMAND_DOWN
},
1577 {ui::VKEY_F5
, ui::EF_NONE
},
1578 {ui::VKEY_F5
, ui::EF_NONE
}},
1579 {ui::ET_KEY_PRESSED
,
1580 {ui::VKEY_6
, ui::EF_COMMAND_DOWN
},
1581 {ui::VKEY_F6
, ui::EF_NONE
},
1582 {ui::VKEY_F6
, ui::EF_NONE
}},
1583 {ui::ET_KEY_PRESSED
,
1584 {ui::VKEY_7
, ui::EF_COMMAND_DOWN
},
1585 {ui::VKEY_F7
, ui::EF_NONE
},
1586 {ui::VKEY_F7
, ui::EF_NONE
}},
1587 {ui::ET_KEY_PRESSED
,
1588 {ui::VKEY_8
, ui::EF_COMMAND_DOWN
},
1589 {ui::VKEY_F8
, ui::EF_NONE
},
1590 {ui::VKEY_F8
, ui::EF_NONE
}},
1591 {ui::ET_KEY_PRESSED
,
1592 {ui::VKEY_9
, ui::EF_COMMAND_DOWN
},
1593 {ui::VKEY_F9
, ui::EF_NONE
},
1594 {ui::VKEY_F9
, ui::EF_NONE
}},
1595 {ui::ET_KEY_PRESSED
,
1596 {ui::VKEY_0
, ui::EF_COMMAND_DOWN
},
1597 {ui::VKEY_F10
, ui::EF_NONE
},
1598 {ui::VKEY_F10
, ui::EF_NONE
}},
1599 {ui::ET_KEY_PRESSED
,
1600 {ui::VKEY_OEM_MINUS
, ui::EF_COMMAND_DOWN
},
1601 {ui::VKEY_F11
, ui::EF_NONE
},
1602 {ui::VKEY_F11
, ui::EF_NONE
}},
1603 {ui::ET_KEY_PRESSED
,
1604 {ui::VKEY_OEM_PLUS
, ui::EF_COMMAND_DOWN
},
1605 {ui::VKEY_F12
, ui::EF_NONE
},
1606 {ui::VKEY_F12
, ui::EF_NONE
}},
1608 // The function keys should not be rewritten with Search key pressed.
1609 {ui::ET_KEY_PRESSED
,
1610 {ui::VKEY_F1
, ui::EF_COMMAND_DOWN
},
1611 {ui::VKEY_F1
, ui::EF_NONE
},
1612 {ui::VKEY_F1
, ui::EF_FUNCTION_KEY
}},
1613 {ui::ET_KEY_PRESSED
,
1614 {ui::VKEY_F2
, ui::EF_COMMAND_DOWN
},
1615 {ui::VKEY_F2
, ui::EF_NONE
},
1616 {ui::VKEY_F2
, ui::EF_FUNCTION_KEY
}},
1617 {ui::ET_KEY_PRESSED
,
1618 {ui::VKEY_F3
, ui::EF_COMMAND_DOWN
},
1619 {ui::VKEY_F3
, ui::EF_NONE
},
1620 {ui::VKEY_F3
, ui::EF_FUNCTION_KEY
}},
1621 {ui::ET_KEY_PRESSED
,
1622 {ui::VKEY_F4
, ui::EF_COMMAND_DOWN
},
1623 {ui::VKEY_F4
, ui::EF_NONE
},
1624 {ui::VKEY_F4
, ui::EF_FUNCTION_KEY
}},
1625 {ui::ET_KEY_PRESSED
,
1626 {ui::VKEY_F5
, ui::EF_COMMAND_DOWN
},
1627 {ui::VKEY_F5
, ui::EF_NONE
},
1628 {ui::VKEY_F5
, ui::EF_FUNCTION_KEY
}},
1629 {ui::ET_KEY_PRESSED
,
1630 {ui::VKEY_F6
, ui::EF_COMMAND_DOWN
},
1631 {ui::VKEY_F6
, ui::EF_NONE
},
1632 {ui::VKEY_F6
, ui::EF_FUNCTION_KEY
}},
1633 {ui::ET_KEY_PRESSED
,
1634 {ui::VKEY_F7
, ui::EF_COMMAND_DOWN
},
1635 {ui::VKEY_F7
, ui::EF_NONE
},
1636 {ui::VKEY_F7
, ui::EF_FUNCTION_KEY
}},
1637 {ui::ET_KEY_PRESSED
,
1638 {ui::VKEY_F8
, ui::EF_COMMAND_DOWN
},
1639 {ui::VKEY_F8
, ui::EF_NONE
},
1640 {ui::VKEY_F8
, ui::EF_FUNCTION_KEY
}},
1641 {ui::ET_KEY_PRESSED
,
1642 {ui::VKEY_F9
, ui::EF_COMMAND_DOWN
},
1643 {ui::VKEY_F9
, ui::EF_NONE
},
1644 {ui::VKEY_F9
, ui::EF_FUNCTION_KEY
}},
1645 {ui::ET_KEY_PRESSED
,
1646 {ui::VKEY_F10
, ui::EF_COMMAND_DOWN
},
1647 {ui::VKEY_F10
, ui::EF_NONE
},
1648 {ui::VKEY_F10
, ui::EF_FUNCTION_KEY
}},
1649 {ui::ET_KEY_PRESSED
,
1650 {ui::VKEY_F11
, ui::EF_COMMAND_DOWN
},
1651 {ui::VKEY_F11
, ui::EF_NONE
},
1652 {ui::VKEY_F11
, ui::EF_FUNCTION_KEY
}},
1653 {ui::ET_KEY_PRESSED
,
1654 {ui::VKEY_F12
, ui::EF_COMMAND_DOWN
},
1655 {ui::VKEY_F12
, ui::EF_NONE
},
1656 {ui::VKEY_F12
, ui::EF_FUNCTION_KEY
}},
1659 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
1661 CheckFunctionKeyTestCase(&rewriter
, tests
[i
]);
1665 TEST_F(EventRewriterTest
, TestRewriteExtendedKeysWithSearchRemapped
) {
1666 const CommandLine
original_cl(*CommandLine::ForCurrentProcess());
1668 // Remap Search to Control.
1669 TestingPrefServiceSyncable prefs
;
1670 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1671 IntegerPrefMember search
;
1672 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
1673 search
.SetValue(chromeos::input_method::kControlKey
);
1675 EventRewriter
rewriter(NULL
);
1676 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1677 rewriter
.set_pref_service_for_testing(&prefs
);
1679 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1680 chromeos::switches::kHasChromeOSKeyboard
, "");
1682 KeyTestCase tests
[] = {
1683 // Alt+Search+Down -> End
1684 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1685 {ui::VKEY_DOWN
, ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
},
1686 {ui::VKEY_END
, ui::EF_NONE
}},
1688 // Shift+Alt+Search+Down -> Shift+End
1689 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1691 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
},
1692 {ui::VKEY_END
, ui::EF_SHIFT_DOWN
}},
1695 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
1697 CheckKeyTestCase(&rewriter
, tests
[i
]);
1700 *CommandLine::ForCurrentProcess() = original_cl
;
1703 TEST_F(EventRewriterTest
, TestRewriteKeyEventSentByXSendEvent
) {
1704 // Remap Control to Alt.
1705 TestingPrefServiceSyncable prefs
;
1706 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1707 IntegerPrefMember control
;
1708 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
1709 control
.SetValue(chromeos::input_method::kAltKey
);
1711 EventRewriter
rewriter(NULL
);
1712 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1713 rewriter
.set_pref_service_for_testing(&prefs
);
1715 // Send left control press.
1717 ui::KeyEvent
keyevent(
1718 ui::ET_KEY_PRESSED
, ui::VKEY_CONTROL
, ui::EF_FINAL
);
1719 scoped_ptr
<ui::Event
> new_event
;
1720 // Control should NOT be remapped to Alt if EF_FINAL is set.
1721 EXPECT_EQ(ui::EVENT_REWRITE_CONTINUE
,
1722 rewriter
.RewriteEvent(keyevent
, &new_event
));
1723 EXPECT_FALSE(new_event
);
1725 #if defined(USE_X11)
1726 // Send left control press, using XI2 native events.
1728 ui::ScopedXI2Event xev
;
1729 xev
.InitKeyEvent(ui::ET_KEY_PRESSED
, ui::VKEY_CONTROL
, 0);
1730 XEvent
* xevent
= xev
;
1731 xevent
->xkey
.keycode
= XKeysymToKeycode(gfx::GetXDisplay(), XK_Control_L
);
1732 xevent
->xkey
.send_event
= True
; // XSendEvent() always does this.
1733 ui::KeyEvent
keyevent(xev
);
1734 scoped_ptr
<ui::Event
> new_event
;
1735 // Control should NOT be remapped to Alt if send_event
1736 // flag in the event is True.
1737 EXPECT_EQ(ui::EVENT_REWRITE_CONTINUE
,
1738 rewriter
.RewriteEvent(keyevent
, &new_event
));
1739 EXPECT_FALSE(new_event
);
1744 TEST_F(EventRewriterTest
, TestRewriteNonNativeEvent
) {
1745 // Remap Control to Alt.
1746 TestingPrefServiceSyncable prefs
;
1747 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1748 IntegerPrefMember control
;
1749 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
1750 control
.SetValue(chromeos::input_method::kAltKey
);
1752 EventRewriter
rewriter(NULL
);
1753 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1754 rewriter
.set_pref_service_for_testing(&prefs
);
1756 const int kTouchId
= 2;
1757 gfx::Point
location(0, 0);
1758 ui::TouchEvent
press(
1759 ui::ET_TOUCH_PRESSED
, location
, kTouchId
, base::TimeDelta());
1760 press
.set_flags(ui::EF_CONTROL_DOWN
);
1761 #if defined(USE_X11)
1762 ui::UpdateX11EventForFlags(&press
);
1765 scoped_ptr
<ui::Event
> new_event
;
1766 rewriter
.RewriteEvent(press
, &new_event
);
1767 EXPECT_TRUE(new_event
);
1768 // Control should be remapped to Alt.
1769 EXPECT_EQ(ui::EF_ALT_DOWN
,
1770 new_event
->flags() & (ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
));
1773 // Keeps a buffer of handled events.
1774 class EventBuffer
: public ui::test::TestEventProcessor
{
1777 virtual ~EventBuffer() {}
1779 void PopEvents(ScopedVector
<ui::Event
>* events
) {
1781 events
->swap(events_
);
1785 // ui::EventProcessor overrides:
1786 virtual ui::EventDispatchDetails
OnEventFromSource(
1787 ui::Event
* event
) override
{
1788 if (event
->IsKeyEvent()) {
1789 events_
.push_back(new ui::KeyEvent(*static_cast<ui::KeyEvent
*>(event
)));
1790 } else if (event
->IsMouseWheelEvent()) {
1792 new ui::MouseWheelEvent(*static_cast<ui::MouseWheelEvent
*>(event
)));
1793 } else if (event
->IsMouseEvent()) {
1795 new ui::MouseEvent(*static_cast<ui::MouseEvent
*>(event
)));
1797 return ui::EventDispatchDetails();
1800 ScopedVector
<ui::Event
> events_
;
1802 DISALLOW_COPY_AND_ASSIGN(EventBuffer
);
1805 // Trivial EventSource that does nothing but send events.
1806 class TestEventSource
: public ui::EventSource
{
1808 explicit TestEventSource(ui::EventProcessor
* processor
)
1809 : processor_(processor
) {}
1810 virtual ui::EventProcessor
* GetEventProcessor() override
{
1813 ui::EventDispatchDetails
Send(ui::Event
* event
) {
1814 return SendEventToProcessor(event
);
1818 ui::EventProcessor
* processor_
;
1821 // Tests of event rewriting that depend on the Ash window manager.
1822 class EventRewriterAshTest
: public ash::test::AshTestBase
{
1824 EventRewriterAshTest()
1825 : source_(&buffer_
),
1826 fake_user_manager_(new chromeos::FakeUserManager
),
1827 user_manager_enabler_(fake_user_manager_
) {}
1828 virtual ~EventRewriterAshTest() {}
1830 bool RewriteFunctionKeys(const ui::Event
& event
,
1831 scoped_ptr
<ui::Event
>* rewritten_event
) {
1832 return rewriter_
->RewriteEvent(event
, rewritten_event
);
1835 ui::EventDispatchDetails
Send(ui::Event
* event
) {
1836 return source_
.Send(event
);
1839 void SendKeyEvent(ui::EventType type
, ui::KeyboardCode key_code
) {
1840 ui::KeyEvent
press(type
, key_code
, ui::EF_NONE
);
1841 ui::EventDispatchDetails details
= Send(&press
);
1842 CHECK(!details
.dispatcher_destroyed
);
1845 void SendActivateStickyKeyPattern(ui::KeyboardCode key_code
) {
1846 SendKeyEvent(ui::ET_KEY_PRESSED
, key_code
);
1847 SendKeyEvent(ui::ET_KEY_RELEASED
, key_code
);
1851 TestingPrefServiceSyncable
* prefs() { return &prefs_
; }
1853 void PopEvents(ScopedVector
<ui::Event
>* events
) {
1854 buffer_
.PopEvents(events
);
1857 virtual void SetUp() override
{
1858 AshTestBase::SetUp();
1859 sticky_keys_controller_
=
1860 ash::Shell::GetInstance()->sticky_keys_controller();
1861 rewriter_
.reset(new EventRewriter(sticky_keys_controller_
));
1862 chromeos::Preferences::RegisterProfilePrefs(prefs_
.registry());
1863 rewriter_
->set_pref_service_for_testing(&prefs_
);
1864 #if defined(USE_X11)
1865 ui::SetUpTouchPadForTest(kTouchPadDeviceId
);
1867 source_
.AddEventRewriter(rewriter_
.get());
1868 sticky_keys_controller_
->Enable(true);
1871 virtual void TearDown() override
{
1873 AshTestBase::TearDown();
1877 ash::StickyKeysController
* sticky_keys_controller_
;
1880 scoped_ptr
<EventRewriter
> rewriter_
;
1882 EventBuffer buffer_
;
1883 TestEventSource source_
;
1885 chromeos::FakeUserManager
* fake_user_manager_
; // Not owned.
1886 chromeos::ScopedUserManagerEnabler user_manager_enabler_
;
1887 TestingPrefServiceSyncable prefs_
;
1889 DISALLOW_COPY_AND_ASSIGN(EventRewriterAshTest
);
1892 TEST_F(EventRewriterAshTest
, TopRowKeysAreFunctionKeys
) {
1893 scoped_ptr
<aura::Window
> window(CreateTestWindowInShellWithId(1));
1894 ash::wm::WindowState
* window_state
= ash::wm::GetWindowState(window
.get());
1895 window_state
->Activate();
1896 ScopedVector
<ui::Event
> events
;
1898 // Create a simulated keypress of F1 targetted at the window.
1899 ui::KeyEvent
press_f1(ui::ET_KEY_PRESSED
, ui::VKEY_F1
, ui::EF_NONE
);
1901 // Simulate an apps v2 window that has requested top row keys as function
1902 // keys. The event should not be rewritten.
1903 window_state
->set_top_row_keys_are_function_keys(true);
1904 ui::EventDispatchDetails details
= Send(&press_f1
);
1905 ASSERT_FALSE(details
.dispatcher_destroyed
);
1907 EXPECT_EQ(1u, events
.size());
1909 GetExpectedResultAsString(ui::VKEY_F1
, ui::EF_NONE
, ui::ET_KEY_PRESSED
),
1910 GetKeyEventAsString(*static_cast<ui::KeyEvent
*>(events
[0])));
1912 // The event should also not be rewritten if the send-function-keys pref is
1913 // additionally set, for both apps v2 and regular windows.
1914 BooleanPrefMember send_function_keys_pref
;
1915 send_function_keys_pref
.Init(prefs::kLanguageSendFunctionKeys
, prefs());
1916 send_function_keys_pref
.SetValue(true);
1917 window_state
->set_top_row_keys_are_function_keys(false);
1918 details
= Send(&press_f1
);
1919 ASSERT_FALSE(details
.dispatcher_destroyed
);
1921 EXPECT_EQ(1u, events
.size());
1923 GetExpectedResultAsString(ui::VKEY_F1
, ui::EF_NONE
, ui::ET_KEY_PRESSED
),
1924 GetKeyEventAsString(*static_cast<ui::KeyEvent
*>(events
[0])));
1926 // If the pref isn't set when an event is sent to a regular window, F1 is
1927 // rewritten to the back key.
1928 send_function_keys_pref
.SetValue(false);
1929 details
= Send(&press_f1
);
1930 ASSERT_FALSE(details
.dispatcher_destroyed
);
1932 EXPECT_EQ(1u, events
.size());
1933 EXPECT_EQ(GetExpectedResultAsString(
1934 ui::VKEY_BROWSER_BACK
, ui::EF_NONE
, ui::ET_KEY_PRESSED
),
1935 GetKeyEventAsString(*static_cast<ui::KeyEvent
*>(events
[0])));
1938 TEST_F(EventRewriterTest
, TestRewrittenModifierClick
) {
1939 std::vector
<unsigned int> device_list
;
1940 device_list
.push_back(10);
1941 ui::TouchFactory::GetInstance()->SetPointerDeviceForTest(device_list
);
1943 // Remap Control to Alt.
1944 TestingPrefServiceSyncable prefs
;
1945 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1946 IntegerPrefMember control
;
1947 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
1948 control
.SetValue(chromeos::input_method::kAltKey
);
1950 EventRewriter
rewriter(NULL
);
1951 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1952 rewriter
.set_pref_service_for_testing(&prefs
);
1954 // Check that Control + Left Button is converted (via Alt + Left Button)
1956 ui::ScopedXI2Event xev
;
1957 xev
.InitGenericButtonEvent(10,
1958 ui::ET_MOUSE_PRESSED
,
1960 ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_CONTROL_DOWN
);
1961 ui::MouseEvent
press(xev
);
1963 EXPECT_EQ(ui::ET_MOUSE_PRESSED
, press
.type());
1964 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_CONTROL_DOWN
, press
.flags());
1965 scoped_ptr
<ui::Event
> new_event
;
1966 const ui::MouseEvent
* result
=
1967 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
1968 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
1969 EXPECT_FALSE(ui::EF_LEFT_MOUSE_BUTTON
& result
->flags());
1970 EXPECT_FALSE(ui::EF_CONTROL_DOWN
& result
->flags());
1971 EXPECT_FALSE(ui::EF_ALT_DOWN
& result
->flags());
1972 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
1975 TEST_F(EventRewriterTest
, DontRewriteIfNotRewritten
) {
1976 // TODO(kpschoedel): pending changes for crbug.com/360377
1977 // to |chromeos::EventRewriter::RewriteLocatedEvent()
1978 std::vector
<unsigned int> device_list
;
1979 device_list
.push_back(10);
1980 device_list
.push_back(11);
1981 ui::TouchFactory::GetInstance()->SetPointerDeviceForTest(device_list
);
1982 TestingPrefServiceSyncable prefs
;
1983 EventRewriter
rewriter(NULL
);
1984 rewriter
.set_pref_service_for_testing(&prefs
);
1985 const int kLeftAndAltFlag
= ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_ALT_DOWN
;
1987 // Test Alt + Left click.
1989 ui::MouseEvent
press(ui::ET_MOUSE_PRESSED
,
1993 ui::EF_LEFT_MOUSE_BUTTON
);
1994 ui::EventTestApi
test_press(&press
);
1995 test_press
.set_source_device_id(10);
1997 EXPECT_EQ(ui::ET_MOUSE_PRESSED
, press
.type());
1998 EXPECT_EQ(kLeftAndAltFlag
, press
.flags());
1999 scoped_ptr
<ui::Event
> new_event
;
2000 const ui::MouseEvent
* result
=
2001 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
2002 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
2003 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
2004 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
2007 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
,
2011 ui::EF_LEFT_MOUSE_BUTTON
);
2012 ui::EventTestApi
test_release(&release
);
2013 test_release
.set_source_device_id(10);
2014 scoped_ptr
<ui::Event
> new_event
;
2015 const ui::MouseEvent
* result
=
2016 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
2017 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
2018 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
2019 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
2021 #if defined(USE_X11)
2022 // Test Alt + Left click, using XI2 native events.
2024 ui::ScopedXI2Event xev
;
2025 xev
.InitGenericButtonEvent(
2026 10, ui::ET_MOUSE_PRESSED
, gfx::Point(), kLeftAndAltFlag
);
2027 ui::MouseEvent
press(xev
);
2029 EXPECT_EQ(ui::ET_MOUSE_PRESSED
, press
.type());
2030 EXPECT_EQ(kLeftAndAltFlag
, press
.flags());
2031 scoped_ptr
<ui::Event
> new_event
;
2032 const ui::MouseEvent
* result
=
2033 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
2034 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
2035 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
2036 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
2039 ui::ScopedXI2Event xev
;
2040 xev
.InitGenericButtonEvent(
2041 10, ui::ET_MOUSE_RELEASED
, gfx::Point(), kLeftAndAltFlag
);
2042 ui::MouseEvent
release(xev
);
2043 scoped_ptr
<ui::Event
> new_event
;
2044 const ui::MouseEvent
* result
=
2045 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
2046 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
2047 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
2048 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
2052 // No ALT in frst click.
2054 ui::MouseEvent
press(ui::ET_MOUSE_PRESSED
,
2057 ui::EF_LEFT_MOUSE_BUTTON
,
2058 ui::EF_LEFT_MOUSE_BUTTON
);
2059 ui::EventTestApi
test_press(&press
);
2060 test_press
.set_source_device_id(10);
2061 scoped_ptr
<ui::Event
> new_event
;
2062 const ui::MouseEvent
* result
=
2063 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
2064 EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON
& result
->flags());
2065 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
2068 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
,
2072 ui::EF_LEFT_MOUSE_BUTTON
);
2073 ui::EventTestApi
test_release(&release
);
2074 test_release
.set_source_device_id(10);
2075 scoped_ptr
<ui::Event
> new_event
;
2076 const ui::MouseEvent
* result
=
2077 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
2078 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_ALT_DOWN
) & result
->flags());
2079 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
2081 #if defined(USE_X11)
2082 // No ALT in frst click, using XI2 native events.
2084 ui::ScopedXI2Event xev
;
2085 xev
.InitGenericButtonEvent(
2086 10, ui::ET_MOUSE_PRESSED
, gfx::Point(), ui::EF_LEFT_MOUSE_BUTTON
);
2087 ui::MouseEvent
press(xev
);
2088 scoped_ptr
<ui::Event
> new_event
;
2089 const ui::MouseEvent
* result
=
2090 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
2091 EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON
& result
->flags());
2092 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
2095 ui::ScopedXI2Event xev
;
2096 xev
.InitGenericButtonEvent(
2097 10, ui::ET_MOUSE_RELEASED
, gfx::Point(), kLeftAndAltFlag
);
2098 ui::MouseEvent
release(xev
);
2099 scoped_ptr
<ui::Event
> new_event
;
2100 const ui::MouseEvent
* result
=
2101 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
2102 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_ALT_DOWN
) & result
->flags());
2103 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
2107 // ALT on different device.
2109 ui::MouseEvent
press(ui::ET_MOUSE_PRESSED
,
2113 ui::EF_LEFT_MOUSE_BUTTON
);
2114 ui::EventTestApi
test_press(&press
);
2115 test_press
.set_source_device_id(11);
2116 scoped_ptr
<ui::Event
> new_event
;
2117 const ui::MouseEvent
* result
=
2118 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
2119 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
2120 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
2121 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
2124 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
,
2128 ui::EF_LEFT_MOUSE_BUTTON
);
2129 ui::EventTestApi
test_release(&release
);
2130 test_release
.set_source_device_id(10);
2131 scoped_ptr
<ui::Event
> new_event
;
2132 const ui::MouseEvent
* result
=
2133 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
2134 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_ALT_DOWN
) & result
->flags());
2135 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
2138 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
,
2142 ui::EF_LEFT_MOUSE_BUTTON
);
2143 ui::EventTestApi
test_release(&release
);
2144 test_release
.set_source_device_id(11);
2145 scoped_ptr
<ui::Event
> new_event
;
2146 const ui::MouseEvent
* result
=
2147 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
2148 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
2149 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
2150 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
2152 #if defined(USE_X11)
2153 // ALT on different device, using XI2 native events.
2155 ui::ScopedXI2Event xev
;
2156 xev
.InitGenericButtonEvent(
2157 11, ui::ET_MOUSE_PRESSED
, gfx::Point(), kLeftAndAltFlag
);
2158 ui::MouseEvent
press(xev
);
2159 scoped_ptr
<ui::Event
> new_event
;
2160 const ui::MouseEvent
* result
=
2161 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
2162 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
2163 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
2164 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
2167 ui::ScopedXI2Event xev
;
2168 xev
.InitGenericButtonEvent(
2169 10, ui::ET_MOUSE_RELEASED
, gfx::Point(), kLeftAndAltFlag
);
2170 ui::MouseEvent
release(xev
);
2171 scoped_ptr
<ui::Event
> new_event
;
2172 const ui::MouseEvent
* result
=
2173 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
2174 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_ALT_DOWN
) & result
->flags());
2175 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
2178 ui::ScopedXI2Event xev
;
2179 xev
.InitGenericButtonEvent(
2180 11, ui::ET_MOUSE_RELEASED
, gfx::Point(), kLeftAndAltFlag
);
2181 ui::MouseEvent
release(xev
);
2182 scoped_ptr
<ui::Event
> new_event
;
2183 const ui::MouseEvent
* result
=
2184 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
2185 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
2186 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
2187 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
2192 TEST_F(EventRewriterAshTest
, StickyKeyEventDispatchImpl
) {
2193 // Test the actual key event dispatch implementation.
2194 ScopedVector
<ui::Event
> events
;
2196 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
);
2198 EXPECT_EQ(1u, events
.size());
2199 EXPECT_EQ(ui::ET_KEY_PRESSED
, events
[0]->type());
2200 EXPECT_EQ(ui::VKEY_CONTROL
,
2201 static_cast<ui::KeyEvent
*>(events
[0])->key_code());
2203 // Test key press event is correctly modified and modifier release
2205 ui::KeyEvent
press(ui::ET_KEY_PRESSED
, ui::VKEY_C
, ui::EF_NONE
);
2206 ui::EventDispatchDetails details
= Send(&press
);
2208 EXPECT_EQ(2u, events
.size());
2209 EXPECT_EQ(ui::ET_KEY_PRESSED
, events
[0]->type());
2210 EXPECT_EQ(ui::VKEY_C
, static_cast<ui::KeyEvent
*>(events
[0])->key_code());
2211 EXPECT_TRUE(events
[0]->flags() & ui::EF_CONTROL_DOWN
);
2212 EXPECT_EQ(ui::ET_KEY_RELEASED
, events
[1]->type());
2213 EXPECT_EQ(ui::VKEY_CONTROL
,
2214 static_cast<ui::KeyEvent
*>(events
[1])->key_code());
2216 // Test key release event is not modified.
2217 ui::KeyEvent
release(ui::ET_KEY_RELEASED
, ui::VKEY_C
, ui::EF_NONE
);
2218 details
= Send(&release
);
2219 ASSERT_FALSE(details
.dispatcher_destroyed
);
2221 EXPECT_EQ(1u, events
.size());
2222 EXPECT_EQ(ui::ET_KEY_RELEASED
, events
[0]->type());
2223 EXPECT_EQ(ui::VKEY_C
, static_cast<ui::KeyEvent
*>(events
[0])->key_code());
2224 EXPECT_FALSE(events
[0]->flags() & ui::EF_CONTROL_DOWN
);
2227 TEST_F(EventRewriterAshTest
, MouseEventDispatchImpl
) {
2228 ScopedVector
<ui::Event
> events
;
2230 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
);
2233 // Test mouse press event is correctly modified.
2234 gfx::Point
location(0, 0);
2235 ui::MouseEvent
press(ui::ET_MOUSE_PRESSED
,
2238 ui::EF_LEFT_MOUSE_BUTTON
,
2239 ui::EF_LEFT_MOUSE_BUTTON
);
2240 ui::EventDispatchDetails details
= Send(&press
);
2241 ASSERT_FALSE(details
.dispatcher_destroyed
);
2243 EXPECT_EQ(1u, events
.size());
2244 EXPECT_EQ(ui::ET_MOUSE_PRESSED
, events
[0]->type());
2245 EXPECT_TRUE(events
[0]->flags() & ui::EF_CONTROL_DOWN
);
2247 // Test mouse release event is correctly modified and modifier release
2248 // event is sent. The mouse event should have the correct DIP location.
2249 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
,
2252 ui::EF_LEFT_MOUSE_BUTTON
,
2253 ui::EF_LEFT_MOUSE_BUTTON
);
2254 details
= Send(&release
);
2255 ASSERT_FALSE(details
.dispatcher_destroyed
);
2257 EXPECT_EQ(2u, events
.size());
2258 EXPECT_EQ(ui::ET_MOUSE_RELEASED
, events
[0]->type());
2259 EXPECT_TRUE(events
[0]->flags() & ui::EF_CONTROL_DOWN
);
2260 EXPECT_EQ(ui::ET_KEY_RELEASED
, events
[1]->type());
2261 EXPECT_EQ(ui::VKEY_CONTROL
,
2262 static_cast<ui::KeyEvent
*>(events
[1])->key_code());
2265 TEST_F(EventRewriterAshTest
, MouseWheelEventDispatchImpl
) {
2266 ScopedVector
<ui::Event
> events
;
2268 // Test positive mouse wheel event is correctly modified and modifier release
2270 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
);
2272 gfx::Point
location(0, 0);
2273 ui::MouseEvent
mev(ui::ET_MOUSEWHEEL
,
2276 ui::EF_LEFT_MOUSE_BUTTON
,
2277 ui::EF_LEFT_MOUSE_BUTTON
);
2278 ui::MouseWheelEvent
positive(mev
, 0, ui::MouseWheelEvent::kWheelDelta
);
2279 ui::EventDispatchDetails details
= Send(&positive
);
2280 ASSERT_FALSE(details
.dispatcher_destroyed
);
2282 EXPECT_EQ(2u, events
.size());
2283 EXPECT_TRUE(events
[0]->IsMouseWheelEvent());
2284 EXPECT_TRUE(events
[0]->flags() & ui::EF_CONTROL_DOWN
);
2285 EXPECT_EQ(ui::ET_KEY_RELEASED
, events
[1]->type());
2286 EXPECT_EQ(ui::VKEY_CONTROL
,
2287 static_cast<ui::KeyEvent
*>(events
[1])->key_code());
2289 // Test negative mouse wheel event is correctly modified and modifier release
2291 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
);
2293 ui::MouseWheelEvent
negative(mev
, 0, -ui::MouseWheelEvent::kWheelDelta
);
2294 details
= Send(&negative
);
2295 ASSERT_FALSE(details
.dispatcher_destroyed
);
2297 EXPECT_EQ(2u, events
.size());
2298 EXPECT_TRUE(events
[0]->IsMouseWheelEvent());
2299 EXPECT_TRUE(events
[0]->flags() & ui::EF_CONTROL_DOWN
);
2300 EXPECT_EQ(ui::ET_KEY_RELEASED
, events
[1]->type());
2301 EXPECT_EQ(ui::VKEY_CONTROL
,
2302 static_cast<ui::KeyEvent
*>(events
[1])->key_code());
2305 class StickyKeysOverlayTest
: public EventRewriterAshTest
{
2307 StickyKeysOverlayTest() : overlay_(NULL
) {}
2309 virtual ~StickyKeysOverlayTest() {}
2311 virtual void SetUp() override
{
2312 EventRewriterAshTest::SetUp();
2313 overlay_
= sticky_keys_controller_
->GetOverlayForTest();
2314 ASSERT_TRUE(overlay_
);
2317 ash::StickyKeysOverlay
* overlay_
;
2320 TEST_F(StickyKeysOverlayTest
, OneModifierEnabled
) {
2321 EXPECT_FALSE(overlay_
->is_visible());
2322 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2323 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2325 // Pressing modifier key should show overlay.
2326 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
);
2327 EXPECT_TRUE(overlay_
->is_visible());
2328 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
2329 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2331 // Pressing a normal key should hide overlay.
2332 SendActivateStickyKeyPattern(ui::VKEY_T
);
2333 EXPECT_FALSE(overlay_
->is_visible());
2334 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2335 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2338 TEST_F(StickyKeysOverlayTest
, TwoModifiersEnabled
) {
2339 EXPECT_FALSE(overlay_
->is_visible());
2340 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2341 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2342 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2343 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
2345 // Pressing two modifiers should show overlay.
2346 SendActivateStickyKeyPattern(ui::VKEY_SHIFT
);
2347 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
);
2348 EXPECT_TRUE(overlay_
->is_visible());
2349 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
2350 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
2351 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
2352 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2354 // Pressing a normal key should hide overlay.
2355 SendActivateStickyKeyPattern(ui::VKEY_N
);
2356 EXPECT_FALSE(overlay_
->is_visible());
2357 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2358 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2359 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2360 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
2363 TEST_F(StickyKeysOverlayTest
, LockedModifier
) {
2364 EXPECT_FALSE(overlay_
->is_visible());
2365 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2366 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
2368 // Pressing a modifier key twice should lock modifier and show overlay.
2369 SendActivateStickyKeyPattern(ui::VKEY_LMENU
);
2370 SendActivateStickyKeyPattern(ui::VKEY_LMENU
);
2371 EXPECT_TRUE(overlay_
->is_visible());
2372 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
2373 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
2375 // Pressing a normal key should not hide overlay.
2376 SendActivateStickyKeyPattern(ui::VKEY_D
);
2377 EXPECT_TRUE(overlay_
->is_visible());
2378 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
2379 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
2382 TEST_F(StickyKeysOverlayTest
, LockedAndNormalModifier
) {
2383 EXPECT_FALSE(overlay_
->is_visible());
2384 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2385 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2386 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2387 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
2389 // Pressing a modifier key twice should lock modifier and show overlay.
2390 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
);
2391 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
);
2392 EXPECT_TRUE(overlay_
->is_visible());
2393 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
2394 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2396 // Pressing another modifier key should still show overlay.
2397 SendActivateStickyKeyPattern(ui::VKEY_SHIFT
);
2398 EXPECT_TRUE(overlay_
->is_visible());
2399 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
2400 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2401 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
2402 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
2404 // Pressing a normal key should not hide overlay but disable normal modifier.
2405 SendActivateStickyKeyPattern(ui::VKEY_D
);
2406 EXPECT_TRUE(overlay_
->is_visible());
2407 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
2408 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2409 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2410 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
2413 TEST_F(StickyKeysOverlayTest
, ModifiersDisabled
) {
2414 EXPECT_FALSE(overlay_
->is_visible());
2415 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2416 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2417 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2418 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
2419 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2420 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
2421 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2422 overlay_
->GetModifierKeyState(ui::EF_COMMAND_DOWN
));
2424 // Enable modifiers.
2425 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
);
2426 SendActivateStickyKeyPattern(ui::VKEY_SHIFT
);
2427 SendActivateStickyKeyPattern(ui::VKEY_SHIFT
);
2428 SendActivateStickyKeyPattern(ui::VKEY_LMENU
);
2429 SendActivateStickyKeyPattern(ui::VKEY_COMMAND
);
2430 SendActivateStickyKeyPattern(ui::VKEY_COMMAND
);
2432 EXPECT_TRUE(overlay_
->is_visible());
2433 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
2434 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2435 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
2436 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
2437 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
2438 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
2439 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
2440 overlay_
->GetModifierKeyState(ui::EF_COMMAND_DOWN
));
2442 // Disable modifiers and overlay should be hidden.
2443 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
);
2444 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
);
2445 SendActivateStickyKeyPattern(ui::VKEY_SHIFT
);
2446 SendActivateStickyKeyPattern(ui::VKEY_LMENU
);
2447 SendActivateStickyKeyPattern(ui::VKEY_LMENU
);
2448 SendActivateStickyKeyPattern(ui::VKEY_COMMAND
);
2450 EXPECT_FALSE(overlay_
->is_visible());
2451 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2452 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2453 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2454 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
2455 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2456 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
2457 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2458 overlay_
->GetModifierKeyState(ui::EF_COMMAND_DOWN
));
2461 TEST_F(StickyKeysOverlayTest
, ModifierVisibility
) {
2462 // All but AltGr and Mod3 should initially be visible.
2463 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_CONTROL_DOWN
));
2464 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_SHIFT_DOWN
));
2465 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_ALT_DOWN
));
2466 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_COMMAND_DOWN
));
2467 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_ALTGR_DOWN
));
2468 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_MOD3_DOWN
));
2470 // Turn all modifiers on.
2471 sticky_keys_controller_
->SetModifiersEnabled(true, true);
2472 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_CONTROL_DOWN
));
2473 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_SHIFT_DOWN
));
2474 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_ALT_DOWN
));
2475 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_COMMAND_DOWN
));
2476 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_ALTGR_DOWN
));
2477 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_MOD3_DOWN
));
2480 sticky_keys_controller_
->SetModifiersEnabled(false, true);
2481 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_ALTGR_DOWN
));
2482 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_MOD3_DOWN
));
2485 sticky_keys_controller_
->SetModifiersEnabled(true, false);
2486 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_ALTGR_DOWN
));
2487 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_MOD3_DOWN
));
2489 // Turn off AltGr and Mod3.
2490 sticky_keys_controller_
->SetModifiersEnabled(false, false);
2491 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_ALTGR_DOWN
));
2492 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_MOD3_DOWN
));
2495 } // namespace chromeos