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