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