Adding instrumentation to locate the source of jankiness
[chromium-blink-merge.git] / chrome / browser / chromeos / events / event_rewriter_unittest.cc
blob79845a6619920b4c9fb0af349345bfa17baa67cd
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/events/event_rewriter.h"
7 #include <vector>
9 #include "ash/shell.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"
35 #if defined(USE_X11)
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"
42 #endif
44 namespace {
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,
52 int ui_flags,
53 ui::EventType ui_type) {
54 return base::StringPrintf("ui_keycode=0x%X ui_flags=0x%X ui_type=%d",
55 ui_keycode,
56 ui_flags & ~ui::EF_IS_REPEAT,
57 ui_type);
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,
67 int ui_flags,
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);
72 if (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.
79 struct KeyTestCase {
80 enum {
81 // Test types:
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.
90 int test;
91 ui::EventType type;
92 struct {
93 ui::KeyboardCode key_code;
94 int flags;
95 } input, expected;
98 #if defined(USE_X11)
99 // Check rewriting of an X11-based key event.
100 void CheckX11KeyTestCase(const std::string& expected,
101 chromeos::EventRewriter* rewriter,
102 const KeyTestCase& test,
103 XEvent* xevent) {
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));
126 #endif
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.
138 EXPECT_EQ(
139 expected,
140 GetRewrittenEventAsString(
141 rewriter, test.input.key_code, test.input.flags, test.type));
144 #if defined(USE_X11)
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,
155 kKeyboardDeviceId,
156 test.type,
157 test.input.key_code,
158 test.input.flags);
159 xevent = xev;
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));
164 if (xievent->detail)
165 CheckX11KeyTestCase(expected, rewriter, test, xevent);
167 #endif
170 // Table entry for simple single function key event rewriting tests.
171 struct FunctionKeyTestCase {
172 ui::EventType type;
173 struct {
174 ui::KeyboardCode key_code;
175 int flags;
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,
190 test.type);
191 // Check rewriting of a non-native-based key event.
192 EXPECT_EQ(
193 vkey_expected,
194 GetRewrittenEventAsString(
195 rewriter, test.input.key_code, test.input.flags, test.type));
197 #if defined(USE_X11)
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,
212 test.type);
213 EXPECT_EQ(native_expected, GetKeyEventAsString(rewritten_key_event));
215 #endif
218 } // namespace
220 namespace chromeos {
222 class EventRewriterTest : public ash::test::AshTestBase {
223 public:
224 EventRewriterTest()
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();
245 protected:
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())
255 : &event;
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) {
299 SCOPED_TRACE(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) {
335 SCOPED_TRACE(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) {
361 SCOPED_TRACE(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) {
384 SCOPED_TRACE(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) {
513 SCOPED_TRACE(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
549 // modifiers".
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) {
556 SCOPED_TRACE(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) {
616 SCOPED_TRACE(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) {
652 SCOPED_TRACE(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
696 // modifiers.
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
702 // the Alt modifier.
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) {
709 SCOPED_TRACE(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) {
733 SCOPED_TRACE(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) {
758 SCOPED_TRACE(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,
780 {ui::VKEY_LWIN,
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) {
800 SCOPED_TRACE(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) {
824 SCOPED_TRACE(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) {
849 SCOPED_TRACE(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) {
876 SCOPED_TRACE(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,
893 {ui::VKEY_LWIN,
894 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN},
895 {ui::VKEY_MENU,
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) {
914 SCOPED_TRACE(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_);
934 // Press Search.
935 EXPECT_EQ(
936 GetExpectedResultAsString(ui::VKEY_CAPITAL,
937 ui::EF_CAPS_LOCK_DOWN | ui::EF_MOD3_DOWN,
938 ui::ET_KEY_PRESSED),
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_);
944 // Release Search.
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_);
952 // Press Search.
953 EXPECT_EQ(
954 GetExpectedResultAsString(ui::VKEY_CAPITAL,
955 ui::EF_CAPS_LOCK_DOWN | ui::EF_MOD3_DOWN,
956 ui::ET_KEY_PRESSED),
957 GetRewrittenEventAsString(&rewriter,
958 ui::VKEY_LWIN,
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_);
964 // Release Search.
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,
975 ui::ET_KEY_PRESSED),
976 GetRewrittenEventAsString(&rewriter,
977 ui::VKEY_CAPITAL,
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
1026 // specified.
1027 {KeyTestCase::TEST_VKEY,
1028 ui::ET_KEY_PRESSED,
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,
1040 ui::ET_KEY_PRESSED,
1041 {ui::VKEY_A, ui::EF_NONE},
1042 {ui::VKEY_A, ui::EF_NONE}},
1045 for (size_t i = 0; i < arraysize(tests); ++i) {
1046 SCOPED_TRACE(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));
1075 // Release F15
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.
1081 EXPECT_EQ(
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.
1095 EXPECT_EQ(
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));
1111 // Release F15
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.
1117 EXPECT_EQ(
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));
1133 // Release F15
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.
1139 EXPECT_EQ(
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));
1157 // Release F15
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.
1163 EXPECT_EQ(
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
1191 // ControlMask
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
1197 // ControlMask.
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) {
1204 SCOPED_TRACE(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.
1224 EXPECT_EQ(
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,
1255 {ui::VKEY_BACK,
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}},
1258 // Alt+Up -> Prior
1259 {KeyTestCase::TEST_ALL, ui::ET_KEY_PRESSED,
1260 {ui::VKEY_UP, ui::EF_ALT_DOWN},
1261 {ui::VKEY_PRIOR, ui::EF_NONE}},
1262 // Alt+Down -> Next
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,
1285 {ui::VKEY_UP,
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,
1290 {ui::VKEY_DOWN,
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}},
1294 // Period -> Period
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) {
1337 SCOPED_TRACE(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[] = {
1350 // F1 -> Back
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}},
1363 // F2 -> Forward
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}},
1376 // F3 -> Refresh
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}},
1467 // F10 -> Volume Up
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}},
1480 // F11 -> F11
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}},
1493 // F12 -> F12
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
1558 // key.
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) {
1660 SCOPED_TRACE(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,
1690 {ui::VKEY_DOWN,
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) {
1696 SCOPED_TRACE(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);
1741 #endif
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);
1763 #endif
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 {
1775 public:
1776 EventBuffer() {}
1777 virtual ~EventBuffer() {}
1779 void PopEvents(ScopedVector<ui::Event>* events) {
1780 events->clear();
1781 events->swap(events_);
1784 private:
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()) {
1791 events_.push_back(
1792 new ui::MouseWheelEvent(*static_cast<ui::MouseWheelEvent*>(event)));
1793 } else if (event->IsMouseEvent()) {
1794 events_.push_back(
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 {
1807 public:
1808 explicit TestEventSource(ui::EventProcessor* processor)
1809 : processor_(processor) {}
1810 virtual ui::EventProcessor* GetEventProcessor() override {
1811 return processor_;
1813 ui::EventDispatchDetails Send(ui::Event* event) {
1814 return SendEventToProcessor(event);
1817 private:
1818 ui::EventProcessor* processor_;
1821 // Tests of event rewriting that depend on the Ash window manager.
1822 class EventRewriterAshTest : public ash::test::AshTestBase {
1823 public:
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);
1850 protected:
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);
1866 #endif
1867 source_.AddEventRewriter(rewriter_.get());
1868 sticky_keys_controller_->Enable(true);
1871 virtual void TearDown() override {
1872 rewriter_.reset();
1873 AshTestBase::TearDown();
1876 protected:
1877 ash::StickyKeysController* sticky_keys_controller_;
1879 private:
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);
1906 PopEvents(&events);
1907 EXPECT_EQ(1u, events.size());
1908 EXPECT_EQ(
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);
1920 PopEvents(&events);
1921 EXPECT_EQ(1u, events.size());
1922 EXPECT_EQ(
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);
1931 PopEvents(&events);
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)
1955 // to Right Button.
1956 ui::ScopedXI2Event xev;
1957 xev.InitGenericButtonEvent(10,
1958 ui::ET_MOUSE_PRESSED,
1959 gfx::Point(),
1960 ui::EF_LEFT_MOUSE_BUTTON | ui::EF_CONTROL_DOWN);
1961 ui::MouseEvent press(xev);
1962 // Sanity check.
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,
1990 gfx::Point(),
1991 gfx::Point(),
1992 kLeftAndAltFlag,
1993 ui::EF_LEFT_MOUSE_BUTTON);
1994 ui::EventTestApi test_press(&press);
1995 test_press.set_source_device_id(10);
1996 // Sanity check.
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,
2008 gfx::Point(),
2009 gfx::Point(),
2010 kLeftAndAltFlag,
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);
2028 // Sanity check.
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());
2050 #endif
2052 // No ALT in frst click.
2054 ui::MouseEvent press(ui::ET_MOUSE_PRESSED,
2055 gfx::Point(),
2056 gfx::Point(),
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,
2069 gfx::Point(),
2070 gfx::Point(),
2071 kLeftAndAltFlag,
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());
2105 #endif
2107 // ALT on different device.
2109 ui::MouseEvent press(ui::ET_MOUSE_PRESSED,
2110 gfx::Point(),
2111 gfx::Point(),
2112 kLeftAndAltFlag,
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,
2125 gfx::Point(),
2126 gfx::Point(),
2127 kLeftAndAltFlag,
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,
2139 gfx::Point(),
2140 gfx::Point(),
2141 kLeftAndAltFlag,
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());
2189 #endif
2192 TEST_F(EventRewriterAshTest, StickyKeyEventDispatchImpl) {
2193 // Test the actual key event dispatch implementation.
2194 ScopedVector<ui::Event> events;
2196 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2197 PopEvents(&events);
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
2204 // event is sent.
2205 ui::KeyEvent press(ui::ET_KEY_PRESSED, ui::VKEY_C, ui::EF_NONE);
2206 ui::EventDispatchDetails details = Send(&press);
2207 PopEvents(&events);
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);
2220 PopEvents(&events);
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);
2231 PopEvents(&events);
2233 // Test mouse press event is correctly modified.
2234 gfx::Point location(0, 0);
2235 ui::MouseEvent press(ui::ET_MOUSE_PRESSED,
2236 location,
2237 location,
2238 ui::EF_LEFT_MOUSE_BUTTON,
2239 ui::EF_LEFT_MOUSE_BUTTON);
2240 ui::EventDispatchDetails details = Send(&press);
2241 ASSERT_FALSE(details.dispatcher_destroyed);
2242 PopEvents(&events);
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,
2250 location,
2251 location,
2252 ui::EF_LEFT_MOUSE_BUTTON,
2253 ui::EF_LEFT_MOUSE_BUTTON);
2254 details = Send(&release);
2255 ASSERT_FALSE(details.dispatcher_destroyed);
2256 PopEvents(&events);
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
2269 // event is sent.
2270 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2271 PopEvents(&events);
2272 gfx::Point location(0, 0);
2273 ui::MouseEvent mev(ui::ET_MOUSEWHEEL,
2274 location,
2275 location,
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);
2281 PopEvents(&events);
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
2290 // event is sent.
2291 SendActivateStickyKeyPattern(ui::VKEY_CONTROL);
2292 PopEvents(&events);
2293 ui::MouseWheelEvent negative(mev, 0, -ui::MouseWheelEvent::kWheelDelta);
2294 details = Send(&negative);
2295 ASSERT_FALSE(details.dispatcher_destroyed);
2296 PopEvents(&events);
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 {
2306 public:
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));
2479 // Turn off Mod3.
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));
2484 // Turn off AltGr.
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