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 |