Chromium Code Reviews| 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 } | |
|
Finnur
2013/11/12 16:27:54
Why do we need to copy this function?
| |
| 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. | |
|
Finnur
2013/11/12 16:27:54
I think this is not the right approach.
1) I'm not
zhchbin
2013/11/13 05:01:57
You can do an experiment:
1. Change the SendNativ
zhchbin
2013/11/13 16:05:10
Maybe you ignore this comment?
Finnur
2013/11/18 11:16:14
I didn't have a good advice for you because I don'
zhchbin
2013/11/18 13:10:13
The message loop is: https://code.google.com/p/chr
Finnur
2013/11/18 14:14:53
I think this is the one remaining issue before you
zhchbin
2013/11/18 14:54:44
Em... first of all, sorry for my poor English that
| |
| 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 SendNativeKeyEvent(ui::VKEY_MEDIA_NEXT_TRACK, false, false, false); | |
| 239 | |
| 240 // We should get two success result. | |
| 241 ASSERT_TRUE(catcher.GetNextResult()); | |
| 242 ASSERT_TRUE(catcher.GetNextResult()); | |
| 243 } | |
| 244 | |
| 131 } // namespace extensions | 245 } // namespace extensions |
| OLD | NEW |