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