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