1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/events/event_rewriter.h"
10 #include "ash/sticky_keys/sticky_keys_controller.h"
11 #include "ash/sticky_keys/sticky_keys_overlay.h"
12 #include "ash/test/ash_test_base.h"
13 #include "ash/wm/window_state.h"
14 #include "base/basictypes.h"
15 #include "base/command_line.h"
16 #include "base/prefs/pref_member.h"
17 #include "base/strings/stringprintf.h"
18 #include "chrome/browser/chromeos/input_method/input_method_configuration.h"
19 #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h"
20 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
21 #include "chrome/browser/chromeos/preferences.h"
22 #include "chrome/common/pref_names.h"
23 #include "chrome/test/base/testing_pref_service_syncable.h"
24 #include "chromeos/chromeos_switches.h"
25 #include "components/user_manager/fake_user_manager.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "ui/aura/window.h"
28 #include "ui/aura/window_tree_host.h"
29 #include "ui/base/ime/chromeos/fake_ime_keyboard.h"
30 #include "ui/events/event.h"
31 #include "ui/events/event_rewriter.h"
32 #include "ui/events/event_utils.h"
33 #include "ui/events/test/events_test_utils.h"
34 #include "ui/events/test/test_event_processor.h"
37 #include <X11/keysym.h>
39 #include "ui/events/devices/x11/touch_factory_x11.h"
40 #include "ui/events/event_utils.h"
41 #include "ui/events/test/events_test_utils_x11.h"
42 #include "ui/gfx/x/x11_types.h"
47 // The device id of the test touchpad device.
48 const unsigned int kTouchPadDeviceId
= 1;
49 const int kKeyboardDeviceId
= 2;
50 const int kMasterKeyboardDeviceId
= 3;
52 std::string
GetExpectedResultAsString(ui::KeyboardCode ui_keycode
,
54 ui::EventType ui_type
) {
55 return base::StringPrintf("ui_keycode=0x%X ui_flags=0x%X ui_type=%d",
57 ui_flags
& ~ui::EF_IS_REPEAT
,
61 std::string
GetKeyEventAsString(const ui::KeyEvent
& keyevent
) {
62 return GetExpectedResultAsString(
63 keyevent
.key_code(), keyevent
.flags(), keyevent
.type());
66 std::string
GetRewrittenEventAsString(chromeos::EventRewriter
* rewriter
,
67 ui::KeyboardCode ui_keycode
,
69 ui::EventType ui_type
) {
70 const ui::KeyEvent
event(ui_type
, ui_keycode
, ui_flags
);
71 scoped_ptr
<ui::Event
> new_event
;
72 rewriter
->RewriteEvent(event
, &new_event
);
74 return GetKeyEventAsString(
75 static_cast<const ui::KeyEvent
&>(*new_event
.get()));
76 return GetKeyEventAsString(event
);
79 // Table entry for simple single key event rewriting tests.
83 TEST_VKEY
= 1 << 0, // Test ui::KeyEvent with no native event
84 TEST_X11
= 1 << 1, // Test ui::KeyEvent with native XKeyEvent
85 TEST_ALL
= TEST_VKEY
|TEST_X11
,
86 // Special test flags:
87 NUMPAD
= 1 << 8, // Set EF_NUMPAD_KEY on native-based event, because
88 // |XKeysymForWindowsKeyCode()| can not distinguish
89 // between pairs like XK_Insert and XK_KP_Insert.
94 ui::KeyboardCode key_code
;
100 // Check rewriting of an X11-based key event.
101 void CheckX11KeyTestCase(const std::string
& expected
,
102 chromeos::EventRewriter
* rewriter
,
103 const KeyTestCase
& test
,
105 ui::KeyEvent
xkey_event(xevent
);
106 if (test
.test
& KeyTestCase::NUMPAD
)
107 xkey_event
.set_flags(xkey_event
.flags() | ui::EF_NUMPAD_KEY
);
108 // Verify that the X11-based key event is as expected.
109 EXPECT_EQ(GetExpectedResultAsString(
110 test
.input
.key_code
, test
.input
.flags
, test
.type
),
111 GetKeyEventAsString(xkey_event
));
112 // Rewrite the event and check the result.
113 scoped_ptr
<ui::Event
> new_event
;
114 rewriter
->RewriteEvent(xkey_event
, &new_event
);
115 ui::KeyEvent
& rewritten_key_event
=
116 new_event
? *static_cast<ui::KeyEvent
*>(new_event
.get()) : xkey_event
;
117 EXPECT_EQ(expected
, GetKeyEventAsString(rewritten_key_event
));
118 if (xevent
->type
== GenericEvent
)
119 EXPECT_EQ(nullptr, rewritten_key_event
.native_event());
121 EXPECT_NE(nullptr, rewritten_key_event
.native_event());
125 // Tests a single stateless key rewrite operation.
126 // |i| is a an identifying number to locate failing tests in the tables.
127 void CheckKeyTestCase(chromeos::EventRewriter
* rewriter
,
128 const KeyTestCase
& test
) {
129 std::string expected
=
130 GetExpectedResultAsString(
131 test
.expected
.key_code
, test
.expected
.flags
, test
.type
);
133 if (test
.test
& KeyTestCase::TEST_VKEY
) {
134 // Check rewriting of a non-native-based key event.
137 GetRewrittenEventAsString(
138 rewriter
, test
.input
.key_code
, test
.input
.flags
, test
.type
));
142 if (test
.test
& KeyTestCase::TEST_X11
) {
143 ui::ScopedXI2Event xev
;
144 // Test an XKeyEvent.
145 xev
.InitKeyEvent(test
.type
, test
.input
.key_code
, test
.input
.flags
);
146 XEvent
* xevent
= xev
;
147 DCHECK((xevent
->type
== KeyPress
) || (xevent
->type
== KeyRelease
));
148 if (xevent
->xkey
.keycode
)
149 CheckX11KeyTestCase(expected
, rewriter
, test
, xevent
);
150 // Test an XI2 GenericEvent.
151 xev
.InitGenericKeyEvent(kMasterKeyboardDeviceId
,
157 DCHECK(xevent
->type
== GenericEvent
);
158 XIDeviceEvent
* xievent
= static_cast<XIDeviceEvent
*>(xevent
->xcookie
.data
);
159 DCHECK((xievent
->evtype
== XI_KeyPress
) ||
160 (xievent
->evtype
== XI_KeyRelease
));
162 CheckX11KeyTestCase(expected
, rewriter
, test
, xevent
);
167 // Table entry for simple single function key event rewriting tests.
168 struct FunctionKeyTestCase
{
171 ui::KeyboardCode key_code
;
173 } input
, vkey_expected
, native_expected
;
176 // Tests a single stateless function key rewrite operation.
177 // |i| is a an identifying number to locate failing tests in the tables.
178 // Function key mapping differs from the other key mappings because the
179 // EF_FUNCTION_KEY flag is set during ui::KeyEvent construction when passing in
180 // a native X11 event and the flag is not set when using other constructors.
181 void CheckFunctionKeyTestCase(chromeos::EventRewriter
* rewriter
,
182 const FunctionKeyTestCase
& test
) {
183 std::string vkey_expected
=
184 GetExpectedResultAsString(
185 test
.vkey_expected
.key_code
,
186 test
.vkey_expected
.flags
,
188 // Check rewriting of a non-native-based key event.
191 GetRewrittenEventAsString(
192 rewriter
, test
.input
.key_code
, test
.input
.flags
, test
.type
));
195 ui::ScopedXI2Event xev
;
196 xev
.InitKeyEvent(test
.type
, test
.input
.key_code
, test
.input
.flags
);
197 XEvent
* xevent
= xev
;
198 if (xevent
->xkey
.keycode
) {
199 ui::KeyEvent
xkey_event(xevent
);
200 // Rewrite the event and check the result.
201 scoped_ptr
<ui::Event
> new_event
;
202 rewriter
->RewriteEvent(xkey_event
, &new_event
);
203 ui::KeyEvent
& rewritten_key_event
=
204 new_event
? *static_cast<ui::KeyEvent
*>(new_event
.get()) : xkey_event
;
205 std::string native_expected
=
206 GetExpectedResultAsString(
207 test
.native_expected
.key_code
,
208 test
.native_expected
.flags
,
210 EXPECT_EQ(native_expected
, GetKeyEventAsString(rewritten_key_event
));
219 class EventRewriterTest
: public ash::test::AshTestBase
{
222 : fake_user_manager_(new user_manager::FakeUserManager
),
223 user_manager_enabler_(fake_user_manager_
),
224 input_method_manager_mock_(NULL
) {}
225 ~EventRewriterTest() override
{}
227 void SetUp() override
{
228 input_method_manager_mock_
=
229 new chromeos::input_method::MockInputMethodManager
;
230 chromeos::input_method::InitializeForTesting(
231 input_method_manager_mock_
); // pass ownership
233 AshTestBase::SetUp();
236 void TearDown() override
{
237 AshTestBase::TearDown();
238 // Shutdown() deletes the IME mock object.
239 chromeos::input_method::Shutdown();
243 void TestRewriteNumPadKeys();
244 void TestRewriteNumPadKeysOnAppleKeyboard();
246 const ui::MouseEvent
* RewriteMouseButtonEvent(
247 chromeos::EventRewriter
* rewriter
,
248 const ui::MouseEvent
& event
,
249 scoped_ptr
<ui::Event
>* new_event
) {
250 rewriter
->RewriteMouseButtonEventForTesting(event
, new_event
);
251 return *new_event
? static_cast<const ui::MouseEvent
*>(new_event
->get())
255 user_manager::FakeUserManager
* fake_user_manager_
; // Not owned.
256 chromeos::ScopedUserManagerEnabler user_manager_enabler_
;
257 chromeos::input_method::MockInputMethodManager
* input_method_manager_mock_
;
260 TEST_F(EventRewriterTest
, TestRewriteCommandToControl
) {
261 // First, test with a PC keyboard.
262 TestingPrefServiceSyncable prefs
;
263 EventRewriter
rewriter(NULL
);
264 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
265 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
266 rewriter
.set_pref_service_for_testing(&prefs
);
268 KeyTestCase pc_keyboard_tests
[] = {
269 // VKEY_A, Alt modifier.
270 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
271 {ui::VKEY_A
, ui::EF_ALT_DOWN
},
272 {ui::VKEY_A
, ui::EF_ALT_DOWN
}},
274 // VKEY_A, Win modifier.
275 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
276 {ui::VKEY_A
, ui::EF_COMMAND_DOWN
},
277 {ui::VKEY_A
, ui::EF_COMMAND_DOWN
}},
279 // VKEY_A, Alt+Win modifier.
280 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
281 {ui::VKEY_A
, ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
},
282 {ui::VKEY_A
, ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
}},
284 // VKEY_LWIN (left Windows key), Alt modifier.
285 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
286 {ui::VKEY_LWIN
, ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
},
287 {ui::VKEY_LWIN
, ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
}},
289 // VKEY_RWIN (right Windows key), Alt modifier.
290 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
291 {ui::VKEY_RWIN
, ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
},
292 {ui::VKEY_RWIN
, ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
}},
295 for (size_t i
= 0; i
< arraysize(pc_keyboard_tests
); ++i
) {
297 CheckKeyTestCase(&rewriter
, pc_keyboard_tests
[i
]);
300 // An Apple keyboard reusing the ID, zero.
301 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "Apple Keyboard");
302 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
304 KeyTestCase apple_keyboard_tests
[] = {
305 // VKEY_A, Alt modifier.
306 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
307 {ui::VKEY_A
, ui::EF_ALT_DOWN
},
308 {ui::VKEY_A
, ui::EF_ALT_DOWN
}},
310 // VKEY_A, Win modifier.
311 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
312 {ui::VKEY_A
, ui::EF_COMMAND_DOWN
},
313 {ui::VKEY_A
, ui::EF_CONTROL_DOWN
}},
315 // VKEY_A, Alt+Win modifier.
316 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
317 {ui::VKEY_A
, ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
},
318 {ui::VKEY_A
, ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
}},
320 // VKEY_LWIN (left Windows key), Alt modifier.
321 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
322 {ui::VKEY_LWIN
, ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
},
323 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
}},
325 // VKEY_RWIN (right Windows key), Alt modifier.
326 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
327 {ui::VKEY_RWIN
, ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
},
328 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
}},
331 for (size_t i
= 0; i
< arraysize(apple_keyboard_tests
); ++i
) {
333 CheckKeyTestCase(&rewriter
, apple_keyboard_tests
[i
]);
337 // For crbug.com/133896.
338 TEST_F(EventRewriterTest
, TestRewriteCommandToControlWithControlRemapped
) {
339 // Remap Control to Alt.
340 TestingPrefServiceSyncable prefs
;
341 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
342 IntegerPrefMember control
;
343 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
344 control
.SetValue(chromeos::input_method::kAltKey
);
346 EventRewriter
rewriter(NULL
);
347 rewriter
.set_pref_service_for_testing(&prefs
);
348 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
349 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
351 KeyTestCase pc_keyboard_tests
[] = {// Control should be remapped to Alt.
352 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
353 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
},
354 {ui::VKEY_MENU
, ui::EF_ALT_DOWN
}},
357 for (size_t i
= 0; i
< arraysize(pc_keyboard_tests
); ++i
) {
359 CheckKeyTestCase(&rewriter
, pc_keyboard_tests
[i
]);
362 // An Apple keyboard reusing the ID, zero.
363 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "Apple Keyboard");
364 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
366 KeyTestCase apple_keyboard_tests
[] = {
367 // VKEY_LWIN (left Command key) with Alt modifier. The remapped Command
368 // key should never be re-remapped to Alt.
369 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
370 {ui::VKEY_LWIN
, ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
},
371 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
}},
373 // VKEY_RWIN (right Command key) with Alt modifier. The remapped Command
374 // key should never be re-remapped to Alt.
375 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
376 {ui::VKEY_RWIN
, ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
},
377 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
}},
380 for (size_t i
= 0; i
< arraysize(apple_keyboard_tests
); ++i
) {
382 CheckKeyTestCase(&rewriter
, apple_keyboard_tests
[i
]);
386 void EventRewriterTest::TestRewriteNumPadKeys() {
387 TestingPrefServiceSyncable prefs
;
388 EventRewriter
rewriter(NULL
);
389 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
390 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
391 rewriter
.set_pref_service_for_testing(&prefs
);
393 KeyTestCase tests
[] = {
394 // XK_KP_Insert (= NumPad 0 without Num Lock), no modifier.
395 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
396 {ui::VKEY_INSERT
, ui::EF_NUMPAD_KEY
},
397 {ui::VKEY_NUMPAD0
, ui::EF_NUMPAD_KEY
}},
399 // XK_KP_Insert (= NumPad 0 without Num Lock), Alt modifier.
400 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
401 {ui::VKEY_INSERT
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
},
402 {ui::VKEY_NUMPAD0
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
}},
404 // XK_KP_Delete (= NumPad . without Num Lock), Alt modifier.
405 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
406 {ui::VKEY_DELETE
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
},
407 {ui::VKEY_DECIMAL
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
}},
409 // XK_KP_End (= NumPad 1 without Num Lock), Alt modifier.
410 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
411 {ui::VKEY_END
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
},
412 {ui::VKEY_NUMPAD1
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
}},
414 // XK_KP_Down (= NumPad 2 without Num Lock), Alt modifier.
415 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
416 {ui::VKEY_DOWN
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
},
417 {ui::VKEY_NUMPAD2
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
}},
419 // XK_KP_Next (= NumPad 3 without Num Lock), Alt modifier.
420 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
421 {ui::VKEY_NEXT
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
},
422 {ui::VKEY_NUMPAD3
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
}},
424 // XK_KP_Left (= NumPad 4 without Num Lock), Alt modifier.
425 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
426 {ui::VKEY_LEFT
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
},
427 {ui::VKEY_NUMPAD4
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
}},
429 // XK_KP_Begin (= NumPad 5 without Num Lock), Alt modifier.
430 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
431 {ui::VKEY_CLEAR
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
},
432 {ui::VKEY_NUMPAD5
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
}},
434 // XK_KP_Right (= NumPad 6 without Num Lock), Alt modifier.
435 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
436 {ui::VKEY_RIGHT
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
},
437 {ui::VKEY_NUMPAD6
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
}},
439 // XK_KP_Home (= NumPad 7 without Num Lock), Alt modifier.
440 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
441 {ui::VKEY_HOME
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
},
442 {ui::VKEY_NUMPAD7
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
}},
444 // XK_KP_Up (= NumPad 8 without Num Lock), Alt modifier.
445 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
446 {ui::VKEY_UP
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
},
447 {ui::VKEY_NUMPAD8
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
}},
449 // XK_KP_Prior (= NumPad 9 without Num Lock), Alt modifier.
450 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
451 {ui::VKEY_PRIOR
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
},
452 {ui::VKEY_NUMPAD9
, ui::EF_ALT_DOWN
| ui::EF_NUMPAD_KEY
}},
454 // XK_KP_0 (= NumPad 0 with Num Lock), Num Lock modifier.
455 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
456 {ui::VKEY_NUMPAD0
, ui::EF_NUMPAD_KEY
},
457 {ui::VKEY_NUMPAD0
, ui::EF_NUMPAD_KEY
}},
459 // XK_KP_DECIMAL (= NumPad . with Num Lock), Num Lock modifier.
460 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
461 {ui::VKEY_DECIMAL
, ui::EF_NUMPAD_KEY
},
462 {ui::VKEY_DECIMAL
, ui::EF_NUMPAD_KEY
}},
464 // XK_KP_1 (= NumPad 1 with Num Lock), Num Lock modifier.
465 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
466 {ui::VKEY_NUMPAD1
, ui::EF_NUMPAD_KEY
},
467 {ui::VKEY_NUMPAD1
, ui::EF_NUMPAD_KEY
}},
469 // XK_KP_2 (= NumPad 2 with Num Lock), Num Lock modifier.
470 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
471 {ui::VKEY_NUMPAD2
, ui::EF_NUMPAD_KEY
},
472 {ui::VKEY_NUMPAD2
, ui::EF_NUMPAD_KEY
}},
474 // XK_KP_3 (= NumPad 3 with Num Lock), Num Lock modifier.
475 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
476 {ui::VKEY_NUMPAD3
, ui::EF_NUMPAD_KEY
},
477 {ui::VKEY_NUMPAD3
, ui::EF_NUMPAD_KEY
}},
479 // XK_KP_4 (= NumPad 4 with Num Lock), Num Lock modifier.
480 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
481 {ui::VKEY_NUMPAD4
, ui::EF_NUMPAD_KEY
},
482 {ui::VKEY_NUMPAD4
, ui::EF_NUMPAD_KEY
}},
484 // XK_KP_5 (= NumPad 5 with Num Lock), Num Lock modifier.
485 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
486 {ui::VKEY_NUMPAD5
, ui::EF_NUMPAD_KEY
},
487 {ui::VKEY_NUMPAD5
, ui::EF_NUMPAD_KEY
}},
489 // XK_KP_6 (= NumPad 6 with Num Lock), Num Lock modifier.
490 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
491 {ui::VKEY_NUMPAD6
, ui::EF_NUMPAD_KEY
},
492 {ui::VKEY_NUMPAD6
, ui::EF_NUMPAD_KEY
}},
494 // XK_KP_7 (= NumPad 7 with Num Lock), Num Lock modifier.
495 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
496 {ui::VKEY_NUMPAD7
, ui::EF_NUMPAD_KEY
},
497 {ui::VKEY_NUMPAD7
, ui::EF_NUMPAD_KEY
}},
499 // XK_KP_8 (= NumPad 8 with Num Lock), Num Lock modifier.
500 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
501 {ui::VKEY_NUMPAD8
, ui::EF_NUMPAD_KEY
},
502 {ui::VKEY_NUMPAD8
, ui::EF_NUMPAD_KEY
}},
504 // XK_KP_9 (= NumPad 9 with Num Lock), Num Lock modifier.
505 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
506 {ui::VKEY_NUMPAD9
, ui::EF_NUMPAD_KEY
},
507 {ui::VKEY_NUMPAD9
, ui::EF_NUMPAD_KEY
}},
510 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
512 CheckKeyTestCase(&rewriter
, tests
[i
]);
516 TEST_F(EventRewriterTest
, TestRewriteNumPadKeys
) {
517 TestRewriteNumPadKeys();
520 TEST_F(EventRewriterTest
, TestRewriteNumPadKeysWithDiamondKeyFlag
) {
521 // Make sure the num lock works correctly even when Diamond key exists.
522 const base::CommandLine
original_cl(*base::CommandLine::ForCurrentProcess());
523 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
524 chromeos::switches::kHasChromeOSDiamondKey
, "");
526 TestRewriteNumPadKeys();
527 *base::CommandLine::ForCurrentProcess() = original_cl
;
530 // Tests if the rewriter can handle a Command + Num Pad event.
531 void EventRewriterTest::TestRewriteNumPadKeysOnAppleKeyboard() {
532 TestingPrefServiceSyncable prefs
;
533 EventRewriter
rewriter(NULL
);
534 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "Apple Keyboard");
535 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
536 rewriter
.set_pref_service_for_testing(&prefs
);
538 KeyTestCase tests
[] = {
539 // XK_KP_End (= NumPad 1 without Num Lock), Win modifier.
540 // The result should be "Num Pad 1 with Control + Num Lock modifiers".
541 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
542 {ui::VKEY_END
, ui::EF_COMMAND_DOWN
| ui::EF_NUMPAD_KEY
},
543 {ui::VKEY_NUMPAD1
, ui::EF_CONTROL_DOWN
| ui::EF_NUMPAD_KEY
}},
545 // XK_KP_1 (= NumPad 1 with Num Lock), Win modifier.
546 // The result should also be "Num Pad 1 with Control + Num Lock
548 {KeyTestCase::TEST_ALL
|KeyTestCase::NUMPAD
, ui::ET_KEY_PRESSED
,
549 {ui::VKEY_NUMPAD1
, ui::EF_COMMAND_DOWN
| ui::EF_NUMPAD_KEY
},
550 {ui::VKEY_NUMPAD1
, ui::EF_CONTROL_DOWN
| ui::EF_NUMPAD_KEY
}},
553 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
555 CheckKeyTestCase(&rewriter
, tests
[i
]);
559 TEST_F(EventRewriterTest
, TestRewriteNumPadKeysOnAppleKeyboard
) {
560 TestRewriteNumPadKeysOnAppleKeyboard();
563 TEST_F(EventRewriterTest
,
564 TestRewriteNumPadKeysOnAppleKeyboardWithDiamondKeyFlag
) {
565 // Makes sure the num lock works correctly even when Diamond key exists.
566 const base::CommandLine
original_cl(*base::CommandLine::ForCurrentProcess());
567 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
568 chromeos::switches::kHasChromeOSDiamondKey
, "");
570 TestRewriteNumPadKeysOnAppleKeyboard();
571 *base::CommandLine::ForCurrentProcess() = original_cl
;
574 TEST_F(EventRewriterTest
, TestRewriteModifiersNoRemap
) {
575 TestingPrefServiceSyncable prefs
;
576 EventRewriter
rewriter(NULL
);
577 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
578 rewriter
.set_pref_service_for_testing(&prefs
);
580 KeyTestCase tests
[] = {
581 // Press Search. Confirm the event is not rewritten.
582 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
583 {ui::VKEY_LWIN
, ui::EF_NONE
},
584 {ui::VKEY_LWIN
, ui::EF_COMMAND_DOWN
}},
586 // Press left Control. Confirm the event is not rewritten.
587 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
588 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
},
589 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
}},
591 // Press right Control. Confirm the event is not rewritten.
592 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
593 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
},
594 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
}},
596 // Press left Alt. Confirm the event is not rewritten.
597 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
598 {ui::VKEY_MENU
, ui::EF_ALT_DOWN
},
599 {ui::VKEY_MENU
, ui::EF_ALT_DOWN
}},
601 // Press right Alt. Confirm the event is not rewritten.
602 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
603 {ui::VKEY_MENU
, ui::EF_ALT_DOWN
},
604 {ui::VKEY_MENU
, ui::EF_ALT_DOWN
}},
606 // Test KeyRelease event, just in case.
607 // Release Search. Confirm the release event is not rewritten.
608 {KeyTestCase::TEST_ALL
, ui::ET_KEY_RELEASED
,
609 {ui::VKEY_LWIN
, ui::EF_NONE
},
610 {ui::VKEY_LWIN
, ui::EF_NONE
}},
613 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
615 CheckKeyTestCase(&rewriter
, tests
[i
]);
619 TEST_F(EventRewriterTest
, TestRewriteModifiersNoRemapMultipleKeys
) {
620 TestingPrefServiceSyncable prefs
;
621 EventRewriter
rewriter(NULL
);
622 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
623 rewriter
.set_pref_service_for_testing(&prefs
);
625 KeyTestCase tests
[] = {
626 // Press Alt with Shift. Confirm the event is not rewritten.
627 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
628 {ui::VKEY_MENU
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
},
629 {ui::VKEY_MENU
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
}},
631 // Press Search with Caps Lock mask. Confirm the event is not rewritten.
632 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
633 {ui::VKEY_LWIN
, ui::EF_CAPS_LOCK_DOWN
| ui::EF_COMMAND_DOWN
},
634 {ui::VKEY_LWIN
, ui::EF_CAPS_LOCK_DOWN
| ui::EF_COMMAND_DOWN
}},
636 // Release Search with Caps Lock mask. Confirm the event is not rewritten.
637 {KeyTestCase::TEST_ALL
, ui::ET_KEY_RELEASED
,
638 {ui::VKEY_LWIN
, ui::EF_CAPS_LOCK_DOWN
},
639 {ui::VKEY_LWIN
, ui::EF_CAPS_LOCK_DOWN
}},
641 // Press Shift+Ctrl+Alt+Search+A. Confirm the event is not rewritten.
642 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
643 {ui::VKEY_B
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
644 ui::EF_COMMAND_DOWN
},
645 {ui::VKEY_B
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
646 ui::EF_COMMAND_DOWN
}},
649 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
651 CheckKeyTestCase(&rewriter
, tests
[i
]);
655 TEST_F(EventRewriterTest
, TestRewriteModifiersDisableSome
) {
656 // Disable Search and Control keys.
657 TestingPrefServiceSyncable prefs
;
658 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
659 IntegerPrefMember search
;
660 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
661 search
.SetValue(chromeos::input_method::kVoidKey
);
662 IntegerPrefMember control
;
663 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
664 control
.SetValue(chromeos::input_method::kVoidKey
);
666 EventRewriter
rewriter(NULL
);
667 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
668 rewriter
.set_pref_service_for_testing(&prefs
);
670 KeyTestCase disabled_modifier_tests
[] = {
671 // Press Alt with Shift. This key press shouldn't be affected by the
672 // pref. Confirm the event is not rewritten.
673 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
674 {ui::VKEY_MENU
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
},
675 {ui::VKEY_MENU
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
}},
677 // Press Search. Confirm the event is now VKEY_UNKNOWN.
678 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
679 {ui::VKEY_LWIN
, ui::EF_NONE
},
680 {ui::VKEY_UNKNOWN
, ui::EF_NONE
}},
682 // Press Control. Confirm the event is now VKEY_UNKNOWN.
683 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
684 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
},
685 {ui::VKEY_UNKNOWN
, ui::EF_NONE
}},
687 // Press Control+Search. Confirm the event is now VKEY_UNKNOWN
688 // without any modifiers.
689 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
690 {ui::VKEY_LWIN
, ui::EF_CONTROL_DOWN
},
691 {ui::VKEY_UNKNOWN
, ui::EF_NONE
}},
693 // Press Control+Search+a. Confirm the event is now VKEY_A without any
695 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
696 {ui::VKEY_A
, ui::EF_CONTROL_DOWN
},
697 {ui::VKEY_A
, ui::EF_NONE
}},
699 // Press Control+Search+Alt+a. Confirm the event is now VKEY_A only with
701 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
702 {ui::VKEY_A
, ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
},
703 {ui::VKEY_A
, ui::EF_ALT_DOWN
}},
706 for (size_t i
= 0; i
< arraysize(disabled_modifier_tests
); ++i
) {
708 CheckKeyTestCase(&rewriter
, disabled_modifier_tests
[i
]);
711 // Remap Alt to Control.
712 IntegerPrefMember alt
;
713 alt
.Init(prefs::kLanguageRemapAltKeyTo
, &prefs
);
714 alt
.SetValue(chromeos::input_method::kControlKey
);
716 KeyTestCase tests
[] = {
717 // Press left Alt. Confirm the event is now VKEY_CONTROL
718 // even though the Control key itself is disabled.
719 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
720 {ui::VKEY_MENU
, ui::EF_ALT_DOWN
},
721 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
}},
723 // Press Alt+a. Confirm the event is now Control+a even though the Control
724 // key itself is disabled.
725 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
726 {ui::VKEY_A
, ui::EF_ALT_DOWN
},
727 {ui::VKEY_A
, ui::EF_CONTROL_DOWN
}},
730 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
732 CheckKeyTestCase(&rewriter
, tests
[i
]);
736 TEST_F(EventRewriterTest
, TestRewriteModifiersRemapToControl
) {
737 // Remap Search to Control.
738 TestingPrefServiceSyncable prefs
;
739 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
740 IntegerPrefMember search
;
741 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
742 search
.SetValue(chromeos::input_method::kControlKey
);
744 EventRewriter
rewriter(NULL
);
745 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
746 rewriter
.set_pref_service_for_testing(&prefs
);
748 KeyTestCase s_tests
[] = {
749 // Press Search. Confirm the event is now VKEY_CONTROL.
750 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
751 {ui::VKEY_LWIN
, ui::EF_COMMAND_DOWN
},
752 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
}},
755 for (size_t i
= 0; i
< arraysize(s_tests
); ++i
) {
757 CheckKeyTestCase(&rewriter
, s_tests
[i
]);
760 // Remap Alt to Control too.
761 IntegerPrefMember alt
;
762 alt
.Init(prefs::kLanguageRemapAltKeyTo
, &prefs
);
763 alt
.SetValue(chromeos::input_method::kControlKey
);
765 KeyTestCase sa_tests
[] = {
766 // Press Alt. Confirm the event is now VKEY_CONTROL.
767 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
768 {ui::VKEY_MENU
, ui::EF_ALT_DOWN
},
769 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
}},
771 // Press Alt+Search. Confirm the event is now VKEY_CONTROL.
772 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
773 {ui::VKEY_LWIN
, ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
},
774 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
}},
776 // Press Control+Alt+Search. Confirm the event is now VKEY_CONTROL.
777 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
779 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
},
780 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
}},
782 // Press Shift+Control+Alt+Search. Confirm the event is now Control with
783 // Shift and Control modifiers.
784 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
785 {ui::VKEY_LWIN
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
|
786 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
},
787 {ui::VKEY_CONTROL
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
}},
789 // Press Shift+Control+Alt+Search+B. Confirm the event is now B with Shift
790 // and Control modifiers.
791 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
792 {ui::VKEY_B
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
793 ui::EF_COMMAND_DOWN
},
794 {ui::VKEY_B
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
}},
797 for (size_t i
= 0; i
< arraysize(sa_tests
); ++i
) {
799 CheckKeyTestCase(&rewriter
, sa_tests
[i
]);
803 TEST_F(EventRewriterTest
, TestRewriteModifiersRemapToEscape
) {
804 // Remap Search to ESC.
805 TestingPrefServiceSyncable prefs
;
806 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
807 IntegerPrefMember search
;
808 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
809 search
.SetValue(chromeos::input_method::kEscapeKey
);
811 EventRewriter
rewriter(NULL
);
812 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
813 rewriter
.set_pref_service_for_testing(&prefs
);
815 KeyTestCase tests
[] = {// Press Search. Confirm the event is now VKEY_ESCAPE.
816 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
817 {ui::VKEY_LWIN
, ui::EF_COMMAND_DOWN
},
818 {ui::VKEY_ESCAPE
, ui::EF_NONE
}},
821 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
823 CheckKeyTestCase(&rewriter
, tests
[i
]);
827 TEST_F(EventRewriterTest
, TestRewriteModifiersRemapMany
) {
828 // Remap Search to Alt.
829 TestingPrefServiceSyncable prefs
;
830 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
831 IntegerPrefMember search
;
832 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
833 search
.SetValue(chromeos::input_method::kAltKey
);
835 EventRewriter
rewriter(NULL
);
836 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
837 rewriter
.set_pref_service_for_testing(&prefs
);
839 KeyTestCase s2a_tests
[] = {
840 // Press Search. Confirm the event is now VKEY_MENU.
841 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
842 {ui::VKEY_LWIN
, ui::EF_COMMAND_DOWN
},
843 {ui::VKEY_MENU
, ui::EF_ALT_DOWN
}},
846 for (size_t i
= 0; i
< arraysize(s2a_tests
); ++i
) {
848 CheckKeyTestCase(&rewriter
, s2a_tests
[i
]);
851 // Remap Alt to Control.
852 IntegerPrefMember alt
;
853 alt
.Init(prefs::kLanguageRemapAltKeyTo
, &prefs
);
854 alt
.SetValue(chromeos::input_method::kControlKey
);
856 KeyTestCase a2c_tests
[] = {
857 // Press left Alt. Confirm the event is now VKEY_CONTROL.
858 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
859 {ui::VKEY_MENU
, ui::EF_ALT_DOWN
},
860 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
}},
861 // Press Shift+comma. Verify that only the flags are changed.
862 // The X11 portion of the test addresses crbug.com/390263 by verifying
863 // that the X keycode remains that for ',<' and not for 105-key '<>'.
864 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
865 {ui::VKEY_OEM_COMMA
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
},
866 {ui::VKEY_OEM_COMMA
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
}},
867 // Press Shift+9. Verify that only the flags are changed.
868 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
869 {ui::VKEY_9
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
},
870 {ui::VKEY_9
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
}},
873 for (size_t i
= 0; i
< arraysize(a2c_tests
); ++i
) {
875 CheckKeyTestCase(&rewriter
, a2c_tests
[i
]);
878 // Remap Control to Search.
879 IntegerPrefMember control
;
880 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
881 control
.SetValue(chromeos::input_method::kSearchKey
);
883 KeyTestCase c2s_tests
[] = {
884 // Press left Control. Confirm the event is now VKEY_LWIN.
885 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
886 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
},
887 {ui::VKEY_LWIN
, ui::EF_COMMAND_DOWN
}},
889 // Then, press all of the three, Control+Alt+Search.
890 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
892 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
},
894 ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
}},
896 // Press Shift+Control+Alt+Search.
897 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
898 {ui::VKEY_LWIN
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
|
899 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
},
900 {ui::VKEY_MENU
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
|
901 ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
}},
903 // Press Shift+Control+Alt+Search+B
904 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
905 {ui::VKEY_B
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
906 ui::EF_COMMAND_DOWN
},
907 {ui::VKEY_B
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
|
908 ui::EF_COMMAND_DOWN
}},
911 for (size_t i
= 0; i
< arraysize(c2s_tests
); ++i
) {
913 CheckKeyTestCase(&rewriter
, c2s_tests
[i
]);
917 TEST_F(EventRewriterTest
, TestRewriteModifiersRemapToCapsLock
) {
918 // Remap Search to Caps Lock.
919 TestingPrefServiceSyncable prefs
;
920 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
921 IntegerPrefMember search
;
922 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
923 search
.SetValue(chromeos::input_method::kCapsLockKey
);
925 chromeos::input_method::FakeImeKeyboard ime_keyboard
;
926 EventRewriter
rewriter(NULL
);
927 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
928 rewriter
.set_pref_service_for_testing(&prefs
);
929 rewriter
.set_ime_keyboard_for_testing(&ime_keyboard
);
930 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
934 GetExpectedResultAsString(ui::VKEY_CAPITAL
,
935 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
937 GetRewrittenEventAsString(
938 &rewriter
, ui::VKEY_LWIN
, ui::EF_COMMAND_DOWN
, ui::ET_KEY_PRESSED
));
939 // Confirm that the Caps Lock status is changed.
940 EXPECT_TRUE(ime_keyboard
.caps_lock_is_enabled_
);
943 EXPECT_EQ(GetExpectedResultAsString(
944 ui::VKEY_CAPITAL
, ui::EF_NONE
, ui::ET_KEY_RELEASED
),
945 GetRewrittenEventAsString(
946 &rewriter
, ui::VKEY_LWIN
, ui::EF_NONE
, ui::ET_KEY_RELEASED
));
947 // Confirm that the Caps Lock status is not changed.
948 EXPECT_TRUE(ime_keyboard
.caps_lock_is_enabled_
);
952 GetExpectedResultAsString(ui::VKEY_CAPITAL
,
953 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
955 GetRewrittenEventAsString(&rewriter
,
957 ui::EF_COMMAND_DOWN
| ui::EF_CAPS_LOCK_DOWN
,
958 ui::ET_KEY_PRESSED
));
959 // Confirm that the Caps Lock status is changed.
960 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
963 EXPECT_EQ(GetExpectedResultAsString(
964 ui::VKEY_CAPITAL
, ui::EF_NONE
, ui::ET_KEY_RELEASED
),
965 GetRewrittenEventAsString(
966 &rewriter
, ui::VKEY_LWIN
, ui::EF_NONE
, ui::ET_KEY_RELEASED
));
967 // Confirm that the Caps Lock status is not changed.
968 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
970 // Press Caps Lock (on an external keyboard).
971 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL
,
972 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
974 GetRewrittenEventAsString(&rewriter
,
976 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
977 ui::ET_KEY_PRESSED
));
979 // Confirm that calling RewriteForTesting() does not change the state of
980 // |ime_keyboard|. In this case, X Window system itself should change the
981 // Caps Lock state, not ash::EventRewriter.
982 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
984 // Release Caps Lock (on an external keyboard).
985 EXPECT_EQ(GetExpectedResultAsString(
986 ui::VKEY_CAPITAL
, ui::EF_NONE
, ui::ET_KEY_RELEASED
),
987 GetRewrittenEventAsString(
988 &rewriter
, ui::VKEY_CAPITAL
, ui::EF_NONE
, ui::ET_KEY_RELEASED
));
989 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
992 TEST_F(EventRewriterTest
, TestRewriteCapsLock
) {
993 TestingPrefServiceSyncable prefs
;
994 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
996 chromeos::input_method::FakeImeKeyboard ime_keyboard
;
997 EventRewriter
rewriter(NULL
);
998 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
999 rewriter
.set_pref_service_for_testing(&prefs
);
1000 rewriter
.set_ime_keyboard_for_testing(&ime_keyboard
);
1001 EXPECT_FALSE(ime_keyboard
.caps_lock_is_enabled_
);
1003 // On Chrome OS, CapsLock is mapped to F16 with Mod3Mask.
1004 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL
,
1005 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
1006 ui::ET_KEY_PRESSED
),
1007 GetRewrittenEventAsString(
1008 &rewriter
, ui::VKEY_F16
, ui::EF_MOD3_DOWN
, ui::ET_KEY_PRESSED
));
1009 EXPECT_TRUE(ime_keyboard
.caps_lock_is_enabled_
);
1012 TEST_F(EventRewriterTest
, TestRewriteDiamondKey
) {
1013 TestingPrefServiceSyncable prefs
;
1014 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1016 chromeos::input_method::FakeImeKeyboard ime_keyboard
;
1017 EventRewriter
rewriter(NULL
);
1018 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1019 rewriter
.set_pref_service_for_testing(&prefs
);
1020 rewriter
.set_ime_keyboard_for_testing(&ime_keyboard
);
1022 KeyTestCase tests
[] = {
1023 // F15 should work as Ctrl when --has-chromeos-diamond-key is not
1025 {KeyTestCase::TEST_VKEY
,
1027 {ui::VKEY_F15
, ui::EF_NONE
},
1028 {ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
}},
1030 {KeyTestCase::TEST_VKEY
,
1031 ui::ET_KEY_RELEASED
,
1032 {ui::VKEY_F15
, ui::EF_NONE
},
1033 {ui::VKEY_CONTROL
, ui::EF_NONE
}},
1035 // However, Mod2Mask should not be rewritten to CtrlMask when
1036 // --has-chromeos-diamond-key is not specified.
1037 {KeyTestCase::TEST_VKEY
,
1039 {ui::VKEY_A
, ui::EF_NONE
},
1040 {ui::VKEY_A
, ui::EF_NONE
}},
1043 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
1045 CheckKeyTestCase(&rewriter
, tests
[i
]);
1049 TEST_F(EventRewriterTest
, TestRewriteDiamondKeyWithFlag
) {
1050 const base::CommandLine
original_cl(*base::CommandLine::ForCurrentProcess());
1051 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1052 chromeos::switches::kHasChromeOSDiamondKey
, "");
1054 TestingPrefServiceSyncable prefs
;
1055 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1057 chromeos::input_method::FakeImeKeyboard ime_keyboard
;
1058 EventRewriter
rewriter(NULL
);
1059 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1060 rewriter
.set_pref_service_for_testing(&prefs
);
1061 rewriter
.set_ime_keyboard_for_testing(&ime_keyboard
);
1063 // By default, F15 should work as Control.
1064 EXPECT_EQ(GetExpectedResultAsString(
1065 ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
, ui::ET_KEY_PRESSED
),
1066 GetRewrittenEventAsString(
1067 &rewriter
, ui::VKEY_F15
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1068 // Check that Control is applied to a subsequent key press.
1069 EXPECT_EQ(GetExpectedResultAsString(
1070 ui::VKEY_A
, ui::EF_CONTROL_DOWN
, ui::ET_KEY_PRESSED
),
1071 GetRewrittenEventAsString(
1072 &rewriter
, ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1074 EXPECT_EQ(GetExpectedResultAsString(
1075 ui::VKEY_CONTROL
, ui::EF_NONE
, ui::ET_KEY_RELEASED
),
1076 GetRewrittenEventAsString(
1077 &rewriter
, ui::VKEY_F15
, ui::EF_NONE
, ui::ET_KEY_RELEASED
));
1078 // Check that Control is no longer applied to a subsequent key press.
1080 GetExpectedResultAsString(ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
),
1081 GetRewrittenEventAsString(
1082 &rewriter
, ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1084 IntegerPrefMember diamond
;
1085 diamond
.Init(prefs::kLanguageRemapDiamondKeyTo
, &prefs
);
1086 diamond
.SetValue(chromeos::input_method::kVoidKey
);
1088 EXPECT_EQ(GetExpectedResultAsString(
1089 ui::VKEY_UNKNOWN
, ui::EF_NONE
, ui::ET_KEY_PRESSED
),
1090 GetRewrittenEventAsString(
1091 &rewriter
, ui::VKEY_F15
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1092 // Check that no modifier is applied to another key.
1094 GetExpectedResultAsString(ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
),
1095 GetRewrittenEventAsString(
1096 &rewriter
, ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1098 diamond
.SetValue(chromeos::input_method::kControlKey
);
1100 EXPECT_EQ(GetExpectedResultAsString(
1101 ui::VKEY_CONTROL
, ui::EF_CONTROL_DOWN
, ui::ET_KEY_PRESSED
),
1102 GetRewrittenEventAsString(
1103 &rewriter
, ui::VKEY_F15
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1104 // Check that Control is applied to a subsequent key press.
1105 EXPECT_EQ(GetExpectedResultAsString(
1106 ui::VKEY_A
, ui::EF_CONTROL_DOWN
, ui::ET_KEY_PRESSED
),
1107 GetRewrittenEventAsString(
1108 &rewriter
, ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1110 EXPECT_EQ(GetExpectedResultAsString(
1111 ui::VKEY_CONTROL
, ui::EF_NONE
, ui::ET_KEY_RELEASED
),
1112 GetRewrittenEventAsString(
1113 &rewriter
, ui::VKEY_F15
, ui::EF_NONE
, ui::ET_KEY_RELEASED
));
1114 // Check that Control is no longer applied to a subsequent key press.
1116 GetExpectedResultAsString(ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
),
1117 GetRewrittenEventAsString(
1118 &rewriter
, ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1120 diamond
.SetValue(chromeos::input_method::kAltKey
);
1122 EXPECT_EQ(GetExpectedResultAsString(
1123 ui::VKEY_MENU
, ui::EF_ALT_DOWN
, ui::ET_KEY_PRESSED
),
1124 GetRewrittenEventAsString(
1125 &rewriter
, ui::VKEY_F15
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1126 // Check that Alt is applied to a subsequent key press.
1127 EXPECT_EQ(GetExpectedResultAsString(
1128 ui::VKEY_A
, ui::EF_ALT_DOWN
, ui::ET_KEY_PRESSED
),
1129 GetRewrittenEventAsString(
1130 &rewriter
, ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1132 EXPECT_EQ(GetExpectedResultAsString(
1133 ui::VKEY_MENU
, ui::EF_NONE
, ui::ET_KEY_RELEASED
),
1134 GetRewrittenEventAsString(
1135 &rewriter
, ui::VKEY_F15
, ui::EF_NONE
, ui::ET_KEY_RELEASED
));
1136 // Check that Alt is no longer applied to a subsequent key press.
1138 GetExpectedResultAsString(ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
),
1139 GetRewrittenEventAsString(
1140 &rewriter
, ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1142 diamond
.SetValue(chromeos::input_method::kCapsLockKey
);
1144 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL
,
1145 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
1146 ui::ET_KEY_PRESSED
),
1147 GetRewrittenEventAsString(
1148 &rewriter
, ui::VKEY_F15
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1149 // Check that Caps is applied to a subsequent key press.
1150 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A
,
1151 ui::EF_CAPS_LOCK_DOWN
| ui::EF_MOD3_DOWN
,
1152 ui::ET_KEY_PRESSED
),
1153 GetRewrittenEventAsString(
1154 &rewriter
, ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1156 EXPECT_EQ(GetExpectedResultAsString(
1157 ui::VKEY_CAPITAL
, ui::EF_NONE
, ui::ET_KEY_RELEASED
),
1158 GetRewrittenEventAsString(
1159 &rewriter
, ui::VKEY_F15
, ui::EF_NONE
, ui::ET_KEY_RELEASED
));
1160 // Check that Control is no longer applied to a subsequent key press.
1162 GetExpectedResultAsString(ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
),
1163 GetRewrittenEventAsString(
1164 &rewriter
, ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1166 *base::CommandLine::ForCurrentProcess() = original_cl
;
1169 TEST_F(EventRewriterTest
, TestRewriteCapsLockToControl
) {
1170 // Remap CapsLock to Control.
1171 TestingPrefServiceSyncable prefs
;
1172 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1173 IntegerPrefMember control
;
1174 control
.Init(prefs::kLanguageRemapCapsLockKeyTo
, &prefs
);
1175 control
.SetValue(chromeos::input_method::kControlKey
);
1177 EventRewriter
rewriter(NULL
);
1178 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1179 rewriter
.set_pref_service_for_testing(&prefs
);
1181 KeyTestCase tests
[] = {
1182 // Press CapsLock+a. Confirm that Mod3Mask is rewritten to ControlMask.
1183 // On Chrome OS, CapsLock works as a Mod3 modifier.
1184 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1185 {ui::VKEY_A
, ui::EF_MOD3_DOWN
},
1186 {ui::VKEY_A
, ui::EF_CONTROL_DOWN
}},
1188 // Press Control+CapsLock+a. Confirm that Mod3Mask is rewritten to
1190 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1191 {ui::VKEY_A
, ui::EF_CONTROL_DOWN
| ui::EF_MOD3_DOWN
},
1192 {ui::VKEY_A
, ui::EF_CONTROL_DOWN
}},
1194 // Press Alt+CapsLock+a. Confirm that Mod3Mask is rewritten to
1196 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1197 {ui::VKEY_A
, ui::EF_ALT_DOWN
| ui::EF_MOD3_DOWN
},
1198 {ui::VKEY_A
, ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
}},
1201 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
1203 CheckKeyTestCase(&rewriter
, tests
[i
]);
1207 TEST_F(EventRewriterTest
, TestRewriteCapsLockMod3InUse
) {
1208 // Remap CapsLock to Control.
1209 TestingPrefServiceSyncable prefs
;
1210 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1211 IntegerPrefMember control
;
1212 control
.Init(prefs::kLanguageRemapCapsLockKeyTo
, &prefs
);
1213 control
.SetValue(chromeos::input_method::kControlKey
);
1215 EventRewriter
rewriter(NULL
);
1216 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1217 rewriter
.set_pref_service_for_testing(&prefs
);
1218 input_method_manager_mock_
->set_mod3_used(true);
1220 // Press CapsLock+a. Confirm that Mod3Mask is NOT rewritten to ControlMask
1221 // when Mod3Mask is already in use by the current XKB layout.
1223 GetExpectedResultAsString(ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
),
1224 GetRewrittenEventAsString(
1225 &rewriter
, ui::VKEY_A
, ui::EF_NONE
, ui::ET_KEY_PRESSED
));
1227 input_method_manager_mock_
->set_mod3_used(false);
1230 TEST_F(EventRewriterTest
, TestRewriteExtendedKeys
) {
1231 TestingPrefServiceSyncable prefs
;
1232 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1233 EventRewriter
rewriter(NULL
);
1234 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1235 rewriter
.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId
);
1236 rewriter
.set_pref_service_for_testing(&prefs
);
1238 KeyTestCase tests
[] = {
1239 // Alt+Backspace -> Delete
1240 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1241 {ui::VKEY_BACK
, ui::EF_ALT_DOWN
},
1242 {ui::VKEY_DELETE
, ui::EF_NONE
}},
1243 // Control+Alt+Backspace -> Control+Delete
1244 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1245 {ui::VKEY_BACK
, ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
},
1246 {ui::VKEY_DELETE
, ui::EF_CONTROL_DOWN
}},
1247 // Search+Alt+Backspace -> Alt+Backspace
1248 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1249 {ui::VKEY_BACK
, ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
},
1250 {ui::VKEY_BACK
, ui::EF_ALT_DOWN
}},
1251 // Search+Control+Alt+Backspace -> Control+Alt+Backspace
1252 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1254 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
},
1255 {ui::VKEY_BACK
, ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
}},
1257 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1258 {ui::VKEY_UP
, ui::EF_ALT_DOWN
},
1259 {ui::VKEY_PRIOR
, ui::EF_NONE
}},
1261 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1262 {ui::VKEY_DOWN
, ui::EF_ALT_DOWN
},
1263 {ui::VKEY_NEXT
, ui::EF_NONE
}},
1264 // Ctrl+Alt+Up -> Home
1265 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1266 {ui::VKEY_UP
, ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
},
1267 {ui::VKEY_HOME
, ui::EF_NONE
}},
1268 // Ctrl+Alt+Down -> End
1269 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1270 {ui::VKEY_DOWN
, ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
},
1271 {ui::VKEY_END
, ui::EF_NONE
}},
1273 // Search+Alt+Up -> Alt+Up
1274 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1275 {ui::VKEY_UP
, ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
},
1276 {ui::VKEY_UP
, ui::EF_ALT_DOWN
}},
1277 // Search+Alt+Down -> Alt+Down
1278 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1279 {ui::VKEY_DOWN
, ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
},
1280 {ui::VKEY_DOWN
, ui::EF_ALT_DOWN
}},
1281 // Search+Ctrl+Alt+Up -> Search+Ctrl+Alt+Up
1282 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1284 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
},
1285 {ui::VKEY_UP
, ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
}},
1286 // Search+Ctrl+Alt+Down -> Ctrl+Alt+Down
1287 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1289 ui::EF_COMMAND_DOWN
| ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
},
1290 {ui::VKEY_DOWN
, ui::EF_ALT_DOWN
| ui::EF_CONTROL_DOWN
}},
1293 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1294 {ui::VKEY_OEM_PERIOD
, ui::EF_NONE
},
1295 {ui::VKEY_OEM_PERIOD
, ui::EF_NONE
}},
1297 // Search+Backspace -> Delete
1298 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1299 {ui::VKEY_BACK
, ui::EF_COMMAND_DOWN
},
1300 {ui::VKEY_DELETE
, ui::EF_NONE
}},
1301 // Search+Up -> Prior
1302 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1303 {ui::VKEY_UP
, ui::EF_COMMAND_DOWN
},
1304 {ui::VKEY_PRIOR
, ui::EF_NONE
}},
1305 // Search+Down -> Next
1306 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1307 {ui::VKEY_DOWN
, ui::EF_COMMAND_DOWN
},
1308 {ui::VKEY_NEXT
, ui::EF_NONE
}},
1309 // Search+Left -> Home
1310 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1311 {ui::VKEY_LEFT
, ui::EF_COMMAND_DOWN
},
1312 {ui::VKEY_HOME
, ui::EF_NONE
}},
1313 // Control+Search+Left -> Home
1314 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1315 {ui::VKEY_LEFT
, ui::EF_COMMAND_DOWN
| ui::EF_CONTROL_DOWN
},
1316 {ui::VKEY_HOME
, ui::EF_CONTROL_DOWN
}},
1317 // Search+Right -> End
1318 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1319 {ui::VKEY_RIGHT
, ui::EF_COMMAND_DOWN
},
1320 {ui::VKEY_END
, ui::EF_NONE
}},
1321 // Control+Search+Right -> End
1322 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1323 {ui::VKEY_RIGHT
, ui::EF_COMMAND_DOWN
| ui::EF_CONTROL_DOWN
},
1324 {ui::VKEY_END
, ui::EF_CONTROL_DOWN
}},
1325 // Search+Period -> Insert
1326 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1327 {ui::VKEY_OEM_PERIOD
, ui::EF_COMMAND_DOWN
},
1328 {ui::VKEY_INSERT
, ui::EF_NONE
}},
1329 // Control+Search+Period -> Control+Insert
1330 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1331 {ui::VKEY_OEM_PERIOD
, ui::EF_COMMAND_DOWN
| ui::EF_CONTROL_DOWN
},
1332 {ui::VKEY_INSERT
, ui::EF_CONTROL_DOWN
}}};
1334 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
1336 CheckKeyTestCase(&rewriter
, tests
[i
]);
1340 TEST_F(EventRewriterTest
, TestRewriteFunctionKeys
) {
1341 TestingPrefServiceSyncable prefs
;
1342 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1343 EventRewriter
rewriter(NULL
);
1344 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1345 rewriter
.set_pref_service_for_testing(&prefs
);
1347 FunctionKeyTestCase tests
[] = {
1349 {ui::ET_KEY_PRESSED
,
1350 {ui::VKEY_F1
, ui::EF_NONE
},
1351 {ui::VKEY_BROWSER_BACK
, ui::EF_NONE
},
1352 {ui::VKEY_BROWSER_BACK
, ui::EF_FUNCTION_KEY
}},
1353 {ui::ET_KEY_PRESSED
,
1354 {ui::VKEY_F1
, ui::EF_CONTROL_DOWN
},
1355 {ui::VKEY_BROWSER_BACK
, ui::EF_CONTROL_DOWN
},
1356 {ui::VKEY_BROWSER_BACK
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1357 {ui::ET_KEY_PRESSED
,
1358 {ui::VKEY_F1
, ui::EF_ALT_DOWN
},
1359 {ui::VKEY_BROWSER_BACK
, ui::EF_ALT_DOWN
},
1360 {ui::VKEY_BROWSER_BACK
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1362 {ui::ET_KEY_PRESSED
,
1363 {ui::VKEY_F2
, ui::EF_NONE
},
1364 {ui::VKEY_BROWSER_FORWARD
, ui::EF_NONE
},
1365 {ui::VKEY_BROWSER_FORWARD
, ui::EF_FUNCTION_KEY
}},
1366 {ui::ET_KEY_PRESSED
,
1367 {ui::VKEY_F2
, ui::EF_CONTROL_DOWN
},
1368 {ui::VKEY_BROWSER_FORWARD
, ui::EF_CONTROL_DOWN
},
1369 {ui::VKEY_BROWSER_FORWARD
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1370 {ui::ET_KEY_PRESSED
,
1371 {ui::VKEY_F2
, ui::EF_ALT_DOWN
},
1372 {ui::VKEY_BROWSER_FORWARD
, ui::EF_ALT_DOWN
},
1373 {ui::VKEY_BROWSER_FORWARD
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1375 {ui::ET_KEY_PRESSED
,
1376 {ui::VKEY_F3
, ui::EF_NONE
},
1377 {ui::VKEY_BROWSER_REFRESH
, ui::EF_NONE
},
1378 {ui::VKEY_BROWSER_REFRESH
, ui::EF_FUNCTION_KEY
}},
1379 {ui::ET_KEY_PRESSED
,
1380 {ui::VKEY_F3
, ui::EF_CONTROL_DOWN
},
1381 {ui::VKEY_BROWSER_REFRESH
, ui::EF_CONTROL_DOWN
},
1382 {ui::VKEY_BROWSER_REFRESH
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1383 {ui::ET_KEY_PRESSED
,
1384 {ui::VKEY_F3
, ui::EF_ALT_DOWN
},
1385 {ui::VKEY_BROWSER_REFRESH
, ui::EF_ALT_DOWN
},
1386 {ui::VKEY_BROWSER_REFRESH
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1387 // F4 -> Launch App 2
1388 {ui::ET_KEY_PRESSED
,
1389 {ui::VKEY_F4
, ui::EF_NONE
},
1390 {ui::VKEY_MEDIA_LAUNCH_APP2
, ui::EF_NONE
},
1391 {ui::VKEY_MEDIA_LAUNCH_APP2
, ui::EF_FUNCTION_KEY
}},
1392 {ui::ET_KEY_PRESSED
,
1393 {ui::VKEY_F4
, ui::EF_CONTROL_DOWN
},
1394 {ui::VKEY_MEDIA_LAUNCH_APP2
, ui::EF_CONTROL_DOWN
},
1395 {ui::VKEY_MEDIA_LAUNCH_APP2
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1396 {ui::ET_KEY_PRESSED
,
1397 {ui::VKEY_F4
, ui::EF_ALT_DOWN
},
1398 {ui::VKEY_MEDIA_LAUNCH_APP2
, ui::EF_ALT_DOWN
},
1399 {ui::VKEY_MEDIA_LAUNCH_APP2
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1400 // F5 -> Launch App 1
1401 {ui::ET_KEY_PRESSED
,
1402 {ui::VKEY_F5
, ui::EF_NONE
},
1403 {ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_NONE
},
1404 {ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_FUNCTION_KEY
}},
1405 {ui::ET_KEY_PRESSED
,
1406 {ui::VKEY_F5
, ui::EF_CONTROL_DOWN
},
1407 {ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_CONTROL_DOWN
},
1408 {ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1409 {ui::ET_KEY_PRESSED
,
1410 {ui::VKEY_F5
, ui::EF_ALT_DOWN
},
1411 {ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_ALT_DOWN
},
1412 {ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1413 // F6 -> Brightness down
1414 {ui::ET_KEY_PRESSED
,
1415 {ui::VKEY_F6
, ui::EF_NONE
},
1416 {ui::VKEY_BRIGHTNESS_DOWN
, ui::EF_NONE
},
1417 {ui::VKEY_BRIGHTNESS_DOWN
, ui::EF_FUNCTION_KEY
}},
1418 {ui::ET_KEY_PRESSED
,
1419 {ui::VKEY_F6
, ui::EF_CONTROL_DOWN
},
1420 {ui::VKEY_BRIGHTNESS_DOWN
, ui::EF_CONTROL_DOWN
},
1421 {ui::VKEY_BRIGHTNESS_DOWN
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1422 {ui::ET_KEY_PRESSED
,
1423 {ui::VKEY_F6
, ui::EF_ALT_DOWN
},
1424 {ui::VKEY_BRIGHTNESS_DOWN
, ui::EF_ALT_DOWN
},
1425 {ui::VKEY_BRIGHTNESS_DOWN
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1426 // F7 -> Brightness up
1427 {ui::ET_KEY_PRESSED
,
1428 {ui::VKEY_F7
, ui::EF_NONE
},
1429 {ui::VKEY_BRIGHTNESS_UP
, ui::EF_NONE
},
1430 {ui::VKEY_BRIGHTNESS_UP
, ui::EF_FUNCTION_KEY
}},
1431 {ui::ET_KEY_PRESSED
,
1432 {ui::VKEY_F7
, ui::EF_CONTROL_DOWN
},
1433 {ui::VKEY_BRIGHTNESS_UP
, ui::EF_CONTROL_DOWN
},
1434 {ui::VKEY_BRIGHTNESS_UP
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1435 {ui::ET_KEY_PRESSED
,
1436 {ui::VKEY_F7
, ui::EF_ALT_DOWN
},
1437 {ui::VKEY_BRIGHTNESS_UP
, ui::EF_ALT_DOWN
},
1438 {ui::VKEY_BRIGHTNESS_UP
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1439 // F8 -> Volume Mute
1440 {ui::ET_KEY_PRESSED
,
1441 {ui::VKEY_F8
, ui::EF_NONE
},
1442 {ui::VKEY_VOLUME_MUTE
, ui::EF_NONE
},
1443 {ui::VKEY_VOLUME_MUTE
, ui::EF_FUNCTION_KEY
}},
1444 {ui::ET_KEY_PRESSED
,
1445 {ui::VKEY_F8
, ui::EF_CONTROL_DOWN
},
1446 {ui::VKEY_VOLUME_MUTE
, ui::EF_CONTROL_DOWN
},
1447 {ui::VKEY_VOLUME_MUTE
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1448 {ui::ET_KEY_PRESSED
,
1449 {ui::VKEY_F8
, ui::EF_ALT_DOWN
},
1450 {ui::VKEY_VOLUME_MUTE
, ui::EF_ALT_DOWN
},
1451 {ui::VKEY_VOLUME_MUTE
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1452 // F9 -> Volume Down
1453 {ui::ET_KEY_PRESSED
,
1454 {ui::VKEY_F9
, ui::EF_NONE
},
1455 {ui::VKEY_VOLUME_DOWN
, ui::EF_NONE
},
1456 {ui::VKEY_VOLUME_DOWN
, ui::EF_FUNCTION_KEY
}},
1457 {ui::ET_KEY_PRESSED
,
1458 {ui::VKEY_F9
, ui::EF_CONTROL_DOWN
},
1459 {ui::VKEY_VOLUME_DOWN
, ui::EF_CONTROL_DOWN
},
1460 {ui::VKEY_VOLUME_DOWN
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1461 {ui::ET_KEY_PRESSED
,
1462 {ui::VKEY_F9
, ui::EF_ALT_DOWN
},
1463 {ui::VKEY_VOLUME_DOWN
, ui::EF_ALT_DOWN
},
1464 {ui::VKEY_VOLUME_DOWN
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1466 {ui::ET_KEY_PRESSED
,
1467 {ui::VKEY_F10
, ui::EF_NONE
},
1468 {ui::VKEY_VOLUME_UP
, ui::EF_NONE
},
1469 {ui::VKEY_VOLUME_UP
, ui::EF_FUNCTION_KEY
}},
1470 {ui::ET_KEY_PRESSED
,
1471 {ui::VKEY_F10
, ui::EF_CONTROL_DOWN
},
1472 {ui::VKEY_VOLUME_UP
, ui::EF_CONTROL_DOWN
},
1473 {ui::VKEY_VOLUME_UP
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1474 {ui::ET_KEY_PRESSED
,
1475 {ui::VKEY_F10
, ui::EF_ALT_DOWN
},
1476 {ui::VKEY_VOLUME_UP
, ui::EF_ALT_DOWN
},
1477 {ui::VKEY_VOLUME_UP
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1479 {ui::ET_KEY_PRESSED
,
1480 {ui::VKEY_F11
, ui::EF_NONE
},
1481 {ui::VKEY_F11
, ui::EF_NONE
},
1482 {ui::VKEY_F11
, ui::EF_FUNCTION_KEY
}},
1483 {ui::ET_KEY_PRESSED
,
1484 {ui::VKEY_F11
, ui::EF_CONTROL_DOWN
},
1485 {ui::VKEY_F11
, ui::EF_CONTROL_DOWN
},
1486 {ui::VKEY_F11
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1487 {ui::ET_KEY_PRESSED
,
1488 {ui::VKEY_F11
, ui::EF_ALT_DOWN
},
1489 {ui::VKEY_F11
, ui::EF_ALT_DOWN
},
1490 {ui::VKEY_F11
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1492 {ui::ET_KEY_PRESSED
,
1493 {ui::VKEY_F12
, ui::EF_NONE
},
1494 {ui::VKEY_F12
, ui::EF_NONE
},
1495 {ui::VKEY_F12
, ui::EF_FUNCTION_KEY
}},
1496 {ui::ET_KEY_PRESSED
,
1497 {ui::VKEY_F12
, ui::EF_CONTROL_DOWN
},
1498 {ui::VKEY_F12
, ui::EF_CONTROL_DOWN
},
1499 {ui::VKEY_F12
, ui::EF_CONTROL_DOWN
| ui::EF_FUNCTION_KEY
}},
1500 {ui::ET_KEY_PRESSED
,
1501 {ui::VKEY_F12
, ui::EF_ALT_DOWN
},
1502 {ui::VKEY_F12
, ui::EF_ALT_DOWN
},
1503 {ui::VKEY_F12
, ui::EF_ALT_DOWN
| ui::EF_FUNCTION_KEY
}},
1505 // The number row should not be rewritten without Search key.
1506 {ui::ET_KEY_PRESSED
,
1507 {ui::VKEY_1
, ui::EF_NONE
},
1508 {ui::VKEY_1
, ui::EF_NONE
},
1509 {ui::VKEY_1
, ui::EF_NONE
}},
1510 {ui::ET_KEY_PRESSED
,
1511 {ui::VKEY_2
, ui::EF_NONE
},
1512 {ui::VKEY_2
, ui::EF_NONE
},
1513 {ui::VKEY_2
, ui::EF_NONE
}},
1514 {ui::ET_KEY_PRESSED
,
1515 {ui::VKEY_3
, ui::EF_NONE
},
1516 {ui::VKEY_3
, ui::EF_NONE
},
1517 {ui::VKEY_3
, ui::EF_NONE
}},
1518 {ui::ET_KEY_PRESSED
,
1519 {ui::VKEY_4
, ui::EF_NONE
},
1520 {ui::VKEY_4
, ui::EF_NONE
},
1521 {ui::VKEY_4
, ui::EF_NONE
}},
1522 {ui::ET_KEY_PRESSED
,
1523 {ui::VKEY_5
, ui::EF_NONE
},
1524 {ui::VKEY_5
, ui::EF_NONE
},
1525 {ui::VKEY_5
, ui::EF_NONE
}},
1526 {ui::ET_KEY_PRESSED
,
1527 {ui::VKEY_6
, ui::EF_NONE
},
1528 {ui::VKEY_6
, ui::EF_NONE
},
1529 {ui::VKEY_6
, ui::EF_NONE
}},
1530 {ui::ET_KEY_PRESSED
,
1531 {ui::VKEY_7
, ui::EF_NONE
},
1532 {ui::VKEY_7
, ui::EF_NONE
},
1533 {ui::VKEY_7
, ui::EF_NONE
}},
1534 {ui::ET_KEY_PRESSED
,
1535 {ui::VKEY_8
, ui::EF_NONE
},
1536 {ui::VKEY_8
, ui::EF_NONE
},
1537 {ui::VKEY_8
, ui::EF_NONE
}},
1538 {ui::ET_KEY_PRESSED
,
1539 {ui::VKEY_9
, ui::EF_NONE
},
1540 {ui::VKEY_9
, ui::EF_NONE
},
1541 {ui::VKEY_9
, ui::EF_NONE
}},
1542 {ui::ET_KEY_PRESSED
,
1543 {ui::VKEY_0
, ui::EF_NONE
},
1544 {ui::VKEY_0
, ui::EF_NONE
},
1545 {ui::VKEY_0
, ui::EF_NONE
}},
1546 {ui::ET_KEY_PRESSED
,
1547 {ui::VKEY_OEM_MINUS
, ui::EF_NONE
},
1548 {ui::VKEY_OEM_MINUS
, ui::EF_NONE
},
1549 {ui::VKEY_OEM_MINUS
, ui::EF_NONE
}},
1550 {ui::ET_KEY_PRESSED
,
1551 {ui::VKEY_OEM_PLUS
, ui::EF_NONE
},
1552 {ui::VKEY_OEM_PLUS
, ui::EF_NONE
},
1553 {ui::VKEY_OEM_PLUS
, ui::EF_NONE
}},
1555 // The number row should be rewritten as the F<number> row with Search
1557 {ui::ET_KEY_PRESSED
,
1558 {ui::VKEY_1
, ui::EF_COMMAND_DOWN
},
1559 {ui::VKEY_F1
, ui::EF_NONE
},
1560 {ui::VKEY_F1
, ui::EF_NONE
}},
1561 {ui::ET_KEY_PRESSED
,
1562 {ui::VKEY_2
, ui::EF_COMMAND_DOWN
},
1563 {ui::VKEY_F2
, ui::EF_NONE
},
1564 {ui::VKEY_F2
, ui::EF_NONE
}},
1565 {ui::ET_KEY_PRESSED
,
1566 {ui::VKEY_3
, ui::EF_COMMAND_DOWN
},
1567 {ui::VKEY_F3
, ui::EF_NONE
},
1568 {ui::VKEY_F3
, ui::EF_NONE
}},
1569 {ui::ET_KEY_PRESSED
,
1570 {ui::VKEY_4
, ui::EF_COMMAND_DOWN
},
1571 {ui::VKEY_F4
, ui::EF_NONE
},
1572 {ui::VKEY_F4
, ui::EF_NONE
}},
1573 {ui::ET_KEY_PRESSED
,
1574 {ui::VKEY_5
, ui::EF_COMMAND_DOWN
},
1575 {ui::VKEY_F5
, ui::EF_NONE
},
1576 {ui::VKEY_F5
, ui::EF_NONE
}},
1577 {ui::ET_KEY_PRESSED
,
1578 {ui::VKEY_6
, ui::EF_COMMAND_DOWN
},
1579 {ui::VKEY_F6
, ui::EF_NONE
},
1580 {ui::VKEY_F6
, ui::EF_NONE
}},
1581 {ui::ET_KEY_PRESSED
,
1582 {ui::VKEY_7
, ui::EF_COMMAND_DOWN
},
1583 {ui::VKEY_F7
, ui::EF_NONE
},
1584 {ui::VKEY_F7
, ui::EF_NONE
}},
1585 {ui::ET_KEY_PRESSED
,
1586 {ui::VKEY_8
, ui::EF_COMMAND_DOWN
},
1587 {ui::VKEY_F8
, ui::EF_NONE
},
1588 {ui::VKEY_F8
, ui::EF_NONE
}},
1589 {ui::ET_KEY_PRESSED
,
1590 {ui::VKEY_9
, ui::EF_COMMAND_DOWN
},
1591 {ui::VKEY_F9
, ui::EF_NONE
},
1592 {ui::VKEY_F9
, ui::EF_NONE
}},
1593 {ui::ET_KEY_PRESSED
,
1594 {ui::VKEY_0
, ui::EF_COMMAND_DOWN
},
1595 {ui::VKEY_F10
, ui::EF_NONE
},
1596 {ui::VKEY_F10
, ui::EF_NONE
}},
1597 {ui::ET_KEY_PRESSED
,
1598 {ui::VKEY_OEM_MINUS
, ui::EF_COMMAND_DOWN
},
1599 {ui::VKEY_F11
, ui::EF_NONE
},
1600 {ui::VKEY_F11
, ui::EF_NONE
}},
1601 {ui::ET_KEY_PRESSED
,
1602 {ui::VKEY_OEM_PLUS
, ui::EF_COMMAND_DOWN
},
1603 {ui::VKEY_F12
, ui::EF_NONE
},
1604 {ui::VKEY_F12
, ui::EF_NONE
}},
1606 // The function keys should not be rewritten with Search key pressed.
1607 {ui::ET_KEY_PRESSED
,
1608 {ui::VKEY_F1
, ui::EF_COMMAND_DOWN
},
1609 {ui::VKEY_F1
, ui::EF_NONE
},
1610 {ui::VKEY_F1
, ui::EF_FUNCTION_KEY
}},
1611 {ui::ET_KEY_PRESSED
,
1612 {ui::VKEY_F2
, ui::EF_COMMAND_DOWN
},
1613 {ui::VKEY_F2
, ui::EF_NONE
},
1614 {ui::VKEY_F2
, ui::EF_FUNCTION_KEY
}},
1615 {ui::ET_KEY_PRESSED
,
1616 {ui::VKEY_F3
, ui::EF_COMMAND_DOWN
},
1617 {ui::VKEY_F3
, ui::EF_NONE
},
1618 {ui::VKEY_F3
, ui::EF_FUNCTION_KEY
}},
1619 {ui::ET_KEY_PRESSED
,
1620 {ui::VKEY_F4
, ui::EF_COMMAND_DOWN
},
1621 {ui::VKEY_F4
, ui::EF_NONE
},
1622 {ui::VKEY_F4
, ui::EF_FUNCTION_KEY
}},
1623 {ui::ET_KEY_PRESSED
,
1624 {ui::VKEY_F5
, ui::EF_COMMAND_DOWN
},
1625 {ui::VKEY_F5
, ui::EF_NONE
},
1626 {ui::VKEY_F5
, ui::EF_FUNCTION_KEY
}},
1627 {ui::ET_KEY_PRESSED
,
1628 {ui::VKEY_F6
, ui::EF_COMMAND_DOWN
},
1629 {ui::VKEY_F6
, ui::EF_NONE
},
1630 {ui::VKEY_F6
, ui::EF_FUNCTION_KEY
}},
1631 {ui::ET_KEY_PRESSED
,
1632 {ui::VKEY_F7
, ui::EF_COMMAND_DOWN
},
1633 {ui::VKEY_F7
, ui::EF_NONE
},
1634 {ui::VKEY_F7
, ui::EF_FUNCTION_KEY
}},
1635 {ui::ET_KEY_PRESSED
,
1636 {ui::VKEY_F8
, ui::EF_COMMAND_DOWN
},
1637 {ui::VKEY_F8
, ui::EF_NONE
},
1638 {ui::VKEY_F8
, ui::EF_FUNCTION_KEY
}},
1639 {ui::ET_KEY_PRESSED
,
1640 {ui::VKEY_F9
, ui::EF_COMMAND_DOWN
},
1641 {ui::VKEY_F9
, ui::EF_NONE
},
1642 {ui::VKEY_F9
, ui::EF_FUNCTION_KEY
}},
1643 {ui::ET_KEY_PRESSED
,
1644 {ui::VKEY_F10
, ui::EF_COMMAND_DOWN
},
1645 {ui::VKEY_F10
, ui::EF_NONE
},
1646 {ui::VKEY_F10
, ui::EF_FUNCTION_KEY
}},
1647 {ui::ET_KEY_PRESSED
,
1648 {ui::VKEY_F11
, ui::EF_COMMAND_DOWN
},
1649 {ui::VKEY_F11
, ui::EF_NONE
},
1650 {ui::VKEY_F11
, ui::EF_FUNCTION_KEY
}},
1651 {ui::ET_KEY_PRESSED
,
1652 {ui::VKEY_F12
, ui::EF_COMMAND_DOWN
},
1653 {ui::VKEY_F12
, ui::EF_NONE
},
1654 {ui::VKEY_F12
, ui::EF_FUNCTION_KEY
}},
1657 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
1659 CheckFunctionKeyTestCase(&rewriter
, tests
[i
]);
1663 TEST_F(EventRewriterTest
, TestRewriteExtendedKeysWithSearchRemapped
) {
1664 const base::CommandLine
original_cl(*base::CommandLine::ForCurrentProcess());
1666 // Remap Search to Control.
1667 TestingPrefServiceSyncable prefs
;
1668 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1669 IntegerPrefMember search
;
1670 search
.Init(prefs::kLanguageRemapSearchKeyTo
, &prefs
);
1671 search
.SetValue(chromeos::input_method::kControlKey
);
1673 EventRewriter
rewriter(NULL
);
1674 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1675 rewriter
.set_pref_service_for_testing(&prefs
);
1677 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1678 chromeos::switches::kHasChromeOSKeyboard
, "");
1680 KeyTestCase tests
[] = {
1681 // Alt+Search+Down -> End
1682 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1683 {ui::VKEY_DOWN
, ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
},
1684 {ui::VKEY_END
, ui::EF_NONE
}},
1686 // Shift+Alt+Search+Down -> Shift+End
1687 {KeyTestCase::TEST_ALL
, ui::ET_KEY_PRESSED
,
1689 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
| ui::EF_COMMAND_DOWN
},
1690 {ui::VKEY_END
, ui::EF_SHIFT_DOWN
}},
1693 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
1695 CheckKeyTestCase(&rewriter
, tests
[i
]);
1698 *base::CommandLine::ForCurrentProcess() = original_cl
;
1701 TEST_F(EventRewriterTest
, TestRewriteKeyEventSentByXSendEvent
) {
1702 // Remap Control to Alt.
1703 TestingPrefServiceSyncable prefs
;
1704 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1705 IntegerPrefMember control
;
1706 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
1707 control
.SetValue(chromeos::input_method::kAltKey
);
1709 EventRewriter
rewriter(NULL
);
1710 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1711 rewriter
.set_pref_service_for_testing(&prefs
);
1713 // Send left control press.
1715 ui::KeyEvent
keyevent(
1716 ui::ET_KEY_PRESSED
, ui::VKEY_CONTROL
, ui::EF_FINAL
);
1717 scoped_ptr
<ui::Event
> new_event
;
1718 // Control should NOT be remapped to Alt if EF_FINAL is set.
1719 EXPECT_EQ(ui::EVENT_REWRITE_CONTINUE
,
1720 rewriter
.RewriteEvent(keyevent
, &new_event
));
1721 EXPECT_FALSE(new_event
);
1723 #if defined(USE_X11)
1724 // Send left control press, using XI2 native events.
1726 ui::ScopedXI2Event xev
;
1727 xev
.InitKeyEvent(ui::ET_KEY_PRESSED
, ui::VKEY_CONTROL
, 0);
1728 XEvent
* xevent
= xev
;
1729 xevent
->xkey
.keycode
= XKeysymToKeycode(gfx::GetXDisplay(), XK_Control_L
);
1730 xevent
->xkey
.send_event
= True
; // XSendEvent() always does this.
1731 ui::KeyEvent
keyevent(xev
);
1732 scoped_ptr
<ui::Event
> new_event
;
1733 // Control should NOT be remapped to Alt if send_event
1734 // flag in the event is True.
1735 EXPECT_EQ(ui::EVENT_REWRITE_CONTINUE
,
1736 rewriter
.RewriteEvent(keyevent
, &new_event
));
1737 EXPECT_FALSE(new_event
);
1742 TEST_F(EventRewriterTest
, TestRewriteNonNativeEvent
) {
1743 // Remap Control to Alt.
1744 TestingPrefServiceSyncable prefs
;
1745 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1746 IntegerPrefMember control
;
1747 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
1748 control
.SetValue(chromeos::input_method::kAltKey
);
1750 EventRewriter
rewriter(NULL
);
1751 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1752 rewriter
.set_pref_service_for_testing(&prefs
);
1754 const int kTouchId
= 2;
1755 gfx::Point
location(0, 0);
1756 ui::TouchEvent
press(
1757 ui::ET_TOUCH_PRESSED
, location
, kTouchId
, base::TimeDelta());
1758 press
.set_flags(ui::EF_CONTROL_DOWN
);
1759 #if defined(USE_X11)
1760 ui::UpdateX11EventForFlags(&press
);
1763 scoped_ptr
<ui::Event
> new_event
;
1764 rewriter
.RewriteEvent(press
, &new_event
);
1765 EXPECT_TRUE(new_event
);
1766 // Control should be remapped to Alt.
1767 EXPECT_EQ(ui::EF_ALT_DOWN
,
1768 new_event
->flags() & (ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
));
1771 // Keeps a buffer of handled events.
1772 class EventBuffer
: public ui::test::TestEventProcessor
{
1775 ~EventBuffer() override
{}
1777 void PopEvents(ScopedVector
<ui::Event
>* events
) {
1779 events
->swap(events_
);
1783 // ui::EventProcessor overrides:
1784 ui::EventDispatchDetails
OnEventFromSource(ui::Event
* event
) override
{
1785 if (event
->IsKeyEvent()) {
1786 events_
.push_back(new ui::KeyEvent(*static_cast<ui::KeyEvent
*>(event
)));
1787 } else if (event
->IsMouseWheelEvent()) {
1789 new ui::MouseWheelEvent(*static_cast<ui::MouseWheelEvent
*>(event
)));
1790 } else if (event
->IsMouseEvent()) {
1792 new ui::MouseEvent(*static_cast<ui::MouseEvent
*>(event
)));
1794 return ui::EventDispatchDetails();
1797 ScopedVector
<ui::Event
> events_
;
1799 DISALLOW_COPY_AND_ASSIGN(EventBuffer
);
1802 // Trivial EventSource that does nothing but send events.
1803 class TestEventSource
: public ui::EventSource
{
1805 explicit TestEventSource(ui::EventProcessor
* processor
)
1806 : processor_(processor
) {}
1807 ui::EventProcessor
* GetEventProcessor() override
{ return processor_
; }
1808 ui::EventDispatchDetails
Send(ui::Event
* event
) {
1809 return SendEventToProcessor(event
);
1813 ui::EventProcessor
* processor_
;
1816 // Tests of event rewriting that depend on the Ash window manager.
1817 class EventRewriterAshTest
: public ash::test::AshTestBase
{
1819 EventRewriterAshTest()
1820 : source_(&buffer_
),
1821 fake_user_manager_(new user_manager::FakeUserManager
),
1822 user_manager_enabler_(fake_user_manager_
) {}
1823 ~EventRewriterAshTest() override
{}
1825 bool RewriteFunctionKeys(const ui::Event
& event
,
1826 scoped_ptr
<ui::Event
>* rewritten_event
) {
1827 return rewriter_
->RewriteEvent(event
, rewritten_event
);
1830 ui::EventDispatchDetails
Send(ui::Event
* event
) {
1831 return source_
.Send(event
);
1834 void SendKeyEvent(ui::EventType type
, ui::KeyboardCode key_code
) {
1835 ui::KeyEvent
press(type
, key_code
, ui::EF_NONE
);
1836 ui::EventDispatchDetails details
= Send(&press
);
1837 CHECK(!details
.dispatcher_destroyed
);
1840 void SendActivateStickyKeyPattern(ui::KeyboardCode key_code
) {
1841 SendKeyEvent(ui::ET_KEY_PRESSED
, key_code
);
1842 SendKeyEvent(ui::ET_KEY_RELEASED
, key_code
);
1846 TestingPrefServiceSyncable
* prefs() { return &prefs_
; }
1848 void PopEvents(ScopedVector
<ui::Event
>* events
) {
1849 buffer_
.PopEvents(events
);
1852 void SetUp() override
{
1853 AshTestBase::SetUp();
1854 sticky_keys_controller_
=
1855 ash::Shell::GetInstance()->sticky_keys_controller();
1856 rewriter_
.reset(new EventRewriter(sticky_keys_controller_
));
1857 chromeos::Preferences::RegisterProfilePrefs(prefs_
.registry());
1858 rewriter_
->set_pref_service_for_testing(&prefs_
);
1859 #if defined(USE_X11)
1860 ui::SetUpTouchPadForTest(kTouchPadDeviceId
);
1862 source_
.AddEventRewriter(rewriter_
.get());
1863 sticky_keys_controller_
->Enable(true);
1866 void TearDown() override
{
1868 AshTestBase::TearDown();
1872 ash::StickyKeysController
* sticky_keys_controller_
;
1875 scoped_ptr
<EventRewriter
> rewriter_
;
1877 EventBuffer buffer_
;
1878 TestEventSource source_
;
1880 user_manager::FakeUserManager
* fake_user_manager_
; // Not owned.
1881 chromeos::ScopedUserManagerEnabler user_manager_enabler_
;
1882 TestingPrefServiceSyncable prefs_
;
1884 DISALLOW_COPY_AND_ASSIGN(EventRewriterAshTest
);
1887 TEST_F(EventRewriterAshTest
, TopRowKeysAreFunctionKeys
) {
1888 scoped_ptr
<aura::Window
> window(CreateTestWindowInShellWithId(1));
1889 ash::wm::WindowState
* window_state
= ash::wm::GetWindowState(window
.get());
1890 window_state
->Activate();
1891 ScopedVector
<ui::Event
> events
;
1893 // Create a simulated keypress of F1 targetted at the window.
1894 ui::KeyEvent
press_f1(ui::ET_KEY_PRESSED
, ui::VKEY_F1
, ui::EF_NONE
);
1896 // Simulate an apps v2 window that has requested top row keys as function
1897 // keys. The event should not be rewritten.
1898 window_state
->set_top_row_keys_are_function_keys(true);
1899 ui::EventDispatchDetails details
= Send(&press_f1
);
1900 ASSERT_FALSE(details
.dispatcher_destroyed
);
1902 EXPECT_EQ(1u, events
.size());
1904 GetExpectedResultAsString(ui::VKEY_F1
, ui::EF_NONE
, ui::ET_KEY_PRESSED
),
1905 GetKeyEventAsString(*static_cast<ui::KeyEvent
*>(events
[0])));
1907 // The event should also not be rewritten if the send-function-keys pref is
1908 // additionally set, for both apps v2 and regular windows.
1909 BooleanPrefMember send_function_keys_pref
;
1910 send_function_keys_pref
.Init(prefs::kLanguageSendFunctionKeys
, prefs());
1911 send_function_keys_pref
.SetValue(true);
1912 window_state
->set_top_row_keys_are_function_keys(false);
1913 details
= Send(&press_f1
);
1914 ASSERT_FALSE(details
.dispatcher_destroyed
);
1916 EXPECT_EQ(1u, events
.size());
1918 GetExpectedResultAsString(ui::VKEY_F1
, ui::EF_NONE
, ui::ET_KEY_PRESSED
),
1919 GetKeyEventAsString(*static_cast<ui::KeyEvent
*>(events
[0])));
1921 // If the pref isn't set when an event is sent to a regular window, F1 is
1922 // rewritten to the back key.
1923 send_function_keys_pref
.SetValue(false);
1924 details
= Send(&press_f1
);
1925 ASSERT_FALSE(details
.dispatcher_destroyed
);
1927 EXPECT_EQ(1u, events
.size());
1928 EXPECT_EQ(GetExpectedResultAsString(
1929 ui::VKEY_BROWSER_BACK
, ui::EF_NONE
, ui::ET_KEY_PRESSED
),
1930 GetKeyEventAsString(*static_cast<ui::KeyEvent
*>(events
[0])));
1933 TEST_F(EventRewriterTest
, TestRewrittenModifierClick
) {
1934 std::vector
<unsigned int> device_list
;
1935 device_list
.push_back(10);
1936 ui::TouchFactory::GetInstance()->SetPointerDeviceForTest(device_list
);
1938 // Remap Control to Alt.
1939 TestingPrefServiceSyncable prefs
;
1940 chromeos::Preferences::RegisterProfilePrefs(prefs
.registry());
1941 IntegerPrefMember control
;
1942 control
.Init(prefs::kLanguageRemapControlKeyTo
, &prefs
);
1943 control
.SetValue(chromeos::input_method::kAltKey
);
1945 EventRewriter
rewriter(NULL
);
1946 rewriter
.KeyboardDeviceAddedForTesting(kKeyboardDeviceId
, "PC Keyboard");
1947 rewriter
.set_pref_service_for_testing(&prefs
);
1949 // Check that Control + Left Button is converted (via Alt + Left Button)
1951 ui::ScopedXI2Event xev
;
1952 xev
.InitGenericButtonEvent(10,
1953 ui::ET_MOUSE_PRESSED
,
1955 ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_CONTROL_DOWN
);
1956 ui::MouseEvent
press(xev
);
1958 EXPECT_EQ(ui::ET_MOUSE_PRESSED
, press
.type());
1959 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_CONTROL_DOWN
, press
.flags());
1960 scoped_ptr
<ui::Event
> new_event
;
1961 const ui::MouseEvent
* result
=
1962 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
1963 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
1964 EXPECT_FALSE(ui::EF_LEFT_MOUSE_BUTTON
& result
->flags());
1965 EXPECT_FALSE(ui::EF_CONTROL_DOWN
& result
->flags());
1966 EXPECT_FALSE(ui::EF_ALT_DOWN
& result
->flags());
1967 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
1970 TEST_F(EventRewriterTest
, DontRewriteIfNotRewritten
) {
1971 // TODO(kpschoedel): pending changes for crbug.com/360377
1972 // to |chromeos::EventRewriter::RewriteLocatedEvent()
1973 std::vector
<unsigned int> device_list
;
1974 device_list
.push_back(10);
1975 device_list
.push_back(11);
1976 ui::TouchFactory::GetInstance()->SetPointerDeviceForTest(device_list
);
1977 TestingPrefServiceSyncable prefs
;
1978 EventRewriter
rewriter(NULL
);
1979 rewriter
.set_pref_service_for_testing(&prefs
);
1980 const int kLeftAndAltFlag
= ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_ALT_DOWN
;
1982 // Test Alt + Left click.
1984 ui::MouseEvent
press(ui::ET_MOUSE_PRESSED
, gfx::Point(), gfx::Point(),
1985 ui::EventTimeForNow(), kLeftAndAltFlag
,
1986 ui::EF_LEFT_MOUSE_BUTTON
);
1987 ui::EventTestApi
test_press(&press
);
1988 test_press
.set_source_device_id(10);
1990 EXPECT_EQ(ui::ET_MOUSE_PRESSED
, press
.type());
1991 EXPECT_EQ(kLeftAndAltFlag
, press
.flags());
1992 scoped_ptr
<ui::Event
> new_event
;
1993 const ui::MouseEvent
* result
=
1994 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
1995 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
1996 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
1997 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
2000 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
, gfx::Point(), gfx::Point(),
2001 ui::EventTimeForNow(), kLeftAndAltFlag
,
2002 ui::EF_LEFT_MOUSE_BUTTON
);
2003 ui::EventTestApi
test_release(&release
);
2004 test_release
.set_source_device_id(10);
2005 scoped_ptr
<ui::Event
> new_event
;
2006 const ui::MouseEvent
* result
=
2007 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
2008 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
2009 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
2010 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
2012 #if defined(USE_X11)
2013 // Test Alt + Left click, using XI2 native events.
2015 ui::ScopedXI2Event xev
;
2016 xev
.InitGenericButtonEvent(
2017 10, ui::ET_MOUSE_PRESSED
, gfx::Point(), kLeftAndAltFlag
);
2018 ui::MouseEvent
press(xev
);
2020 EXPECT_EQ(ui::ET_MOUSE_PRESSED
, press
.type());
2021 EXPECT_EQ(kLeftAndAltFlag
, press
.flags());
2022 scoped_ptr
<ui::Event
> new_event
;
2023 const ui::MouseEvent
* result
=
2024 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
2025 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
2026 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
2027 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
2030 ui::ScopedXI2Event xev
;
2031 xev
.InitGenericButtonEvent(
2032 10, ui::ET_MOUSE_RELEASED
, gfx::Point(), kLeftAndAltFlag
);
2033 ui::MouseEvent
release(xev
);
2034 scoped_ptr
<ui::Event
> new_event
;
2035 const ui::MouseEvent
* result
=
2036 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
2037 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
2038 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
2039 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
2043 // No ALT in frst click.
2045 ui::MouseEvent
press(ui::ET_MOUSE_PRESSED
, gfx::Point(), gfx::Point(),
2046 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON
,
2047 ui::EF_LEFT_MOUSE_BUTTON
);
2048 ui::EventTestApi
test_press(&press
);
2049 test_press
.set_source_device_id(10);
2050 scoped_ptr
<ui::Event
> new_event
;
2051 const ui::MouseEvent
* result
=
2052 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
2053 EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON
& result
->flags());
2054 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
2057 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
, gfx::Point(), gfx::Point(),
2058 ui::EventTimeForNow(), kLeftAndAltFlag
,
2059 ui::EF_LEFT_MOUSE_BUTTON
);
2060 ui::EventTestApi
test_release(&release
);
2061 test_release
.set_source_device_id(10);
2062 scoped_ptr
<ui::Event
> new_event
;
2063 const ui::MouseEvent
* result
=
2064 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
2065 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_ALT_DOWN
) & result
->flags());
2066 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
2068 #if defined(USE_X11)
2069 // No ALT in frst click, using XI2 native events.
2071 ui::ScopedXI2Event xev
;
2072 xev
.InitGenericButtonEvent(
2073 10, ui::ET_MOUSE_PRESSED
, gfx::Point(), ui::EF_LEFT_MOUSE_BUTTON
);
2074 ui::MouseEvent
press(xev
);
2075 scoped_ptr
<ui::Event
> new_event
;
2076 const ui::MouseEvent
* result
=
2077 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
2078 EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON
& result
->flags());
2079 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
2082 ui::ScopedXI2Event xev
;
2083 xev
.InitGenericButtonEvent(
2084 10, ui::ET_MOUSE_RELEASED
, gfx::Point(), kLeftAndAltFlag
);
2085 ui::MouseEvent
release(xev
);
2086 scoped_ptr
<ui::Event
> new_event
;
2087 const ui::MouseEvent
* result
=
2088 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
2089 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_ALT_DOWN
) & result
->flags());
2090 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
2094 // ALT on different device.
2096 ui::MouseEvent
press(ui::ET_MOUSE_PRESSED
, gfx::Point(), gfx::Point(),
2097 ui::EventTimeForNow(), kLeftAndAltFlag
,
2098 ui::EF_LEFT_MOUSE_BUTTON
);
2099 ui::EventTestApi
test_press(&press
);
2100 test_press
.set_source_device_id(11);
2101 scoped_ptr
<ui::Event
> new_event
;
2102 const ui::MouseEvent
* result
=
2103 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
2104 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
2105 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
2106 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
2109 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
, gfx::Point(), gfx::Point(),
2110 ui::EventTimeForNow(), kLeftAndAltFlag
,
2111 ui::EF_LEFT_MOUSE_BUTTON
);
2112 ui::EventTestApi
test_release(&release
);
2113 test_release
.set_source_device_id(10);
2114 scoped_ptr
<ui::Event
> new_event
;
2115 const ui::MouseEvent
* result
=
2116 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
2117 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_ALT_DOWN
) & result
->flags());
2118 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
2121 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
, gfx::Point(), gfx::Point(),
2122 ui::EventTimeForNow(), kLeftAndAltFlag
,
2123 ui::EF_LEFT_MOUSE_BUTTON
);
2124 ui::EventTestApi
test_release(&release
);
2125 test_release
.set_source_device_id(11);
2126 scoped_ptr
<ui::Event
> new_event
;
2127 const ui::MouseEvent
* result
=
2128 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
2129 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
2130 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
2131 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
2133 #if defined(USE_X11)
2134 // ALT on different device, using XI2 native events.
2136 ui::ScopedXI2Event xev
;
2137 xev
.InitGenericButtonEvent(
2138 11, ui::ET_MOUSE_PRESSED
, gfx::Point(), kLeftAndAltFlag
);
2139 ui::MouseEvent
press(xev
);
2140 scoped_ptr
<ui::Event
> new_event
;
2141 const ui::MouseEvent
* result
=
2142 RewriteMouseButtonEvent(&rewriter
, press
, &new_event
);
2143 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
2144 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
2145 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
2148 ui::ScopedXI2Event xev
;
2149 xev
.InitGenericButtonEvent(
2150 10, ui::ET_MOUSE_RELEASED
, gfx::Point(), kLeftAndAltFlag
);
2151 ui::MouseEvent
release(xev
);
2152 scoped_ptr
<ui::Event
> new_event
;
2153 const ui::MouseEvent
* result
=
2154 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
2155 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_ALT_DOWN
) & result
->flags());
2156 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON
, result
->changed_button_flags());
2159 ui::ScopedXI2Event xev
;
2160 xev
.InitGenericButtonEvent(
2161 11, ui::ET_MOUSE_RELEASED
, gfx::Point(), kLeftAndAltFlag
);
2162 ui::MouseEvent
release(xev
);
2163 scoped_ptr
<ui::Event
> new_event
;
2164 const ui::MouseEvent
* result
=
2165 RewriteMouseButtonEvent(&rewriter
, release
, &new_event
);
2166 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON
& result
->flags());
2167 EXPECT_FALSE(kLeftAndAltFlag
& result
->flags());
2168 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON
, result
->changed_button_flags());
2173 TEST_F(EventRewriterAshTest
, StickyKeyEventDispatchImpl
) {
2174 // Test the actual key event dispatch implementation.
2175 ScopedVector
<ui::Event
> events
;
2177 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
);
2179 EXPECT_EQ(1u, events
.size());
2180 EXPECT_EQ(ui::ET_KEY_PRESSED
, events
[0]->type());
2181 EXPECT_EQ(ui::VKEY_CONTROL
,
2182 static_cast<ui::KeyEvent
*>(events
[0])->key_code());
2184 // Test key press event is correctly modified and modifier release
2186 ui::KeyEvent
press(ui::ET_KEY_PRESSED
, ui::VKEY_C
, ui::EF_NONE
);
2187 ui::EventDispatchDetails details
= Send(&press
);
2189 EXPECT_EQ(2u, events
.size());
2190 EXPECT_EQ(ui::ET_KEY_PRESSED
, events
[0]->type());
2191 EXPECT_EQ(ui::VKEY_C
, static_cast<ui::KeyEvent
*>(events
[0])->key_code());
2192 EXPECT_TRUE(events
[0]->flags() & ui::EF_CONTROL_DOWN
);
2193 EXPECT_EQ(ui::ET_KEY_RELEASED
, events
[1]->type());
2194 EXPECT_EQ(ui::VKEY_CONTROL
,
2195 static_cast<ui::KeyEvent
*>(events
[1])->key_code());
2197 // Test key release event is not modified.
2198 ui::KeyEvent
release(ui::ET_KEY_RELEASED
, ui::VKEY_C
, ui::EF_NONE
);
2199 details
= Send(&release
);
2200 ASSERT_FALSE(details
.dispatcher_destroyed
);
2202 EXPECT_EQ(1u, events
.size());
2203 EXPECT_EQ(ui::ET_KEY_RELEASED
, events
[0]->type());
2204 EXPECT_EQ(ui::VKEY_C
, static_cast<ui::KeyEvent
*>(events
[0])->key_code());
2205 EXPECT_FALSE(events
[0]->flags() & ui::EF_CONTROL_DOWN
);
2208 TEST_F(EventRewriterAshTest
, MouseEventDispatchImpl
) {
2209 ScopedVector
<ui::Event
> events
;
2211 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
);
2214 // Test mouse press event is correctly modified.
2215 gfx::Point
location(0, 0);
2216 ui::MouseEvent
press(ui::ET_MOUSE_PRESSED
, location
, location
,
2217 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON
,
2218 ui::EF_LEFT_MOUSE_BUTTON
);
2219 ui::EventDispatchDetails details
= Send(&press
);
2220 ASSERT_FALSE(details
.dispatcher_destroyed
);
2222 EXPECT_EQ(1u, events
.size());
2223 EXPECT_EQ(ui::ET_MOUSE_PRESSED
, events
[0]->type());
2224 EXPECT_TRUE(events
[0]->flags() & ui::EF_CONTROL_DOWN
);
2226 // Test mouse release event is correctly modified and modifier release
2227 // event is sent. The mouse event should have the correct DIP location.
2228 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
, location
, location
,
2229 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON
,
2230 ui::EF_LEFT_MOUSE_BUTTON
);
2231 details
= Send(&release
);
2232 ASSERT_FALSE(details
.dispatcher_destroyed
);
2234 EXPECT_EQ(2u, events
.size());
2235 EXPECT_EQ(ui::ET_MOUSE_RELEASED
, events
[0]->type());
2236 EXPECT_TRUE(events
[0]->flags() & ui::EF_CONTROL_DOWN
);
2237 EXPECT_EQ(ui::ET_KEY_RELEASED
, events
[1]->type());
2238 EXPECT_EQ(ui::VKEY_CONTROL
,
2239 static_cast<ui::KeyEvent
*>(events
[1])->key_code());
2242 TEST_F(EventRewriterAshTest
, MouseWheelEventDispatchImpl
) {
2243 ScopedVector
<ui::Event
> events
;
2245 // Test positive mouse wheel event is correctly modified and modifier release
2247 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
);
2249 gfx::Point
location(0, 0);
2250 ui::MouseEvent
mev(ui::ET_MOUSEWHEEL
, location
, location
,
2251 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON
,
2252 ui::EF_LEFT_MOUSE_BUTTON
);
2253 ui::MouseWheelEvent
positive(mev
, 0, ui::MouseWheelEvent::kWheelDelta
);
2254 ui::EventDispatchDetails details
= Send(&positive
);
2255 ASSERT_FALSE(details
.dispatcher_destroyed
);
2257 EXPECT_EQ(2u, events
.size());
2258 EXPECT_TRUE(events
[0]->IsMouseWheelEvent());
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());
2264 // Test negative mouse wheel event is correctly modified and modifier release
2266 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
);
2268 ui::MouseWheelEvent
negative(mev
, 0, -ui::MouseWheelEvent::kWheelDelta
);
2269 details
= Send(&negative
);
2270 ASSERT_FALSE(details
.dispatcher_destroyed
);
2272 EXPECT_EQ(2u, events
.size());
2273 EXPECT_TRUE(events
[0]->IsMouseWheelEvent());
2274 EXPECT_TRUE(events
[0]->flags() & ui::EF_CONTROL_DOWN
);
2275 EXPECT_EQ(ui::ET_KEY_RELEASED
, events
[1]->type());
2276 EXPECT_EQ(ui::VKEY_CONTROL
,
2277 static_cast<ui::KeyEvent
*>(events
[1])->key_code());
2280 class StickyKeysOverlayTest
: public EventRewriterAshTest
{
2282 StickyKeysOverlayTest() : overlay_(NULL
) {}
2284 ~StickyKeysOverlayTest() override
{}
2286 void SetUp() override
{
2287 EventRewriterAshTest::SetUp();
2288 overlay_
= sticky_keys_controller_
->GetOverlayForTest();
2289 ASSERT_TRUE(overlay_
);
2292 ash::StickyKeysOverlay
* overlay_
;
2295 TEST_F(StickyKeysOverlayTest
, OneModifierEnabled
) {
2296 EXPECT_FALSE(overlay_
->is_visible());
2297 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2298 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2300 // Pressing modifier key should show overlay.
2301 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
);
2302 EXPECT_TRUE(overlay_
->is_visible());
2303 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
2304 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2306 // Pressing a normal key should hide overlay.
2307 SendActivateStickyKeyPattern(ui::VKEY_T
);
2308 EXPECT_FALSE(overlay_
->is_visible());
2309 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2310 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2313 TEST_F(StickyKeysOverlayTest
, TwoModifiersEnabled
) {
2314 EXPECT_FALSE(overlay_
->is_visible());
2315 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2316 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2317 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2318 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
2320 // Pressing two modifiers should show overlay.
2321 SendActivateStickyKeyPattern(ui::VKEY_SHIFT
);
2322 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
);
2323 EXPECT_TRUE(overlay_
->is_visible());
2324 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
2325 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
2326 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
2327 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2329 // Pressing a normal key should hide overlay.
2330 SendActivateStickyKeyPattern(ui::VKEY_N
);
2331 EXPECT_FALSE(overlay_
->is_visible());
2332 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2333 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2334 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2335 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
2338 TEST_F(StickyKeysOverlayTest
, LockedModifier
) {
2339 EXPECT_FALSE(overlay_
->is_visible());
2340 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2341 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
2343 // Pressing a modifier key twice should lock modifier and show overlay.
2344 SendActivateStickyKeyPattern(ui::VKEY_LMENU
);
2345 SendActivateStickyKeyPattern(ui::VKEY_LMENU
);
2346 EXPECT_TRUE(overlay_
->is_visible());
2347 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
2348 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
2350 // Pressing a normal key should not hide overlay.
2351 SendActivateStickyKeyPattern(ui::VKEY_D
);
2352 EXPECT_TRUE(overlay_
->is_visible());
2353 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
2354 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
2357 TEST_F(StickyKeysOverlayTest
, LockedAndNormalModifier
) {
2358 EXPECT_FALSE(overlay_
->is_visible());
2359 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2360 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2361 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2362 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
2364 // Pressing a modifier key twice should lock modifier and show overlay.
2365 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
);
2366 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
);
2367 EXPECT_TRUE(overlay_
->is_visible());
2368 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
2369 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2371 // Pressing another modifier key should still show overlay.
2372 SendActivateStickyKeyPattern(ui::VKEY_SHIFT
);
2373 EXPECT_TRUE(overlay_
->is_visible());
2374 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
2375 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2376 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
2377 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
2379 // Pressing a normal key should not hide overlay but disable normal modifier.
2380 SendActivateStickyKeyPattern(ui::VKEY_D
);
2381 EXPECT_TRUE(overlay_
->is_visible());
2382 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
2383 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2384 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2385 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
2388 TEST_F(StickyKeysOverlayTest
, ModifiersDisabled
) {
2389 EXPECT_FALSE(overlay_
->is_visible());
2390 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2391 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2392 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2393 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
2394 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2395 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
2396 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2397 overlay_
->GetModifierKeyState(ui::EF_COMMAND_DOWN
));
2399 // Enable modifiers.
2400 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
);
2401 SendActivateStickyKeyPattern(ui::VKEY_SHIFT
);
2402 SendActivateStickyKeyPattern(ui::VKEY_SHIFT
);
2403 SendActivateStickyKeyPattern(ui::VKEY_LMENU
);
2404 SendActivateStickyKeyPattern(ui::VKEY_COMMAND
);
2405 SendActivateStickyKeyPattern(ui::VKEY_COMMAND
);
2407 EXPECT_TRUE(overlay_
->is_visible());
2408 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
2409 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2410 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
2411 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
2412 EXPECT_EQ(ash::STICKY_KEY_STATE_ENABLED
,
2413 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
2414 EXPECT_EQ(ash::STICKY_KEY_STATE_LOCKED
,
2415 overlay_
->GetModifierKeyState(ui::EF_COMMAND_DOWN
));
2417 // Disable modifiers and overlay should be hidden.
2418 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
);
2419 SendActivateStickyKeyPattern(ui::VKEY_CONTROL
);
2420 SendActivateStickyKeyPattern(ui::VKEY_SHIFT
);
2421 SendActivateStickyKeyPattern(ui::VKEY_LMENU
);
2422 SendActivateStickyKeyPattern(ui::VKEY_LMENU
);
2423 SendActivateStickyKeyPattern(ui::VKEY_COMMAND
);
2425 EXPECT_FALSE(overlay_
->is_visible());
2426 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2427 overlay_
->GetModifierKeyState(ui::EF_CONTROL_DOWN
));
2428 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2429 overlay_
->GetModifierKeyState(ui::EF_SHIFT_DOWN
));
2430 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2431 overlay_
->GetModifierKeyState(ui::EF_ALT_DOWN
));
2432 EXPECT_EQ(ash::STICKY_KEY_STATE_DISABLED
,
2433 overlay_
->GetModifierKeyState(ui::EF_COMMAND_DOWN
));
2436 TEST_F(StickyKeysOverlayTest
, ModifierVisibility
) {
2437 // All but AltGr and Mod3 should initially be visible.
2438 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_CONTROL_DOWN
));
2439 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_SHIFT_DOWN
));
2440 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_ALT_DOWN
));
2441 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_COMMAND_DOWN
));
2442 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_ALTGR_DOWN
));
2443 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_MOD3_DOWN
));
2445 // Turn all modifiers on.
2446 sticky_keys_controller_
->SetModifiersEnabled(true, true);
2447 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_CONTROL_DOWN
));
2448 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_SHIFT_DOWN
));
2449 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_ALT_DOWN
));
2450 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_COMMAND_DOWN
));
2451 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_ALTGR_DOWN
));
2452 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_MOD3_DOWN
));
2455 sticky_keys_controller_
->SetModifiersEnabled(false, true);
2456 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_ALTGR_DOWN
));
2457 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_MOD3_DOWN
));
2460 sticky_keys_controller_
->SetModifiersEnabled(true, false);
2461 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_ALTGR_DOWN
));
2462 EXPECT_TRUE(overlay_
->GetModifierVisible(ui::EF_MOD3_DOWN
));
2464 // Turn off AltGr and Mod3.
2465 sticky_keys_controller_
->SetModifiersEnabled(false, false);
2466 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_ALTGR_DOWN
));
2467 EXPECT_FALSE(overlay_
->GetModifierVisible(ui::EF_MOD3_DOWN
));
2470 } // namespace chromeos