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