Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(930)

Side by Side Diff: chrome/browser/chromeos/events/new_event_rewriter_unittest.cc

Issue 237363005: Convert chromeos::EventRewriter to a ui::EventRewriter (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "chrome/browser/chromeos/events/new_event_rewriter.h"
6
7 #include <X11/keysym.h>
8 #include <X11/XF86keysym.h>
9 #include <X11/Xlib.h>
10 #undef Bool
11 #undef None
12 #undef RootWindow
13
14 #include <vector>
15
16 #include "ash/test/ash_test_base.h"
17 #include "ash/wm/window_state.h"
18 #include "base/basictypes.h"
19 #include "base/command_line.h"
20 #include "base/prefs/pref_member.h"
21 #include "base/strings/stringprintf.h"
22 #include "chrome/browser/chromeos/input_method/input_method_configuration.h"
23 #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h"
24 #include "chrome/browser/chromeos/login/mock_user_manager.h"
25 #include "chrome/browser/chromeos/login/user_manager.h"
26 #include "chrome/browser/chromeos/preferences.h"
27 #include "chrome/common/pref_names.h"
28 #include "chrome/test/base/testing_pref_service_syncable.h"
29 #include "chromeos/chromeos_switches.h"
30 #include "chromeos/ime/fake_ime_keyboard.h"
31 #include "testing/gtest/include/gtest/gtest.h"
32 #include "ui/aura/window.h"
33 #include "ui/events/event.h"
34 #include "ui/events/event_rewriter.h"
35 #include "ui/events/test/events_test_utils_x11.h"
36 #include "ui/events/x/touch_factory_x11.h"
37 #include "ui/gfx/x/x11_types.h"
38
39 namespace {
40
41 std::string GetKeyEventAsString(const ui::KeyEvent& keyevent) {
42 return base::StringPrintf(
43 "ui_keycode=0x%X ui_flags=0x%X ui_type=%d",
44 keyevent.key_code(), keyevent.flags(), keyevent.type());
45 }
46
47 std::string GetRewrittenEventAsString(chromeos::KeyboardEventRewriter* rewriter,
48 ui::KeyboardCode ui_keycode,
49 int ui_flags,
50 ui::EventType ui_type) {
51 ui::KeyEvent event(ui_type, ui_keycode, ui_flags, false);
52 scoped_ptr<ui::Event> new_event;
53 rewriter->RewriteEvent(&event, &new_event);
54 return GetKeyEventAsString(event);
55 }
56
57 std::string GetExpectedResultAsString(ui::KeyboardCode ui_keycode,
58 int ui_flags,
59 ui::EventType ui_type) {
60 return base::StringPrintf(
61 "ui_keycode=0x%X ui_flags=0x%X ui_type=%d",
62 ui_keycode, ui_flags, ui_type);
63 }
64
65 std::string GetRewrittenEventNumbered(size_t i,
66 chromeos::KeyboardEventRewriter* rewriter,
67 ui::KeyboardCode ui_keycode,
68 int ui_flags,
69 ui::EventType ui_type) {
70 return base::StringPrintf("(%zu) ", i) +
71 GetRewrittenEventAsString(rewriter, ui_keycode, ui_flags, ui_type);
72 }
73
74 std::string GetExpectedResultNumbered(size_t i,
75 ui::KeyboardCode ui_keycode,
76 int ui_flags,
77 ui::EventType ui_type) {
78 return base::StringPrintf("(%zu) ", i) +
79 GetExpectedResultAsString(ui_keycode, ui_flags, ui_type);
80 }
81
82
83 } // namespace
84
85 namespace chromeos {
86
87 class KeyboardEventRewriterTest : public ash::test::AshTestBase {
88 public:
89 KeyboardEventRewriterTest()
90 : display_(gfx::GetXDisplay()),
91 mock_user_manager_(new chromeos::MockUserManager),
92 user_manager_enabler_(mock_user_manager_),
93 input_method_manager_mock_(NULL) {
94 }
95 virtual ~KeyboardEventRewriterTest() {}
96
97 virtual void SetUp() {
98 // Mocking user manager because the real one needs to be called on UI thread
99 EXPECT_CALL(*mock_user_manager_, IsLoggedInAsGuest())
100 .WillRepeatedly(testing::Return(false));
101 input_method_manager_mock_ =
102 new chromeos::input_method::MockInputMethodManager;
103 chromeos::input_method::InitializeForTesting(
104 input_method_manager_mock_); // pass ownership
105
106 AshTestBase::SetUp();
107 }
108
109 virtual void TearDown() {
110 AshTestBase::TearDown();
111 // Shutdown() deletes the IME mock object.
112 chromeos::input_method::Shutdown();
113 }
114
115 protected:
116 void TestRewriteNumPadKeys();
117 void TestRewriteNumPadKeysOnAppleKeyboard();
118
119 void RewriteMouseEvent(chromeos::KeyboardEventRewriter* rewriter,
120 ui::MouseEvent* event) {
121 rewriter->RewriteLocatedEventForTesting(event);
122 }
123
124 Display* display_;
125 chromeos::MockUserManager* mock_user_manager_; // Not owned.
126 chromeos::ScopedUserManagerEnabler user_manager_enabler_;
127 chromeos::input_method::MockInputMethodManager* input_method_manager_mock_;
128 };
129
130 TEST_F(KeyboardEventRewriterTest, TestRewriteCommandToControl) {
131 // First, test with a PC keyboard.
132 TestingPrefServiceSyncable prefs;
133 KeyboardEventRewriter rewriter;
134 rewriter.DeviceAddedForTesting(0, "PC Keyboard");
135 rewriter.set_last_device_id_for_testing(0);
136 rewriter.set_pref_service_for_testing(&prefs);
137
138 // VKEY_A, Alt modifier.
139 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
sadrul 2014/04/14 21:51:32 How are you creating these tests? It would be grea
kpschoedel 2014/04/14 22:25:45 These are copies from the old unit tests, with the
140 ui::EF_ALT_DOWN,
141 ui::ET_KEY_PRESSED),
142 GetRewrittenEventAsString(&rewriter,
143 ui::VKEY_A,
144 ui::EF_ALT_DOWN,
145 ui::ET_KEY_PRESSED));
146
147 // VKEY_A, Win modifier.
148 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
149 ui::EF_COMMAND_DOWN,
150 ui::ET_KEY_PRESSED),
151 GetRewrittenEventAsString(&rewriter,
152 ui::VKEY_A,
153 ui::EF_COMMAND_DOWN,
154 ui::ET_KEY_PRESSED));
155
156 // VKEY_A, Alt+Win modifier.
157 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
158 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
159 ui::ET_KEY_PRESSED),
160 GetRewrittenEventAsString(&rewriter,
161 ui::VKEY_A,
162 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
163 ui::ET_KEY_PRESSED));
164
165 // VKEY_LWIN (left Windows key), Alt modifier.
166 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN,
167 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
168 ui::ET_KEY_PRESSED),
169 GetRewrittenEventAsString(&rewriter,
170 ui::VKEY_LWIN,
171 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
172 ui::ET_KEY_PRESSED));
173
174 // VKEY_RWIN (right Windows key), Alt modifier.
175 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_RWIN,
176 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
177 ui::ET_KEY_PRESSED),
178 GetRewrittenEventAsString(&rewriter,
179 ui::VKEY_RWIN,
180 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
181 ui::ET_KEY_PRESSED));
182
183 // An Apple keyboard reusing the ID, zero.
184 rewriter.DeviceAddedForTesting(0, "Apple Keyboard");
185 rewriter.set_last_device_id_for_testing(0);
186
187 // VKEY_A, Alt modifier.
188 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
189 ui::EF_ALT_DOWN,
190 ui::ET_KEY_PRESSED),
191 GetRewrittenEventAsString(&rewriter,
192 ui::VKEY_A,
193 ui::EF_ALT_DOWN,
194 ui::ET_KEY_PRESSED));
195
196 // VKEY_A, Win modifier.
197 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
198 ui::EF_CONTROL_DOWN,
199 ui::ET_KEY_PRESSED),
200 GetRewrittenEventAsString(&rewriter,
201 ui::VKEY_A,
202 ui::EF_COMMAND_DOWN,
203 ui::ET_KEY_PRESSED));
204
205 // VKEY_A, Alt+Win modifier.
206 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
207 ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
208 ui::ET_KEY_PRESSED),
209 GetRewrittenEventAsString(&rewriter,
210 ui::VKEY_A,
211 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
212 ui::ET_KEY_PRESSED));
213
214 // VKEY_LWIN (left Windows key), Alt modifier.
215 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
216 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
217 ui::ET_KEY_PRESSED),
218 GetRewrittenEventAsString(&rewriter,
219 ui::VKEY_LWIN,
220 ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
221 ui::ET_KEY_PRESSED));
222
223 // VKEY_RWIN (right Windows key), Alt modifier.
224 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
225 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
226 ui::ET_KEY_PRESSED),
227 GetRewrittenEventAsString(&rewriter,
228 ui::VKEY_RWIN,
229 ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
230 ui::ET_KEY_PRESSED));
231 }
232
233 // For crbug.com/133896.
234 TEST_F(KeyboardEventRewriterTest,
235 TestRewriteCommandToControlWithControlRemapped) {
236 // Remap Control to Alt.
237 TestingPrefServiceSyncable prefs;
238 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
239 IntegerPrefMember control;
240 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
241 control.SetValue(chromeos::input_method::kAltKey);
242
243 KeyboardEventRewriter rewriter;
244 rewriter.set_pref_service_for_testing(&prefs);
245 rewriter.DeviceAddedForTesting(0, "PC Keyboard");
246 rewriter.set_last_device_id_for_testing(0);
247
248 // Control should be remapped to Alt.
249 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
250 ui::EF_ALT_DOWN,
251 ui::ET_KEY_PRESSED),
252 GetRewrittenEventAsString(&rewriter,
253 ui::VKEY_CONTROL,
254 ui::EF_CONTROL_DOWN,
255 ui::ET_KEY_PRESSED));
256
257 // An Apple keyboard reusing the ID, zero.
258 rewriter.DeviceAddedForTesting(0, "Apple Keyboard");
259 rewriter.set_last_device_id_for_testing(0);
260
261 // VKEY_LWIN (left Command key) with Alt modifier. The remapped Command key
262 // should never be re-remapped to Alt.
263 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
264 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
265 ui::ET_KEY_PRESSED),
266 GetRewrittenEventAsString(&rewriter,
267 ui::VKEY_LWIN,
268 ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
269 ui::ET_KEY_PRESSED));
270
271 // VKEY_RWIN (right Command key) with Alt modifier. The remapped Command key
272 // should never be re-remapped to Alt.
273 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
274 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
275 ui::ET_KEY_PRESSED),
276 GetRewrittenEventAsString(&rewriter,
277 ui::VKEY_RWIN,
278 ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
279 ui::ET_KEY_PRESSED));
280 }
281
282 void KeyboardEventRewriterTest::TestRewriteNumPadKeys() {
283 TestingPrefServiceSyncable prefs;
284 KeyboardEventRewriter rewriter;
285 rewriter.set_pref_service_for_testing(&prefs);
286
287 // XK_KP_Insert (= NumPad 0 without Num Lock), no modifier.
288 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD0,
289 ui::EF_NUMPAD,
290 ui::ET_KEY_PRESSED),
291 GetRewrittenEventAsString(&rewriter,
292 ui::VKEY_INSERT,
293 ui::EF_NUMPAD,
294 ui::ET_KEY_PRESSED));
295
296 // XK_KP_Insert (= NumPad 0 without Num Lock), Alt modifier.
297 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD0,
298 ui::EF_ALT_DOWN | ui::EF_NUMPAD,
299 ui::ET_KEY_PRESSED),
300 GetRewrittenEventAsString(&rewriter,
301 ui::VKEY_INSERT,
302 ui::EF_ALT_DOWN | ui::EF_NUMPAD,
303 ui::ET_KEY_PRESSED));
304
305 // XK_KP_Delete (= NumPad . without Num Lock), Alt modifier.
306 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_DECIMAL,
307 ui::EF_ALT_DOWN | ui::EF_NUMPAD,
308 ui::ET_KEY_PRESSED),
309 GetRewrittenEventAsString(&rewriter,
310 ui::VKEY_DELETE,
311 ui::EF_ALT_DOWN | ui::EF_NUMPAD,
312 ui::ET_KEY_PRESSED));
313
314 // XK_KP_End (= NumPad 1 without Num Lock), Alt modifier.
315 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD1,
316 ui::EF_ALT_DOWN | ui::EF_NUMPAD,
317 ui::ET_KEY_PRESSED),
318 GetRewrittenEventAsString(&rewriter,
319 ui::VKEY_END,
320 ui::EF_ALT_DOWN | ui::EF_NUMPAD,
321 ui::ET_KEY_PRESSED));
322
323 // XK_KP_Down (= NumPad 2 without Num Lock), Alt modifier.
324 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD2,
325 ui::EF_ALT_DOWN | ui::EF_NUMPAD,
326 ui::ET_KEY_PRESSED),
327 GetRewrittenEventAsString(&rewriter,
328 ui::VKEY_DOWN,
329 ui::EF_ALT_DOWN | ui::EF_NUMPAD,
330 ui::ET_KEY_PRESSED));
331
332 // XK_KP_Next (= NumPad 3 without Num Lock), Alt modifier.
333 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD3,
334 ui::EF_ALT_DOWN | ui::EF_NUMPAD,
335 ui::ET_KEY_PRESSED),
336 GetRewrittenEventAsString(&rewriter,
337 ui::VKEY_NEXT,
338 ui::EF_ALT_DOWN | ui::EF_NUMPAD,
339 ui::ET_KEY_PRESSED));
340
341 // XK_KP_Left (= NumPad 4 without Num Lock), Alt modifier.
342 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD4,
343 ui::EF_ALT_DOWN | ui::EF_NUMPAD,
344 ui::ET_KEY_PRESSED),
345 GetRewrittenEventAsString(&rewriter,
346 ui::VKEY_LEFT,
347 ui::EF_ALT_DOWN | ui::EF_NUMPAD,
348 ui::ET_KEY_PRESSED));
349
350 // XK_KP_Begin (= NumPad 5 without Num Lock), Alt modifier.
351 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD5,
352 ui::EF_ALT_DOWN | ui::EF_NUMPAD,
353 ui::ET_KEY_PRESSED),
354 GetRewrittenEventAsString(&rewriter,
355 ui::VKEY_CLEAR,
356 ui::EF_ALT_DOWN | ui::EF_NUMPAD,
357 ui::ET_KEY_PRESSED));
358
359 // XK_KP_Right (= NumPad 6 without Num Lock), Alt modifier.
360 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD6,
361 ui::EF_ALT_DOWN | ui::EF_NUMPAD,
362 ui::ET_KEY_PRESSED),
363 GetRewrittenEventAsString(&rewriter,
364 ui::VKEY_RIGHT,
365 ui::EF_ALT_DOWN | ui::EF_NUMPAD,
366 ui::ET_KEY_PRESSED));
367
368 // XK_KP_Home (= NumPad 7 without Num Lock), Alt modifier.
369 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD7,
370 ui::EF_ALT_DOWN | ui::EF_NUMPAD,
371 ui::ET_KEY_PRESSED),
372 GetRewrittenEventAsString(&rewriter,
373 ui::VKEY_HOME,
374 ui::EF_ALT_DOWN | ui::EF_NUMPAD,
375 ui::ET_KEY_PRESSED));
376
377 // XK_KP_Up (= NumPad 8 without Num Lock), Alt modifier.
378 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD8,
379 ui::EF_ALT_DOWN | ui::EF_NUMPAD,
380 ui::ET_KEY_PRESSED),
381 GetRewrittenEventAsString(&rewriter,
382 ui::VKEY_UP,
383 ui::EF_ALT_DOWN | ui::EF_NUMPAD,
384 ui::ET_KEY_PRESSED));
385
386 // XK_KP_Prior (= NumPad 9 without Num Lock), Alt modifier.
387 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD9,
388 ui::EF_ALT_DOWN | ui::EF_NUMPAD,
389 ui::ET_KEY_PRESSED),
390 GetRewrittenEventAsString(&rewriter,
391 ui::VKEY_PRIOR,
392 ui::EF_ALT_DOWN | ui::EF_NUMPAD,
393 ui::ET_KEY_PRESSED));
394
395 // XK_KP_0 (= NumPad 0 with Num Lock), Num Lock modifier.
396 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD0,
397 ui::EF_NUMPAD,
398 ui::ET_KEY_PRESSED),
399 GetRewrittenEventAsString(&rewriter,
400 ui::VKEY_NUMPAD0,
401 ui::EF_NUMPAD,
402 ui::ET_KEY_PRESSED));
403
404 // XK_KP_DECIMAL (= NumPad . with Num Lock), Num Lock modifier.
405 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_DECIMAL,
406 ui::EF_NUMPAD,
407 ui::ET_KEY_PRESSED),
408 GetRewrittenEventAsString(&rewriter,
409 ui::VKEY_DECIMAL,
410 ui::EF_NUMPAD,
411 ui::ET_KEY_PRESSED));
412
413 // XK_KP_1 (= NumPad 1 with Num Lock), Num Lock modifier.
414 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD1,
415 ui::EF_NUMPAD,
416 ui::ET_KEY_PRESSED),
417 GetRewrittenEventAsString(&rewriter,
418 ui::VKEY_NUMPAD1,
419 ui::EF_NUMPAD,
420 ui::ET_KEY_PRESSED));
421
422 // XK_KP_2 (= NumPad 2 with Num Lock), Num Lock modifier.
423 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD2,
424 ui::EF_NUMPAD,
425 ui::ET_KEY_PRESSED),
426 GetRewrittenEventAsString(&rewriter,
427 ui::VKEY_NUMPAD2,
428 ui::EF_NUMPAD,
429 ui::ET_KEY_PRESSED));
430
431 // XK_KP_3 (= NumPad 3 with Num Lock), Num Lock modifier.
432 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD3,
433 ui::EF_NUMPAD,
434 ui::ET_KEY_PRESSED),
435 GetRewrittenEventAsString(&rewriter,
436 ui::VKEY_NUMPAD3,
437 ui::EF_NUMPAD,
438 ui::ET_KEY_PRESSED));
439
440 // XK_KP_4 (= NumPad 4 with Num Lock), Num Lock modifier.
441 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD4,
442 ui::EF_NUMPAD,
443 ui::ET_KEY_PRESSED),
444 GetRewrittenEventAsString(&rewriter,
445 ui::VKEY_NUMPAD4,
446 ui::EF_NUMPAD,
447 ui::ET_KEY_PRESSED));
448
449 // XK_KP_5 (= NumPad 5 with Num Lock), Num Lock modifier.
450 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD5,
451 ui::EF_NUMPAD,
452 ui::ET_KEY_PRESSED),
453 GetRewrittenEventAsString(&rewriter,
454 ui::VKEY_NUMPAD5,
455 ui::EF_NUMPAD,
456 ui::ET_KEY_PRESSED));
457
458 // XK_KP_6 (= NumPad 6 with Num Lock), Num Lock modifier.
459 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD6,
460 ui::EF_NUMPAD,
461 ui::ET_KEY_PRESSED),
462 GetRewrittenEventAsString(&rewriter,
463 ui::VKEY_NUMPAD6,
464 ui::EF_NUMPAD,
465 ui::ET_KEY_PRESSED));
466
467 // XK_KP_7 (= NumPad 7 with Num Lock), Num Lock modifier.
468 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD7,
469 ui::EF_NUMPAD,
470 ui::ET_KEY_PRESSED),
471 GetRewrittenEventAsString(&rewriter,
472 ui::VKEY_NUMPAD7,
473 ui::EF_NUMPAD,
474 ui::ET_KEY_PRESSED));
475
476 // XK_KP_8 (= NumPad 8 with Num Lock), Num Lock modifier.
477 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD8,
478 ui::EF_NUMPAD,
479 ui::ET_KEY_PRESSED),
480 GetRewrittenEventAsString(&rewriter,
481 ui::VKEY_NUMPAD8,
482 ui::EF_NUMPAD,
483 ui::ET_KEY_PRESSED));
484
485 // XK_KP_9 (= NumPad 9 with Num Lock), Num Lock modifier.
486 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD9,
487 ui::EF_NUMPAD,
488 ui::ET_KEY_PRESSED),
489 GetRewrittenEventAsString(&rewriter,
490 ui::VKEY_NUMPAD9,
491 ui::EF_NUMPAD,
492 ui::ET_KEY_PRESSED));
493 }
494
495 TEST_F(KeyboardEventRewriterTest, TestRewriteNumPadKeys) {
496 TestRewriteNumPadKeys();
497 }
498
499 TEST_F(KeyboardEventRewriterTest, TestRewriteNumPadKeysWithDiamondKeyFlag) {
500 // Make sure the num lock works correctly even when Diamond key exists.
501 const CommandLine original_cl(*CommandLine::ForCurrentProcess());
502 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
503 chromeos::switches::kHasChromeOSDiamondKey, "");
504
505 TestRewriteNumPadKeys();
506 *CommandLine::ForCurrentProcess() = original_cl;
507 }
508
509 // Tests if the rewriter can handle a Command + Num Pad event.
510 void KeyboardEventRewriterTest::TestRewriteNumPadKeysOnAppleKeyboard() {
511 TestingPrefServiceSyncable prefs;
512 KeyboardEventRewriter rewriter;
513 rewriter.DeviceAddedForTesting(0, "Apple Keyboard");
514 rewriter.set_last_device_id_for_testing(0);
515 rewriter.set_pref_service_for_testing(&prefs);
516
517 // XK_KP_End (= NumPad 1 without Num Lock), Win modifier.
518 // The result should be "Num Pad 1 with Control + Num Lock modifiers".
519 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD1,
520 ui::EF_CONTROL_DOWN | ui::EF_NUMPAD,
521 ui::ET_KEY_PRESSED),
522 GetRewrittenEventAsString(&rewriter,
523 ui::VKEY_END,
524 ui::EF_COMMAND_DOWN | ui::EF_NUMPAD,
525 ui::ET_KEY_PRESSED));
526
527 // XK_KP_1 (= NumPad 1 with Num Lock), Win modifier.
528 // The result should also be "Num Pad 1 with Control + Num Lock modifiers".
529 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD1,
530 ui::EF_CONTROL_DOWN | ui::EF_NUMPAD,
531 ui::ET_KEY_PRESSED),
532 GetRewrittenEventAsString(&rewriter,
533 ui::VKEY_NUMPAD1,
534 ui::EF_COMMAND_DOWN | ui::EF_NUMPAD,
535 ui::ET_KEY_PRESSED));
536 }
537
538 TEST_F(KeyboardEventRewriterTest, TestRewriteNumPadKeysOnAppleKeyboard) {
539 TestRewriteNumPadKeysOnAppleKeyboard();
540 }
541
542 TEST_F(KeyboardEventRewriterTest,
543 TestRewriteNumPadKeysOnAppleKeyboardWithDiamondKeyFlag) {
544 // Makes sure the num lock works correctly even when Diamond key exists.
545 const CommandLine original_cl(*CommandLine::ForCurrentProcess());
546 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
547 chromeos::switches::kHasChromeOSDiamondKey, "");
548
549 TestRewriteNumPadKeysOnAppleKeyboard();
550 *CommandLine::ForCurrentProcess() = original_cl;
551 }
552
553 TEST_F(KeyboardEventRewriterTest, TestRewriteModifiersNoRemap) {
554 TestingPrefServiceSyncable prefs;
555 KeyboardEventRewriter rewriter;
556 // XXX rewriter.DeviceAddedForTesting(0, "PC Keyboard");
557 // XXX rewriter.set_last_device_id_for_testing(0);
558 rewriter.set_pref_service_for_testing(&prefs);
559
560 // Press Search. Confirm the event is not rewritten.
561 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN,
562 ui::EF_COMMAND_DOWN,
563 ui::ET_KEY_PRESSED),
564 GetRewrittenEventAsString(&rewriter,
565 ui::VKEY_LWIN,
566 ui::EF_NONE,
567 ui::ET_KEY_PRESSED));
568
569 // Press left Control. Confirm the event is not rewritten.
570 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
571 ui::EF_CONTROL_DOWN,
572 ui::ET_KEY_PRESSED),
573 GetRewrittenEventAsString(&rewriter,
574 ui::VKEY_CONTROL,
575 ui::EF_CONTROL_DOWN,
576 ui::ET_KEY_PRESSED));
577
578 // Press right Control. Confirm the event is not rewritten.
579 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
580 ui::EF_CONTROL_DOWN,
581 ui::ET_KEY_PRESSED),
582 GetRewrittenEventAsString(&rewriter,
583 ui::VKEY_CONTROL,
584 ui::EF_CONTROL_DOWN,
585 ui::ET_KEY_PRESSED));
586
587 // Press left Alt. Confirm the event is not rewritten.
588 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
589 ui::EF_ALT_DOWN,
590 ui::ET_KEY_PRESSED),
591 GetRewrittenEventAsString(&rewriter,
592 ui::VKEY_MENU,
593 ui::EF_ALT_DOWN,
594 ui::ET_KEY_PRESSED));
595
596 // Press right Alt. Confirm the event is not rewritten.
597 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
598 ui::EF_ALT_DOWN,
599 ui::ET_KEY_PRESSED),
600 GetRewrittenEventAsString(&rewriter,
601 ui::VKEY_MENU,
602 ui::EF_ALT_DOWN,
603 ui::ET_KEY_PRESSED));
604
605 // Test KeyRelease event, just in case.
606 // Release Search. Confirm the release event is not rewritten.
607 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN,
608 ui::EF_NONE,
609 ui::ET_KEY_RELEASED),
610 GetRewrittenEventAsString(&rewriter,
611 ui::VKEY_LWIN,
612 ui::EF_NONE,
613 ui::ET_KEY_RELEASED));
614 }
615
616 TEST_F(KeyboardEventRewriterTest, TestRewriteModifiersNoRemapMultipleKeys) {
617 TestingPrefServiceSyncable prefs;
618 KeyboardEventRewriter rewriter;
619 // XXX rewriter.DeviceAddedForTesting(0, "PC Keyboard");
620 // XXX rewriter.set_last_device_id_for_testing(0);
621 rewriter.set_pref_service_for_testing(&prefs);
622
623 // Press Alt with Shift. Confirm the event is not rewritten.
624 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
625 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
626 ui::ET_KEY_PRESSED),
627 GetRewrittenEventAsString(&rewriter,
628 ui::VKEY_MENU,
629 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
630 ui::ET_KEY_PRESSED));
631
632 // Press Search with Caps Lock mask. Confirm the event is not rewritten.
633 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN,
634 ui::EF_CAPS_LOCK_DOWN |
635 ui::EF_COMMAND_DOWN,
636 ui::ET_KEY_PRESSED),
637 GetRewrittenEventAsString(&rewriter,
638 ui::VKEY_LWIN,
639 ui::EF_CAPS_LOCK_DOWN |
640 ui::EF_COMMAND_DOWN,
641 ui::ET_KEY_PRESSED));
642
643 // Release Search with Caps Lock mask. Confirm the event is not rewritten.
644 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN,
645 ui::EF_CAPS_LOCK_DOWN,
646 ui::ET_KEY_RELEASED),
647 GetRewrittenEventAsString(&rewriter,
648 ui::VKEY_LWIN,
649 ui::EF_CAPS_LOCK_DOWN,
650 ui::ET_KEY_RELEASED));
651
652 // Press Shift+Ctrl+Alt+Search+A. Confirm the event is not rewritten.
653 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_B,
654 ui::EF_SHIFT_DOWN |
655 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN |
656 ui::EF_COMMAND_DOWN,
657 ui::ET_KEY_PRESSED),
658 GetRewrittenEventAsString(&rewriter,
659 ui::VKEY_B,
660 ui::EF_SHIFT_DOWN |
661 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN |
662 ui::EF_COMMAND_DOWN,
663 ui::ET_KEY_PRESSED));
664 }
665
666 TEST_F(KeyboardEventRewriterTest, TestRewriteModifiersDisableSome) {
667 // Disable Search and Control keys.
668 TestingPrefServiceSyncable prefs;
669 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
670 IntegerPrefMember search;
671 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
672 search.SetValue(chromeos::input_method::kVoidKey);
673 IntegerPrefMember control;
674 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
675 control.SetValue(chromeos::input_method::kVoidKey);
676
677 KeyboardEventRewriter rewriter;
678 // XXX rewriter.DeviceAddedForTesting(0, "PC Keyboard");
679 // XXX rewriter.set_last_device_id_for_testing(0);
680 rewriter.set_pref_service_for_testing(&prefs);
681
682 // Press Alt with Shift. This key press shouldn't be affected by the
683 // pref. Confirm the event is not rewritten.
684 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
685 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
686 ui::ET_KEY_PRESSED),
687 GetRewrittenEventAsString(&rewriter,
688 ui::VKEY_MENU,
689 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
690 ui::ET_KEY_PRESSED));
691
692 // Press Search. Confirm the event is now VKEY_UNKNOWN.
693 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_UNKNOWN,
694 ui::EF_NONE,
695 ui::ET_KEY_PRESSED),
696 GetRewrittenEventAsString(&rewriter,
697 ui::VKEY_LWIN,
698 ui::EF_NONE,
699 ui::ET_KEY_PRESSED));
700
701 // Press Control. Confirm the event is now VKEY_UNKNOWN.
702 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_UNKNOWN,
703 ui::EF_NONE,
704 ui::ET_KEY_PRESSED),
705 GetRewrittenEventAsString(&rewriter,
706 ui::VKEY_CONTROL,
707 ui::EF_NONE,
708 ui::ET_KEY_PRESSED));
709
710 // Press Control+Search. Confirm the event is now VKEY_UNKNOWN
711 // without any modifiers.
712 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_UNKNOWN,
713 ui::EF_NONE,
714 ui::ET_KEY_PRESSED),
715 GetRewrittenEventAsString(&rewriter,
716 ui::VKEY_LWIN,
717 ui::EF_CONTROL_DOWN,
718 ui::ET_KEY_PRESSED));
719
720 // Press Control+Search+a. Confirm the event is now VKEY_A without any
721 // modifiers.
722 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
723 ui::EF_NONE,
724 ui::ET_KEY_PRESSED),
725 GetRewrittenEventAsString(&rewriter,
726 ui::VKEY_A,
727 ui::EF_CONTROL_DOWN,
728 ui::ET_KEY_PRESSED));
729
730 // Press Control+Search+Alt+a. Confirm the event is now VKEY_A only with
731 // the Alt modifier.
732 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
733 ui::EF_ALT_DOWN,
734 ui::ET_KEY_PRESSED),
735 GetRewrittenEventAsString(&rewriter,
736 ui::VKEY_A,
737 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
738 ui::ET_KEY_PRESSED));
739
740 // Remap Alt to Control.
741 IntegerPrefMember alt;
742 alt.Init(prefs::kLanguageRemapAltKeyTo, &prefs);
743 alt.SetValue(chromeos::input_method::kControlKey);
744
745 // Press left Alt. Confirm the event is now VKEY_CONTROL
746 // even though the Control key itself is disabled.
747 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
748 ui::EF_CONTROL_DOWN,
749 ui::ET_KEY_PRESSED),
750 GetRewrittenEventAsString(&rewriter,
751 ui::VKEY_MENU,
752 ui::EF_ALT_DOWN,
753 ui::ET_KEY_PRESSED));
754
755 // Press Alt+a. Confirm the event is now Control+a even though the Control
756 // key itself is disabled.
757 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
758 ui::EF_CONTROL_DOWN,
759 ui::ET_KEY_PRESSED),
760 GetRewrittenEventAsString(&rewriter,
761 ui::VKEY_A,
762 ui::EF_ALT_DOWN,
763 ui::ET_KEY_PRESSED));
764 }
765
766 TEST_F(KeyboardEventRewriterTest, TestRewriteModifiersRemapToControl) {
767 // Remap Search to Control.
768 TestingPrefServiceSyncable prefs;
769 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
770 IntegerPrefMember search;
771 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
772 search.SetValue(chromeos::input_method::kControlKey);
773
774 KeyboardEventRewriter rewriter;
775 // XXX rewriter.DeviceAddedForTesting(0, "PC Keyboard");
776 // XXX rewriter.set_last_device_id_for_testing(0);
777 rewriter.set_pref_service_for_testing(&prefs);
778
779 // Press Search. Confirm the event is now VKEY_CONTROL.
780 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
781 ui::EF_CONTROL_DOWN,
782 ui::ET_KEY_PRESSED),
783 GetRewrittenEventAsString(&rewriter,
784 ui::VKEY_LWIN,
785 ui::EF_COMMAND_DOWN,
786 ui::ET_KEY_PRESSED));
787
788 // Remap Alt to Control too.
789 IntegerPrefMember alt;
790 alt.Init(prefs::kLanguageRemapAltKeyTo, &prefs);
791 alt.SetValue(chromeos::input_method::kControlKey);
792
793 // Press Alt. Confirm the event is now VKEY_CONTROL.
794 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
795 ui::EF_CONTROL_DOWN,
796 ui::ET_KEY_PRESSED),
797 GetRewrittenEventAsString(&rewriter,
798 ui::VKEY_MENU,
799 ui::EF_ALT_DOWN,
800 ui::ET_KEY_PRESSED));
801
802 // Press Alt+Search. Confirm the event is now VKEY_CONTROL.
803 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
804 ui::EF_CONTROL_DOWN,
805 ui::ET_KEY_PRESSED),
806 GetRewrittenEventAsString(&rewriter,
807 ui::VKEY_LWIN,
808 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
809 ui::ET_KEY_PRESSED));
810
811 // Press Control+Alt+Search. Confirm the event is now VKEY_CONTROL.
812 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
813 ui::EF_CONTROL_DOWN,
814 ui::ET_KEY_PRESSED),
815 GetRewrittenEventAsString(&rewriter,
816 ui::VKEY_LWIN,
817 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN |
818 ui::EF_COMMAND_DOWN,
819 ui::ET_KEY_PRESSED));
820
821 // Press Shift+Control+Alt+Search. Confirm the event is now Control with
822 // Shift and Control modifiers.
823 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
824 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
825 ui::ET_KEY_PRESSED),
826 GetRewrittenEventAsString(&rewriter,
827 ui::VKEY_LWIN,
828 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
829 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
830 ui::ET_KEY_PRESSED));
831
832 // Press Shift+Control+Alt+Search+B. Confirm the event is now B with Shift
833 // and Control modifiers.
834 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_B,
835 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
836 ui::ET_KEY_PRESSED),
837 GetRewrittenEventAsString(&rewriter,
838 ui::VKEY_B,
839 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
840 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
841 ui::ET_KEY_PRESSED));
842 }
843
844 TEST_F(KeyboardEventRewriterTest, TestRewriteModifiersRemapToEscape) {
845 // Remap Search to ESC.
846 TestingPrefServiceSyncable prefs;
847 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
848 IntegerPrefMember search;
849 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
850 search.SetValue(chromeos::input_method::kEscapeKey);
851
852 KeyboardEventRewriter rewriter;
853 // XXX rewriter.DeviceAddedForTesting(0, "PC Keyboard");
854 // XXX rewriter.set_last_device_id_for_testing(0);
855 rewriter.set_pref_service_for_testing(&prefs);
856
857 // Press Search. Confirm the event is now VKEY_ESCAPE.
858 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_ESCAPE,
859 ui::EF_NONE,
860 ui::ET_KEY_PRESSED),
861 GetRewrittenEventAsString(&rewriter,
862 ui::VKEY_LWIN,
863 ui::EF_COMMAND_DOWN,
864 ui::ET_KEY_PRESSED));
865 }
866
867 TEST_F(KeyboardEventRewriterTest, TestRewriteModifiersRemapMany) {
868 // Remap Search to Alt.
869 TestingPrefServiceSyncable prefs;
870 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
871 IntegerPrefMember search;
872 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
873 search.SetValue(chromeos::input_method::kAltKey);
874
875 KeyboardEventRewriter rewriter;
876 // XXX rewriter.DeviceAddedForTesting(0, "PC Keyboard");
877 // XXX rewriter.set_last_device_id_for_testing(0);
878 rewriter.set_pref_service_for_testing(&prefs);
879
880 // Press Search. Confirm the event is now VKEY_MENU.
881 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
882 ui::EF_ALT_DOWN,
883 ui::ET_KEY_PRESSED),
884 GetRewrittenEventAsString(&rewriter,
885 ui::VKEY_LWIN,
886 ui::EF_COMMAND_DOWN,
887 ui::ET_KEY_PRESSED));
888
889 // Remap Alt to Control.
890 IntegerPrefMember alt;
891 alt.Init(prefs::kLanguageRemapAltKeyTo, &prefs);
892 alt.SetValue(chromeos::input_method::kControlKey);
893
894 // Press left Alt. Confirm the event is now VKEY_CONTROL.
895 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
896 ui::EF_CONTROL_DOWN,
897 ui::ET_KEY_PRESSED),
898 GetRewrittenEventAsString(&rewriter,
899 ui::VKEY_MENU,
900 ui::EF_ALT_DOWN,
901 ui::ET_KEY_PRESSED));
902
903 // Remap Control to Search.
904 IntegerPrefMember control;
905 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
906 control.SetValue(chromeos::input_method::kSearchKey);
907
908 // Press left Control. Confirm the event is now VKEY_LWIN.
909 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN,
910 ui::EF_COMMAND_DOWN,
911 ui::ET_KEY_PRESSED),
912 GetRewrittenEventAsString(&rewriter,
913 ui::VKEY_CONTROL,
914 ui::EF_CONTROL_DOWN,
915 ui::ET_KEY_PRESSED));
916
917 // Then, press all of the three, Control+Alt+Search.
918 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
919 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN |
920 ui::EF_COMMAND_DOWN,
921 ui::ET_KEY_PRESSED),
922 GetRewrittenEventAsString(&rewriter,
923 ui::VKEY_LWIN,
924 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN |
925 ui::EF_COMMAND_DOWN,
926 ui::ET_KEY_PRESSED));
927
928 // Press Shift+Control+Alt+Search.
929 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
930 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
931 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
932 ui::ET_KEY_PRESSED),
933 GetRewrittenEventAsString(&rewriter,
934 ui::VKEY_LWIN,
935 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
936 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
937 ui::ET_KEY_PRESSED));
938
939 // Press Shift+Control+Alt+Search+B
940 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_B,
941 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
942 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
943 ui::ET_KEY_PRESSED),
944 GetRewrittenEventAsString(&rewriter,
945 ui::VKEY_B,
946 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
947 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
948 ui::ET_KEY_PRESSED));
949 }
950
951 TEST_F(KeyboardEventRewriterTest, TestRewriteModifiersRemapToCapsLock) {
952 // Remap Search to Caps Lock.
953 TestingPrefServiceSyncable prefs;
954 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
955 IntegerPrefMember search;
956 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
957 search.SetValue(chromeos::input_method::kCapsLockKey);
958
959 chromeos::input_method::FakeImeKeyboard ime_keyboard;
960 KeyboardEventRewriter rewriter;
961 // XXX rewriter.DeviceAddedForTesting(0, "PC Keyboard");
962 // XXX rewriter.set_last_device_id_for_testing(0);
963 rewriter.set_pref_service_for_testing(&prefs);
964 rewriter.set_ime_keyboard_for_testing(&ime_keyboard);
965 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
966
967 // Press Search.
968 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
969 ui::EF_CAPS_LOCK_DOWN,
970 ui::ET_KEY_PRESSED),
971 GetRewrittenEventAsString(&rewriter,
972 ui::VKEY_LWIN,
973 ui::EF_COMMAND_DOWN,
974 ui::ET_KEY_PRESSED));
975 // Confirm that the Caps Lock status is changed.
976 EXPECT_TRUE(ime_keyboard.caps_lock_is_enabled_);
977
978 // Release Search.
979 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
980 ui::EF_NONE,
981 ui::ET_KEY_RELEASED),
982 GetRewrittenEventAsString(&rewriter,
983 ui::VKEY_LWIN,
984 ui::EF_NONE,
985 ui::ET_KEY_RELEASED));
986 // Confirm that the Caps Lock status is not changed.
987 EXPECT_TRUE(ime_keyboard.caps_lock_is_enabled_);
988
989 // Press Search.
990 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
991 ui::EF_CAPS_LOCK_DOWN,
992 ui::ET_KEY_PRESSED),
993 GetRewrittenEventAsString(&rewriter,
994 ui::VKEY_LWIN,
995 ui::EF_COMMAND_DOWN |
996 ui::EF_CAPS_LOCK_DOWN,
997 ui::ET_KEY_PRESSED));
998 // Confirm that the Caps Lock status is changed.
999 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
1000
1001 // Release Search.
1002 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
1003 ui::EF_NONE,
1004 ui::ET_KEY_RELEASED),
1005 GetRewrittenEventAsString(&rewriter,
1006 ui::VKEY_LWIN,
1007 ui::EF_NONE,
1008 ui::ET_KEY_RELEASED));
1009 // Confirm that the Caps Lock status is not changed.
1010 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
1011
1012 // Press Caps Lock (on an external keyboard).
1013 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
1014 ui::EF_CAPS_LOCK_DOWN,
1015 ui::ET_KEY_PRESSED),
1016 GetRewrittenEventAsString(&rewriter,
1017 ui::VKEY_CAPITAL,
1018 ui::EF_CAPS_LOCK_DOWN,
1019 ui::ET_KEY_PRESSED));
1020
1021 // Confirm that calling RewriteForTesting() does not change the state of
1022 // |ime_keyboard|. In this case, X Window system itself should change the
1023 // Caps Lock state, not ash::EventRewriter.
1024 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
1025
1026 // Release Caps Lock (on an external keyboard).
1027 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
1028 ui::EF_NONE,
1029 ui::ET_KEY_RELEASED),
1030 GetRewrittenEventAsString(&rewriter,
1031 ui::VKEY_CAPITAL,
1032 ui::EF_NONE,
1033 ui::ET_KEY_RELEASED));
1034 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
1035 }
1036
1037 TEST_F(KeyboardEventRewriterTest, TestRewriteCapsLock) {
1038 TestingPrefServiceSyncable prefs;
1039 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1040
1041 chromeos::input_method::FakeImeKeyboard ime_keyboard;
1042 KeyboardEventRewriter rewriter;
1043 rewriter.set_pref_service_for_testing(&prefs);
1044 rewriter.set_ime_keyboard_for_testing(&ime_keyboard);
1045 EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
1046
1047 // On Chrome OS, CapsLock is mapped to F16 with Mod3Mask.
1048 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
1049 ui::EF_CAPS_LOCK_DOWN,
1050 ui::ET_KEY_PRESSED),
1051 GetRewrittenEventAsString(&rewriter,
1052 ui::VKEY_F16,
1053 ui::EF_NONE,
1054 ui::ET_KEY_PRESSED));
1055 EXPECT_TRUE(ime_keyboard.caps_lock_is_enabled_);
1056 }
1057
1058 TEST_F(KeyboardEventRewriterTest, TestRewriteDiamondKey) {
1059 TestingPrefServiceSyncable prefs;
1060 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1061
1062 chromeos::input_method::FakeImeKeyboard ime_keyboard;
1063 KeyboardEventRewriter rewriter;
1064 rewriter.set_pref_service_for_testing(&prefs);
1065 rewriter.set_ime_keyboard_for_testing(&ime_keyboard);
1066
1067 // F15 should work as Ctrl when --has-chromeos-diamond-key is not specified.
1068 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
1069 ui::EF_CONTROL_DOWN,
1070 ui::ET_KEY_PRESSED),
1071 GetRewrittenEventAsString(&rewriter,
1072 ui::VKEY_F15,
1073 ui::EF_NONE,
1074 ui::ET_KEY_PRESSED));
1075
1076 // However, Mod2Mask should not be rewritten to CtrlMask when
1077 // --has-chromeos-diamond-key is not specified.
1078 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
1079 ui::EF_NONE,
1080 ui::ET_KEY_PRESSED),
1081 GetRewrittenEventAsString(&rewriter,
1082 ui::VKEY_A,
1083 ui::EF_NONE,
1084 ui::ET_KEY_PRESSED));
1085 }
1086
1087 TEST_F(KeyboardEventRewriterTest, TestRewriteDiamondKeyWithFlag) {
1088 const CommandLine original_cl(*CommandLine::ForCurrentProcess());
1089 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1090 chromeos::switches::kHasChromeOSDiamondKey, "");
1091
1092 TestingPrefServiceSyncable prefs;
1093 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1094
1095 chromeos::input_method::FakeImeKeyboard ime_keyboard;
1096 KeyboardEventRewriter rewriter;
1097 rewriter.set_pref_service_for_testing(&prefs);
1098 rewriter.set_ime_keyboard_for_testing(&ime_keyboard);
1099
1100 // By default, F15 should work as Control.
1101 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
1102 ui::EF_CONTROL_DOWN,
1103 ui::ET_KEY_PRESSED),
1104 GetRewrittenEventAsString(&rewriter,
1105 ui::VKEY_F15,
1106 ui::EF_NONE,
1107 ui::ET_KEY_PRESSED));
1108
1109 IntegerPrefMember diamond;
1110 diamond.Init(prefs::kLanguageRemapDiamondKeyTo, &prefs);
1111 diamond.SetValue(chromeos::input_method::kVoidKey);
1112
1113 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_UNKNOWN,
1114 ui::EF_NONE,
1115 ui::ET_KEY_PRESSED),
1116 GetRewrittenEventAsString(&rewriter,
1117 ui::VKEY_F15,
1118 ui::EF_NONE,
1119 ui::ET_KEY_PRESSED));
1120
1121 diamond.SetValue(chromeos::input_method::kControlKey);
1122
1123 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
1124 ui::EF_CONTROL_DOWN,
1125 ui::ET_KEY_PRESSED),
1126 GetRewrittenEventAsString(&rewriter,
1127 ui::VKEY_F15,
1128 ui::EF_NONE,
1129 ui::ET_KEY_PRESSED));
1130
1131 diamond.SetValue(chromeos::input_method::kAltKey);
1132
1133 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
1134 ui::EF_ALT_DOWN,
1135 ui::ET_KEY_PRESSED),
1136 GetRewrittenEventAsString(&rewriter,
1137 ui::VKEY_F15,
1138 ui::EF_NONE,
1139 ui::ET_KEY_PRESSED));
1140
1141 diamond.SetValue(chromeos::input_method::kCapsLockKey);
1142
1143 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
1144 ui::EF_CAPS_LOCK_DOWN,
1145 ui::ET_KEY_PRESSED),
1146 GetRewrittenEventAsString(&rewriter,
1147 ui::VKEY_F15,
1148 ui::EF_NONE,
1149 ui::ET_KEY_PRESSED));
1150
1151 *CommandLine::ForCurrentProcess() = original_cl;
1152 }
1153
1154 TEST_F(KeyboardEventRewriterTest, TestRewriteCapsLockToControl) {
1155 // Remap CapsLock to Control.
1156 TestingPrefServiceSyncable prefs;
1157 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1158 IntegerPrefMember control;
1159 control.Init(prefs::kLanguageRemapCapsLockKeyTo, &prefs);
1160 control.SetValue(chromeos::input_method::kControlKey);
1161
1162 KeyboardEventRewriter rewriter;
1163 rewriter.set_pref_service_for_testing(&prefs);
1164
1165 // Press CapsLock+a. Confirm that Mod3Mask is rewritten to ControlMask.
1166 // On Chrome OS, CapsLock works as a Mod3 modifier.
1167 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
1168 ui::EF_CONTROL_DOWN,
1169 ui::ET_KEY_PRESSED),
1170 GetRewrittenEventAsString(&rewriter,
1171 ui::VKEY_A,
1172 ui::EF_CAPS_LOCK_DOWN,
1173 ui::ET_KEY_PRESSED));
1174
1175 // Press Control+CapsLock+a. Confirm that Mod3Mask is rewritten to ControlMask
1176 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
1177 ui::EF_CONTROL_DOWN,
1178 ui::ET_KEY_PRESSED),
1179 GetRewrittenEventAsString(&rewriter,
1180 ui::VKEY_A,
1181 ui::EF_CONTROL_DOWN,
1182 ui::ET_KEY_PRESSED));
1183
1184 // Press Alt+CapsLock+a. Confirm that Mod3Mask is rewritten to ControlMask.
1185 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
1186 ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
1187 ui::ET_KEY_PRESSED),
1188 GetRewrittenEventAsString(&rewriter,
1189 ui::VKEY_A,
1190 ui::EF_ALT_DOWN | ui::EF_CAPS_LOCK_DOWN,
1191 ui::ET_KEY_PRESSED));
1192 }
1193
1194 TEST_F(KeyboardEventRewriterTest, TestRewriteCapsLockMod3InUse) {
1195 // Remap CapsLock to Control.
1196 TestingPrefServiceSyncable prefs;
1197 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1198 IntegerPrefMember control;
1199 control.Init(prefs::kLanguageRemapCapsLockKeyTo, &prefs);
1200 control.SetValue(chromeos::input_method::kControlKey);
1201
1202 KeyboardEventRewriter rewriter;
1203 rewriter.set_pref_service_for_testing(&prefs);
1204 input_method_manager_mock_->set_mod3_used(true);
1205
1206 // Press CapsLock+a. Confirm that Mod3Mask is NOT rewritten to ControlMask
1207 // when Mod3Mask is already in use by the current XKB layout.
1208 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
1209 ui::EF_NONE,
1210 ui::ET_KEY_PRESSED),
1211 GetRewrittenEventAsString(&rewriter,
1212 ui::VKEY_A,
1213 ui::EF_NONE,
1214 ui::ET_KEY_PRESSED));
1215
1216 input_method_manager_mock_->set_mod3_used(false);
1217 }
1218
1219 TEST_F(KeyboardEventRewriterTest, TestRewriteExtendedKeys) {
1220 TestingPrefServiceSyncable prefs;
1221 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1222 KeyboardEventRewriter rewriter;
1223 rewriter.DeviceAddedForTesting(0, "PC Keyboard");
1224 rewriter.set_last_device_id_for_testing(0);
1225 rewriter.set_pref_service_for_testing(&prefs);
1226
1227 struct {
1228 ui::KeyboardCode input;
1229 unsigned int input_mods;
1230 ui::KeyboardCode output;
1231 unsigned int output_mods;
1232 } chromeos_tests[] = {
1233 // Alt+Backspace -> Delete
1234 { ui::VKEY_BACK,
1235 ui::EF_ALT_DOWN,
1236 ui::VKEY_DELETE,
1237 ui::EF_NONE },
1238 // Control+Alt+Backspace -> Control+Delete
1239 { ui::VKEY_BACK,
1240 ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
1241 ui::VKEY_DELETE,
1242 ui::EF_CONTROL_DOWN },
1243 // Search+Alt+Backspace -> Alt+Backspace
1244 { ui::VKEY_BACK,
1245 ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
1246 ui::VKEY_BACK,
1247 ui::EF_ALT_DOWN },
1248 // Search+Control+Alt+Backspace -> Control+Alt+Backspace
1249 { ui::VKEY_BACK,
1250 ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
1251 ui::VKEY_BACK,
1252 ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN },
1253 // Alt+Up -> Prior
1254 { ui::VKEY_UP,
1255 ui::EF_ALT_DOWN,
1256 ui::VKEY_PRIOR,
1257 ui::EF_NONE },
1258 // Alt+Down -> Next
1259 { ui::VKEY_DOWN,
1260 ui::EF_ALT_DOWN,
1261 ui::VKEY_NEXT,
1262 ui::EF_NONE },
1263 // Ctrl+Alt+Up -> Home
1264 { ui::VKEY_UP,
1265 ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
1266 ui::VKEY_HOME,
1267 ui::EF_NONE },
1268 // Ctrl+Alt+Down -> End
1269 { ui::VKEY_DOWN,
1270 ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
1271 ui::VKEY_END,
1272 ui::EF_NONE },
1273
1274 // Search+Alt+Up -> Alt+Up
1275 { ui::VKEY_UP,
1276 ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
1277 ui::VKEY_UP,
1278 ui::EF_ALT_DOWN },
1279 // Search+Alt+Down -> Alt+Down
1280 { ui::VKEY_DOWN,
1281 ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
1282 ui::VKEY_DOWN,
1283 ui::EF_ALT_DOWN },
1284 // Search+Ctrl+Alt+Up -> Search+Ctrl+Alt+Up
1285 { ui::VKEY_UP,
1286 ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
1287 ui::VKEY_UP,
1288 ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN },
1289 // Search+Ctrl+Alt+Down -> Ctrl+Alt+Down
1290 { ui::VKEY_DOWN,
1291 ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
1292 ui::VKEY_DOWN,
1293 ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN },
1294
1295 // Period -> Period
1296 { ui::VKEY_OEM_PERIOD,
1297 ui::EF_NONE,
1298 ui::VKEY_OEM_PERIOD,
1299 ui::EF_NONE },
1300
1301 // Search+Backspace -> Delete
1302 { ui::VKEY_BACK,
1303 ui::EF_COMMAND_DOWN,
1304 ui::VKEY_DELETE,
1305 ui::EF_NONE },
1306 // Search+Up -> Prior
1307 { ui::VKEY_UP,
1308 ui::EF_COMMAND_DOWN,
1309 ui::VKEY_PRIOR,
1310 ui::EF_NONE },
1311 // Search+Down -> Next
1312 { ui::VKEY_DOWN,
1313 ui::EF_COMMAND_DOWN,
1314 ui::VKEY_NEXT,
1315 ui::EF_NONE },
1316 // Search+Left -> Home
1317 { ui::VKEY_LEFT,
1318 ui::EF_COMMAND_DOWN,
1319 ui::VKEY_HOME,
1320 ui::EF_NONE },
1321 // Control+Search+Left -> Home
1322 { ui::VKEY_LEFT,
1323 ui::EF_COMMAND_DOWN | ui::EF_CONTROL_DOWN,
1324 ui::VKEY_HOME,
1325 ui::EF_CONTROL_DOWN },
1326 // Search+Right -> End
1327 { ui::VKEY_RIGHT,
1328 ui::EF_COMMAND_DOWN,
1329 ui::VKEY_END,
1330 ui::EF_NONE },
1331 // Control+Search+Right -> End
1332 { ui::VKEY_RIGHT,
1333 ui::EF_COMMAND_DOWN | ui::EF_CONTROL_DOWN,
1334 ui::VKEY_END,
1335 ui::EF_CONTROL_DOWN },
1336 // Search+Period -> Insert
1337 { ui::VKEY_OEM_PERIOD,
1338 ui::EF_COMMAND_DOWN,
1339 ui::VKEY_INSERT,
1340 ui::EF_NONE },
1341 // Control+Search+Period -> Control+Insert
1342 { ui::VKEY_OEM_PERIOD,
1343 ui::EF_COMMAND_DOWN | ui::EF_CONTROL_DOWN,
1344 ui::VKEY_INSERT,
1345 ui::EF_CONTROL_DOWN }
1346 };
1347
1348 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(chromeos_tests); ++i) {
1349 EXPECT_EQ(GetExpectedResultNumbered(i,
1350 chromeos_tests[i].output,
1351 chromeos_tests[i].output_mods,
1352 ui::ET_KEY_PRESSED),
1353 GetRewrittenEventNumbered(i,
1354 &rewriter,
1355 chromeos_tests[i].input,
1356 chromeos_tests[i].input_mods,
1357 ui::ET_KEY_PRESSED));
1358 }
1359 }
1360
1361 TEST_F(KeyboardEventRewriterTest, TestRewriteFunctionKeys) {
1362 TestingPrefServiceSyncable prefs;
1363 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1364 KeyboardEventRewriter rewriter;
1365 // XXX rewriter.DeviceAddedForTesting(0, "PC Keyboard");
1366 // XXX rewriter.set_last_device_id_for_testing(0);
1367 rewriter.set_pref_service_for_testing(&prefs);
1368
1369 struct {
1370 ui::KeyboardCode input;
1371 unsigned int input_mods;
1372 ui::KeyboardCode output;
1373 unsigned int output_mods;
1374 } tests[] = {
1375 // F1 -> Back
1376 { ui::VKEY_F1,
1377 ui::EF_NONE,
1378 ui::VKEY_BROWSER_BACK,
1379 ui::EF_NONE },
1380 { ui::VKEY_F1,
1381 ui::EF_CONTROL_DOWN,
1382 ui::VKEY_BROWSER_BACK,
1383 ui::EF_CONTROL_DOWN },
1384 { ui::VKEY_F1,
1385 ui::EF_ALT_DOWN,
1386 ui::VKEY_BROWSER_BACK,
1387 ui::EF_ALT_DOWN },
1388 // F2 -> Forward
1389 { ui::VKEY_F2,
1390 ui::EF_NONE,
1391 ui::VKEY_BROWSER_FORWARD,
1392 ui::EF_NONE },
1393 { ui::VKEY_F2,
1394 ui::EF_CONTROL_DOWN,
1395 ui::VKEY_BROWSER_FORWARD,
1396 ui::EF_CONTROL_DOWN },
1397 { ui::VKEY_F2,
1398 ui::EF_ALT_DOWN,
1399 ui::VKEY_BROWSER_FORWARD,
1400 ui::EF_ALT_DOWN },
1401 // F3 -> Refresh
1402 { ui::VKEY_F3,
1403 ui::EF_NONE,
1404 ui::VKEY_BROWSER_REFRESH,
1405 ui::EF_NONE },
1406 { ui::VKEY_F3,
1407 ui::EF_CONTROL_DOWN,
1408 ui::VKEY_BROWSER_REFRESH,
1409 ui::EF_CONTROL_DOWN },
1410 { ui::VKEY_F3,
1411 ui::EF_ALT_DOWN,
1412 ui::VKEY_BROWSER_REFRESH,
1413 ui::EF_ALT_DOWN },
1414 // F4 -> Launch App 2
1415 { ui::VKEY_F4,
1416 ui::EF_NONE,
1417 ui::VKEY_MEDIA_LAUNCH_APP2,
1418 ui::EF_NONE },
1419 { ui::VKEY_F4,
1420 ui::EF_CONTROL_DOWN,
1421 ui::VKEY_MEDIA_LAUNCH_APP2,
1422 ui::EF_CONTROL_DOWN },
1423 { ui::VKEY_F4,
1424 ui::EF_ALT_DOWN,
1425 ui::VKEY_MEDIA_LAUNCH_APP2,
1426 ui::EF_ALT_DOWN },
1427 // F5 -> Launch App 1
1428 { ui::VKEY_F5,
1429 ui::EF_NONE,
1430 ui::VKEY_MEDIA_LAUNCH_APP1,
1431 ui::EF_NONE },
1432 { ui::VKEY_F5,
1433 ui::EF_CONTROL_DOWN,
1434 ui::VKEY_MEDIA_LAUNCH_APP1,
1435 ui::EF_CONTROL_DOWN },
1436 { ui::VKEY_F5,
1437 ui::EF_ALT_DOWN,
1438 ui::VKEY_MEDIA_LAUNCH_APP1,
1439 ui::EF_ALT_DOWN },
1440 // F6 -> Brightness down
1441 { ui::VKEY_F6,
1442 ui::EF_NONE,
1443 ui::VKEY_BRIGHTNESS_DOWN,
1444 ui::EF_NONE },
1445 { ui::VKEY_F6,
1446 ui::EF_CONTROL_DOWN,
1447 ui::VKEY_BRIGHTNESS_DOWN,
1448 ui::EF_CONTROL_DOWN },
1449 { ui::VKEY_F6,
1450 ui::EF_ALT_DOWN,
1451 ui::VKEY_BRIGHTNESS_DOWN,
1452 ui::EF_ALT_DOWN },
1453 // F7 -> Brightness up
1454 { ui::VKEY_F7,
1455 ui::EF_NONE,
1456 ui::VKEY_BRIGHTNESS_UP,
1457 ui::EF_NONE },
1458 { ui::VKEY_F7,
1459 ui::EF_CONTROL_DOWN,
1460 ui::VKEY_BRIGHTNESS_UP,
1461 ui::EF_CONTROL_DOWN },
1462 { ui::VKEY_F7,
1463 ui::EF_ALT_DOWN,
1464 ui::VKEY_BRIGHTNESS_UP,
1465 ui::EF_ALT_DOWN },
1466 // F8 -> Volume Mute
1467 { ui::VKEY_F8,
1468 ui::EF_NONE,
1469 ui::VKEY_VOLUME_MUTE,
1470 ui::EF_NONE },
1471 { ui::VKEY_F8,
1472 ui::EF_CONTROL_DOWN,
1473 ui::VKEY_VOLUME_MUTE,
1474 ui::EF_CONTROL_DOWN },
1475 { ui::VKEY_F8,
1476 ui::EF_ALT_DOWN,
1477 ui::VKEY_VOLUME_MUTE,
1478 ui::EF_ALT_DOWN },
1479 // F9 -> Volume Down
1480 { ui::VKEY_F9,
1481 ui::EF_NONE,
1482 ui::VKEY_VOLUME_DOWN,
1483 ui::EF_NONE },
1484 { ui::VKEY_F9,
1485 ui::EF_CONTROL_DOWN,
1486 ui::VKEY_VOLUME_DOWN,
1487 ui::EF_CONTROL_DOWN },
1488 { ui::VKEY_F9,
1489 ui::EF_ALT_DOWN,
1490 ui::VKEY_VOLUME_DOWN,
1491 ui::EF_ALT_DOWN },
1492 // F10 -> Volume Up
1493 { ui::VKEY_F10,
1494 ui::EF_NONE,
1495 ui::VKEY_VOLUME_UP,
1496 ui::EF_NONE },
1497 { ui::VKEY_F10,
1498 ui::EF_CONTROL_DOWN,
1499 ui::VKEY_VOLUME_UP,
1500 ui::EF_CONTROL_DOWN },
1501 { ui::VKEY_F10,
1502 ui::EF_ALT_DOWN,
1503 ui::VKEY_VOLUME_UP,
1504 ui::EF_ALT_DOWN },
1505 // F11 -> F11
1506 { ui::VKEY_F11,
1507 ui::EF_NONE,
1508 ui::VKEY_F11,
1509 ui::EF_NONE },
1510 { ui::VKEY_F11,
1511 ui::EF_CONTROL_DOWN,
1512 ui::VKEY_F11,
1513 ui::EF_CONTROL_DOWN },
1514 { ui::VKEY_F11,
1515 ui::EF_ALT_DOWN,
1516 ui::VKEY_F11,
1517 ui::EF_ALT_DOWN },
1518 // F12 -> F12
1519 { ui::VKEY_F12,
1520 ui::EF_NONE,
1521 ui::VKEY_F12,
1522 ui::EF_NONE },
1523 { ui::VKEY_F12,
1524 ui::EF_CONTROL_DOWN,
1525 ui::VKEY_F12,
1526 ui::EF_CONTROL_DOWN },
1527 { ui::VKEY_F12,
1528 ui::EF_ALT_DOWN,
1529 ui::VKEY_F12,
1530 ui::EF_ALT_DOWN },
1531
1532 // The number row should not be rewritten without Search key.
1533 { ui::VKEY_1,
1534 ui::EF_NONE,
1535 ui::VKEY_1,
1536 ui::EF_NONE },
1537 { ui::VKEY_2,
1538 ui::EF_NONE,
1539 ui::VKEY_2,
1540 ui::EF_NONE },
1541 { ui::VKEY_3,
1542 ui::EF_NONE,
1543 ui::VKEY_3,
1544 ui::EF_NONE },
1545 { ui::VKEY_4,
1546 ui::EF_NONE,
1547 ui::VKEY_4,
1548 ui::EF_NONE },
1549 { ui::VKEY_5,
1550 ui::EF_NONE,
1551 ui::VKEY_5,
1552 ui::EF_NONE },
1553 { ui::VKEY_6,
1554 ui::EF_NONE,
1555 ui::VKEY_6,
1556 ui::EF_NONE },
1557 { ui::VKEY_7,
1558 ui::EF_NONE,
1559 ui::VKEY_7,
1560 ui::EF_NONE },
1561 { ui::VKEY_8,
1562 ui::EF_NONE,
1563 ui::VKEY_8,
1564 ui::EF_NONE },
1565 { ui::VKEY_9,
1566 ui::EF_NONE,
1567 ui::VKEY_9,
1568 ui::EF_NONE },
1569 { ui::VKEY_0,
1570 ui::EF_NONE,
1571 ui::VKEY_0,
1572 ui::EF_NONE },
1573 { ui::VKEY_OEM_MINUS,
1574 ui::EF_NONE,
1575 ui::VKEY_OEM_MINUS,
1576 ui::EF_NONE },
1577 { ui::VKEY_OEM_PLUS,
1578 ui::EF_NONE,
1579 ui::VKEY_OEM_PLUS,
1580 ui::EF_NONE },
1581
1582 // The number row should be rewritten as the F<number> row with Search key.
1583 { ui::VKEY_1,
1584 ui::EF_COMMAND_DOWN,
1585 ui::VKEY_F1,
1586 ui::EF_NONE },
1587 { ui::VKEY_2,
1588 ui::EF_COMMAND_DOWN,
1589 ui::VKEY_F2,
1590 ui::EF_NONE },
1591 { ui::VKEY_3,
1592 ui::EF_COMMAND_DOWN,
1593 ui::VKEY_F3,
1594 ui::EF_NONE },
1595 { ui::VKEY_4,
1596 ui::EF_COMMAND_DOWN,
1597 ui::VKEY_F4,
1598 ui::EF_NONE },
1599 { ui::VKEY_5,
1600 ui::EF_COMMAND_DOWN,
1601 ui::VKEY_F5,
1602 ui::EF_NONE },
1603 { ui::VKEY_6,
1604 ui::EF_COMMAND_DOWN,
1605 ui::VKEY_F6,
1606 ui::EF_NONE },
1607 { ui::VKEY_7,
1608 ui::EF_COMMAND_DOWN,
1609 ui::VKEY_F7,
1610 ui::EF_NONE },
1611 { ui::VKEY_8,
1612 ui::EF_COMMAND_DOWN,
1613 ui::VKEY_F8,
1614 ui::EF_NONE },
1615 { ui::VKEY_9,
1616 ui::EF_COMMAND_DOWN,
1617 ui::VKEY_F9,
1618 ui::EF_NONE },
1619 { ui::VKEY_0,
1620 ui::EF_COMMAND_DOWN,
1621 ui::VKEY_F10,
1622 ui::EF_NONE },
1623 { ui::VKEY_OEM_MINUS,
1624 ui::EF_COMMAND_DOWN,
1625 ui::VKEY_F11,
1626 ui::EF_NONE },
1627 { ui::VKEY_OEM_PLUS,
1628 ui::EF_COMMAND_DOWN,
1629 ui::VKEY_F12,
1630 ui::EF_NONE },
1631
1632 // The function keys should not be rewritten with Search key pressed.
1633 { ui::VKEY_F1,
1634 ui::EF_COMMAND_DOWN,
1635 ui::VKEY_F1,
1636 ui::EF_NONE },
1637 { ui::VKEY_F2,
1638 ui::EF_COMMAND_DOWN,
1639 ui::VKEY_F2,
1640 ui::EF_NONE },
1641 { ui::VKEY_F3,
1642 ui::EF_COMMAND_DOWN,
1643 ui::VKEY_F3,
1644 ui::EF_NONE },
1645 { ui::VKEY_F4,
1646 ui::EF_COMMAND_DOWN,
1647 ui::VKEY_F4,
1648 ui::EF_NONE },
1649 { ui::VKEY_F5,
1650 ui::EF_COMMAND_DOWN,
1651 ui::VKEY_F5,
1652 ui::EF_NONE },
1653 { ui::VKEY_F6,
1654 ui::EF_COMMAND_DOWN,
1655 ui::VKEY_F6,
1656 ui::EF_NONE },
1657 { ui::VKEY_F7,
1658 ui::EF_COMMAND_DOWN,
1659 ui::VKEY_F7,
1660 ui::EF_NONE },
1661 { ui::VKEY_F8,
1662 ui::EF_COMMAND_DOWN,
1663 ui::VKEY_F8,
1664 ui::EF_NONE },
1665 { ui::VKEY_F9,
1666 ui::EF_COMMAND_DOWN,
1667 ui::VKEY_F9,
1668 ui::EF_NONE },
1669 { ui::VKEY_F10,
1670 ui::EF_COMMAND_DOWN,
1671 ui::VKEY_F10,
1672 ui::EF_NONE },
1673 { ui::VKEY_F11,
1674 ui::EF_COMMAND_DOWN,
1675 ui::VKEY_F11,
1676 ui::EF_NONE },
1677 { ui::VKEY_F12,
1678 ui::EF_COMMAND_DOWN,
1679 ui::VKEY_F12,
1680 ui::EF_NONE },
1681 };
1682
1683 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
1684 EXPECT_EQ(GetExpectedResultNumbered(i,
1685 tests[i].output,
1686 tests[i].output_mods,
1687 ui::ET_KEY_PRESSED),
1688 GetRewrittenEventNumbered(i,
1689 &rewriter,
1690 tests[i].input,
1691 tests[i].input_mods,
1692 ui::ET_KEY_PRESSED));
1693 }
1694 }
1695
1696 TEST_F(KeyboardEventRewriterTest, TestRewriteExtendedKeysWithSearchRemapped) {
1697 const CommandLine original_cl(*CommandLine::ForCurrentProcess());
1698
1699 // Remap Search to Control.
1700 TestingPrefServiceSyncable prefs;
1701 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1702 IntegerPrefMember search;
1703 search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
1704 search.SetValue(chromeos::input_method::kControlKey);
1705
1706 KeyboardEventRewriter rewriter;
1707 rewriter.set_pref_service_for_testing(&prefs);
1708
1709 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1710 chromeos::switches::kHasChromeOSKeyboard, "");
1711
1712 // Alt+Search+Down -> End
1713 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_END,
1714 ui::EF_NONE,
1715 ui::ET_KEY_PRESSED),
1716 GetRewrittenEventAsString(&rewriter,
1717 ui::VKEY_DOWN,
1718 ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
1719 ui::ET_KEY_PRESSED));
1720
1721 // Shift+Alt+Search+Down -> Shift+End
1722 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_END,
1723 ui::EF_SHIFT_DOWN,
1724 ui::ET_KEY_PRESSED),
1725 GetRewrittenEventAsString(&rewriter,
1726 ui::VKEY_DOWN,
1727 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN |
1728 ui::EF_COMMAND_DOWN,
1729 ui::ET_KEY_PRESSED));
1730
1731 *CommandLine::ForCurrentProcess() = original_cl;
1732 }
1733
1734 TEST_F(KeyboardEventRewriterTest, TestRewriteKeyEventSentByXSendEvent) {
1735 // Remap Control to Alt.
1736 TestingPrefServiceSyncable prefs;
1737 chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
1738 IntegerPrefMember control;
1739 control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
1740 control.SetValue(chromeos::input_method::kAltKey);
1741
1742 KeyboardEventRewriter rewriter;
1743 rewriter.set_pref_service_for_testing(&prefs);
1744
1745 // Send left control press.
1746 std::string rewritten_event;
1747 {
1748 ui::ScopedXI2Event xev;
1749 xev.InitKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_CONTROL, 0);
1750 XEvent* xevent = xev;
1751 xevent->xkey.keycode = XKeysymToKeycode(gfx::GetXDisplay(), XK_Control_L);
1752 xevent->xkey.send_event = True; // XSendEvent() always does this.
1753 ui::KeyEvent keyevent(xev, false /* is_char */);
1754 scoped_ptr<ui::Event> new_event;
1755 rewriter.RewriteEvent(&keyevent, &new_event);
1756 rewritten_event = base::StringPrintf(
1757 "ui_keycode=0x%X ui_flags=0x%X ui_type=%d",
1758 keyevent.key_code(), keyevent.flags(), keyevent.type());
1759 }
1760
1761 // Control should NOT be remapped to Alt if send_event
1762 // flag in the event is True.
1763 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
1764 ui::EF_CONTROL_DOWN,
1765 ui::ET_KEY_PRESSED),
1766 rewritten_event);
1767 }
1768
1769 // Tests of event rewriting that depend on the Ash window manager.
1770 class KeyboardEventRewriterAshTest : public ash::test::AshTestBase {
1771 public:
1772 KeyboardEventRewriterAshTest()
1773 : mock_user_manager_(new chromeos::MockUserManager),
1774 user_manager_enabler_(mock_user_manager_) {
1775 }
1776 virtual ~KeyboardEventRewriterAshTest() {}
1777
1778 bool RewriteFunctionKeys(ui::Event* event) {
1779 scoped_ptr<ui::Event> new_event;
1780 return rewriter_->RewriteEvent(event, &new_event);
1781 }
1782
1783 protected:
1784 virtual void SetUp() OVERRIDE {
1785 AshTestBase::SetUp();
1786 rewriter_.reset(new KeyboardEventRewriter());
1787 chromeos::Preferences::RegisterProfilePrefs(prefs_.registry());
1788 rewriter_->set_pref_service_for_testing(&prefs_);
1789 }
1790
1791 virtual void TearDown() OVERRIDE {
1792 rewriter_.reset();
1793 AshTestBase::TearDown();
1794 }
1795
1796 TestingPrefServiceSyncable prefs_;
1797
1798 private:
1799 scoped_ptr<KeyboardEventRewriter> rewriter_;
1800
1801 chromeos::MockUserManager* mock_user_manager_; // Not owned.
1802 chromeos::ScopedUserManagerEnabler user_manager_enabler_;
1803
1804 DISALLOW_COPY_AND_ASSIGN(KeyboardEventRewriterAshTest);
1805 };
1806
1807 TEST_F(KeyboardEventRewriterAshTest, TopRowKeysAreFunctionKeys) {
1808 scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(1));
1809 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window.get());
1810 window_state->Activate();
1811
1812 // Create a simulated keypress of F1 targetted at the window.
1813 ui::KeyEvent press_f1(ui::ET_KEY_PRESSED, ui::VKEY_F1, 0, false);
1814
1815 // Simulate an apps v2 window that has requested top row keys as function
1816 // keys. The event should not be rewritten.
1817 window_state->set_top_row_keys_are_function_keys(true);
1818 ASSERT_FALSE(RewriteFunctionKeys(&press_f1));
1819 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_F1,
1820 ui::EF_NONE,
1821 ui::ET_KEY_PRESSED),
1822 GetKeyEventAsString(press_f1));
1823
1824 // The event should also not be rewritten if the send-function-keys pref is
1825 // additionally set, for both apps v2 and regular windows.
1826 BooleanPrefMember send_function_keys_pref;
1827 send_function_keys_pref.Init(prefs::kLanguageSendFunctionKeys, &prefs_);
1828 send_function_keys_pref.SetValue(true);
1829 window_state->set_top_row_keys_are_function_keys(false);
1830 ASSERT_FALSE(RewriteFunctionKeys(&press_f1));
1831 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_F1,
1832 ui::EF_NONE,
1833 ui::ET_KEY_PRESSED),
1834 GetKeyEventAsString(press_f1));
1835
1836 // If the pref isn't set when an event is sent to a regular window, F1 is
1837 // rewritten to the back key.
1838 send_function_keys_pref.SetValue(false);
1839 ASSERT_TRUE(RewriteFunctionKeys(&press_f1));
1840 EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_BROWSER_BACK,
1841 ui::EF_NONE,
1842 ui::ET_KEY_PRESSED),
1843 GetKeyEventAsString(press_f1));
1844 }
1845
1846 TEST_F(KeyboardEventRewriterTest, DontRewriteIfNotRewritten) {
1847 std::vector<unsigned int> device_list;
1848 device_list.push_back(10);
1849 device_list.push_back(11);
1850 ui::TouchFactory::GetInstance()->SetPointerDeviceForTest(device_list);
1851 TestingPrefServiceSyncable prefs;
1852 KeyboardEventRewriter rewriter;
1853 rewriter.set_pref_service_for_testing(&prefs);
1854 const int kLeftAndAltFlag = ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN;
1855 {
1856 ui::ScopedXI2Event xev;
1857 xev.InitGenericButtonEvent(
1858 10, ui::ET_MOUSE_PRESSED, gfx::Point(), kLeftAndAltFlag);
1859 ui::MouseEvent press(xev);
1860 // Sanity check.
1861 EXPECT_EQ(ui::ET_MOUSE_PRESSED, press.type());
1862 EXPECT_EQ(kLeftAndAltFlag, press.flags());
1863
1864 RewriteMouseEvent(&rewriter, &press);
1865
1866 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & press.flags());
1867 }
1868 {
1869 ui::ScopedXI2Event xev;
1870 xev.InitGenericButtonEvent(
1871 10, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
1872 ui::MouseEvent release(xev);
1873 RewriteMouseEvent(&rewriter, &release);
1874 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & release.flags());
1875 }
1876
1877 // No ALT in frst click.
1878 {
1879 ui::ScopedXI2Event xev;
1880 xev.InitGenericButtonEvent(
1881 10, ui::ET_MOUSE_PRESSED, gfx::Point(), ui::EF_LEFT_MOUSE_BUTTON);
1882 ui::MouseEvent press(xev);
1883 RewriteMouseEvent(&rewriter, &press);
1884 EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & press.flags());
1885 }
1886 {
1887 ui::ScopedXI2Event xev;
1888 xev.InitGenericButtonEvent(
1889 10, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
1890 ui::MouseEvent release(xev);
1891 RewriteMouseEvent(&rewriter, &release);
1892 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN) &
1893 release.flags());
1894 }
1895
1896 // ALT on different device.
1897 {
1898 ui::ScopedXI2Event xev;
1899 xev.InitGenericButtonEvent(
1900 11, ui::ET_MOUSE_PRESSED, gfx::Point(), kLeftAndAltFlag);
1901 ui::MouseEvent press(xev);
1902 RewriteMouseEvent(&rewriter, &press);
1903 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & press.flags());
1904 }
1905 {
1906 ui::ScopedXI2Event xev;
1907 xev.InitGenericButtonEvent(
1908 10, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
1909 ui::MouseEvent release(xev);
1910 RewriteMouseEvent(&rewriter, &release);
1911 EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN) &
1912 release.flags());
1913 }
1914 {
1915 ui::ScopedXI2Event xev;
1916 xev.InitGenericButtonEvent(
1917 11, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
1918 ui::MouseEvent release(xev);
1919 RewriteMouseEvent(&rewriter, &release);
1920 EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & release.flags());
1921 }
1922 }
1923
1924 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698