OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/extension_apitest.h" | 5 #include "chrome/browser/extensions/extension_apitest.h" |
6 #include "chrome/browser/extensions/window_controller.h" | 6 #include "chrome/browser/extensions/window_controller.h" |
7 #include "chrome/browser/ui/browser_window.h" | 7 #include "chrome/browser/ui/browser_window.h" |
8 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 8 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
9 #include "chrome/test/base/interactive_test_utils.h" | 9 #include "chrome/test/base/interactive_test_utils.h" |
10 #include "content/public/test/browser_test_utils.h" | 10 #include "content/public/test/browser_test_utils.h" |
11 #include "ui/base/base_window.h" | 11 #include "ui/base/base_window.h" |
12 | 12 |
13 #if defined(OS_LINUX) | 13 #if defined(OS_LINUX) |
14 #include <X11/Xlib.h> | 14 #include <X11/Xlib.h> |
15 #include <X11/extensions/XTest.h> | 15 #include <X11/extensions/XTest.h> |
16 #include <X11/keysym.h> | 16 #include <X11/keysym.h> |
17 | 17 |
18 #include "ui/events/keycodes/keyboard_code_conversion_x.h" | 18 #include "ui/events/keycodes/keyboard_code_conversion_x.h" |
19 #include "ui/gfx/x/x11_types.h" | 19 #include "ui/gfx/x/x11_types.h" |
| 20 #elif defined(OS_WIN) |
| 21 #include "ui/events/keycodes/keyboard_code_conversion_win.h" |
20 #endif | 22 #endif |
21 | 23 |
22 namespace extensions { | 24 namespace extensions { |
23 | 25 |
24 typedef ExtensionApiTest GlobalCommandsApiTest; | 26 typedef ExtensionApiTest GlobalCommandsApiTest; |
25 | 27 |
26 #if defined(OS_LINUX) | 28 #if defined(OS_LINUX) |
27 // Send a simulated key press and release event, where |control|, |shift| or | 29 // Send a simulated key press and release event, where |control|, |shift| or |
28 // |alt| indicates whether the key is struck with corresponding modifier. | 30 // |alt| indicates whether the key is struck with corresponding modifier. |
29 void SendNativeKeyEventToXDisplay(ui::KeyboardCode key, | 31 void SendNativeKeyEventToXDisplay(ui::KeyboardCode key, |
(...skipping 29 matching lines...) Expand all Loading... |
59 XTestFakeKeyEvent(display, *it, True, CurrentTime); | 61 XTestFakeKeyEvent(display, *it, True, CurrentTime); |
60 | 62 |
61 // Simulate the keys being released. | 63 // Simulate the keys being released. |
62 for (KeyCodes::iterator it = key_codes.begin(); it != key_codes.end(); it++) | 64 for (KeyCodes::iterator it = key_codes.begin(); it != key_codes.end(); it++) |
63 XTestFakeKeyEvent(display, *it, False, CurrentTime); | 65 XTestFakeKeyEvent(display, *it, False, CurrentTime); |
64 | 66 |
65 XFlush(display); | 67 XFlush(display); |
66 } | 68 } |
67 #endif // OS_LINUX | 69 #endif // OS_LINUX |
68 | 70 |
| 71 #if defined(OS_WIN) |
| 72 bool FillKeyboardInput(ui::KeyboardCode key, INPUT* input, bool key_up) { |
| 73 memset(input, 0, sizeof(INPUT)); |
| 74 input->type = INPUT_KEYBOARD; |
| 75 input->ki.wVk = ui::WindowsKeyCodeForKeyboardCode(key); |
| 76 input->ki.dwFlags = key_up ? KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP : |
| 77 KEYEVENTF_EXTENDEDKEY; |
| 78 |
| 79 return true; |
| 80 } |
| 81 |
| 82 // This function is modified from |SendKeyPressImpl| of |
| 83 // ui_controls_internal_win.cc. Use ui_test_utils::SendKeyPressSync when testing |
| 84 // global media keys will fail, this is because we have register the single key |
| 85 // using RegisterHotKey, so the keyboard hook of current thread will never be |
| 86 // called when we only send the single key (For example: "MediaNextTrack" down |
| 87 // -> "MediaNextTrack" up). The difference when testing global key combinations: |
| 88 // the key event are sent one by one. For example, sending "Ctrl+Shift+1", we |
| 89 // will send "Ctrl" down -> "Shift" down -> "1" down, (here the hot key is |
| 90 // activated.), then 1 "up" (here InputDispatcher will receive an key up event, |
| 91 // then the message loop in |SendKeyPressToWindowSync| could stop running |
| 92 // normally) -> "Shift" up -> "Ctrl" up. |
| 93 // |
| 94 // Note: The above comment is only when I have digged out when investigate why |
| 95 // using ui_test_utils::SendKeyPressSync to test global media keys will fail. |
| 96 // I need some help about whether we can use this custom function? |
| 97 // TODO(zhchbin): Clear up the comment. |
| 98 bool SendNativeKeyEvent(ui::KeyboardCode key, |
| 99 bool control, |
| 100 bool shift, |
| 101 bool alt) { |
| 102 INPUT input[8] = { 0 }; // 8, assuming all the modifiers are activated. |
| 103 |
| 104 UINT i = 0; |
| 105 if (control) { |
| 106 if (!FillKeyboardInput(ui::VKEY_CONTROL, &input[i], false)) |
| 107 return false; |
| 108 i++; |
| 109 } |
| 110 |
| 111 if (shift) { |
| 112 if (!FillKeyboardInput(ui::VKEY_SHIFT, &input[i], false)) |
| 113 return false; |
| 114 i++; |
| 115 } |
| 116 |
| 117 if (alt) { |
| 118 if (!FillKeyboardInput(ui::VKEY_MENU, &input[i], false)) |
| 119 return false; |
| 120 i++; |
| 121 } |
| 122 |
| 123 if (!FillKeyboardInput(key, &input[i], false)) |
| 124 return false; |
| 125 i++; |
| 126 |
| 127 if (!FillKeyboardInput(key, &input[i], true)) |
| 128 return false; |
| 129 i++; |
| 130 |
| 131 if (alt) { |
| 132 if (!FillKeyboardInput(ui::VKEY_MENU, &input[i], true)) |
| 133 return false; |
| 134 i++; |
| 135 } |
| 136 |
| 137 if (shift) { |
| 138 if (!FillKeyboardInput(ui::VKEY_SHIFT, &input[i], true)) |
| 139 return false; |
| 140 i++; |
| 141 } |
| 142 |
| 143 if (control) { |
| 144 if (!FillKeyboardInput(ui::VKEY_CONTROL, &input[i], true)) |
| 145 return false; |
| 146 i++; |
| 147 } |
| 148 |
| 149 if (::SendInput(i, input, sizeof(INPUT)) != i) |
| 150 return false; |
| 151 |
| 152 return true; |
| 153 } |
| 154 #endif // OS_WIN |
| 155 |
69 #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS)) | 156 #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS)) |
70 // The feature is only fully implemented on Windows and Linux, other platforms | 157 // The feature is only fully implemented on Windows and Linux, other platforms |
71 // coming. | 158 // coming. |
72 #define MAYBE_GlobalCommand GlobalCommand | 159 #define MAYBE_GlobalCommand GlobalCommand |
73 #else | 160 #else |
74 #define MAYBE_GlobalCommand DISABLED_GlobalCommand | 161 #define MAYBE_GlobalCommand DISABLED_GlobalCommand |
75 #endif | 162 #endif |
76 | 163 |
77 // Test the basics of global commands and make sure they work when Chrome | 164 // Test the basics of global commands and make sure they work when Chrome |
78 // doesn't have focus. Also test that non-global commands are not treated as | 165 // doesn't have focus. Also test that non-global commands are not treated as |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 SendNativeKeyEventToXDisplay(ui::VKEY_A, true, true, false); | 208 SendNativeKeyEventToXDisplay(ui::VKEY_A, true, true, false); |
122 SendNativeKeyEventToXDisplay(ui::VKEY_9, true, true, false); | 209 SendNativeKeyEventToXDisplay(ui::VKEY_9, true, true, false); |
123 #endif | 210 #endif |
124 | 211 |
125 // If this fails, it might be because the global shortcut failed to work, | 212 // If this fails, it might be because the global shortcut failed to work, |
126 // but it might also be because the non-global shortcuts unexpectedly | 213 // but it might also be because the non-global shortcuts unexpectedly |
127 // worked. | 214 // worked. |
128 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message(); | 215 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message(); |
129 } | 216 } |
130 | 217 |
| 218 #if defined(OS_WIN) |
| 219 // The feature is only fully implemented on Windows, other platforms coming. |
| 220 #define MAYBE_GlobalDuplicatedMediaKey GlobalDuplicatedMediaKey |
| 221 #else |
| 222 #define MAYBE_GlobalDuplicatedMediaKey DISABLED_GlobalDuplicatedMediaKey |
| 223 #endif |
| 224 |
| 225 IN_PROC_BROWSER_TEST_F(GlobalCommandsApiTest, MAYBE_GlobalDuplicatedMediaKey) { |
| 226 FeatureSwitch::ScopedOverride enable_global_commands( |
| 227 FeatureSwitch::global_commands(), true); |
| 228 |
| 229 ResultCatcher catcher; |
| 230 ASSERT_TRUE(RunExtensionTest("keybinding/global_media_keys_0")) << message_; |
| 231 ASSERT_TRUE(catcher.GetNextResult()); |
| 232 ASSERT_TRUE(RunExtensionTest("keybinding/global_media_keys_1")) << message_; |
| 233 ASSERT_TRUE(catcher.GetNextResult()); |
| 234 |
| 235 WindowController* controller = browser()->extension_window_controller(); |
| 236 controller->window()->Minimize(); |
| 237 |
| 238 #if defined(OS_WIN) |
| 239 // Currently it works only on Windows. |
| 240 SendNativeKeyEvent(ui::VKEY_MEDIA_NEXT_TRACK, false, false, false); |
| 241 |
| 242 // We should get two success result. |
| 243 ASSERT_TRUE(catcher.GetNextResult()); |
| 244 ASSERT_TRUE(catcher.GetNextResult()); |
| 245 #endif |
| 246 } |
| 247 |
131 } // namespace extensions | 248 } // namespace extensions |
OLD | NEW |