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