EME test page application.
[chromium-blink-merge.git] / chrome / browser / extensions / extension_commands_global_registry_apitest.cc
blob10c4f32cb50e477573bddf0576b197ff3e825262
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
3 // found in the LICENSE file.
5 #include "chrome/browser/extensions/extension_apitest.h"
6 #include "chrome/browser/extensions/window_controller.h"
7 #include "chrome/browser/ui/browser_window.h"
8 #include "chrome/browser/ui/tabs/tab_strip_model.h"
9 #include "chrome/test/base/interactive_test_utils.h"
10 #include "content/public/test/browser_test_utils.h"
11 #include "ui/base/base_window.h"
12 #include "ui/base/test/ui_controls.h"
14 #if defined(OS_LINUX)
15 #include <X11/Xlib.h>
16 #include <X11/extensions/XTest.h>
17 #include <X11/keysym.h>
19 #include "ui/events/keycodes/keyboard_code_conversion_x.h"
20 #include "ui/gfx/x/x11_types.h"
21 #endif
23 #if defined(OS_MACOSX)
24 #include <Carbon/Carbon.h>
26 #include "base/mac/scoped_cftyperef.h"
27 #endif
29 namespace extensions {
31 typedef ExtensionApiTest GlobalCommandsApiTest;
33 #if defined(OS_LINUX)
34 // Send a simulated key press and release event, where |control|, |shift| or
35 // |alt| indicates whether the key is struck with corresponding modifier.
36 void SendNativeKeyEventToXDisplay(ui::KeyboardCode key,
37 bool control,
38 bool shift,
39 bool alt) {
40 Display* display = gfx::GetXDisplay();
41 KeyCode ctrl_key_code = XKeysymToKeycode(display, XK_Control_L);
42 KeyCode shift_key_code = XKeysymToKeycode(display, XK_Shift_L);
43 KeyCode alt_key_code = XKeysymToKeycode(display, XK_Alt_L);
45 // Release modifiers first of all to make sure this function can work as
46 // expected. For example, when |control| is false, but the status of Ctrl key
47 // is down, we will generate a keyboard event with unwanted Ctrl key.
48 XTestFakeKeyEvent(display, ctrl_key_code, False, CurrentTime);
49 XTestFakeKeyEvent(display, shift_key_code, False, CurrentTime);
50 XTestFakeKeyEvent(display, alt_key_code, False, CurrentTime);
52 typedef std::vector<KeyCode> KeyCodes;
53 KeyCodes key_codes;
54 if (control)
55 key_codes.push_back(ctrl_key_code);
56 if (shift)
57 key_codes.push_back(shift_key_code);
58 if (alt)
59 key_codes.push_back(alt_key_code);
61 key_codes.push_back(XKeysymToKeycode(display,
62 XKeysymForWindowsKeyCode(key, false)));
64 // Simulate the keys being pressed.
65 for (KeyCodes::iterator it = key_codes.begin(); it != key_codes.end(); it++)
66 XTestFakeKeyEvent(display, *it, True, CurrentTime);
68 // Simulate the keys being released.
69 for (KeyCodes::iterator it = key_codes.begin(); it != key_codes.end(); it++)
70 XTestFakeKeyEvent(display, *it, False, CurrentTime);
72 XFlush(display);
74 #endif // OS_LINUX
76 #if defined(OS_MACOSX)
77 using base::ScopedCFTypeRef;
79 void SendNativeCommandShift(int key_code) {
80 CGEventSourceRef event_source =
81 CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
82 CGEventTapLocation event_tap_location = kCGHIDEventTap;
84 // Create the keyboard press events.
85 ScopedCFTypeRef<CGEventRef> command_down(CGEventCreateKeyboardEvent(
86 event_source, kVK_Command, true));
87 ScopedCFTypeRef<CGEventRef> shift_down(CGEventCreateKeyboardEvent(
88 event_source, kVK_Shift, true));
89 ScopedCFTypeRef<CGEventRef> key_down(CGEventCreateKeyboardEvent(
90 event_source, key_code, true));
91 CGEventSetFlags(key_down, kCGEventFlagMaskCommand | kCGEventFlagMaskShift);
93 // Create the keyboard release events.
94 ScopedCFTypeRef<CGEventRef> command_up(CGEventCreateKeyboardEvent(
95 event_source, kVK_Command, false));
96 ScopedCFTypeRef<CGEventRef> shift_up(CGEventCreateKeyboardEvent(
97 event_source, kVK_Shift, false));
98 ScopedCFTypeRef<CGEventRef> key_up(CGEventCreateKeyboardEvent(
99 event_source, key_code, false));
100 CGEventSetFlags(key_up, kCGEventFlagMaskCommand | kCGEventFlagMaskShift);
102 // Post all of the events.
103 CGEventPost(event_tap_location, command_down);
104 CGEventPost(event_tap_location, shift_down);
105 CGEventPost(event_tap_location, key_down);
106 CGEventPost(event_tap_location, key_up);
107 CGEventPost(event_tap_location, shift_up);
108 CGEventPost(event_tap_location, command_up);
110 CFRelease(event_source);
112 #endif
114 #if defined(OS_CHROMEOS)
115 // Fully implemented everywhere except Chrome OS.
116 #define MAYBE_GlobalCommand DISABLED_GlobalCommand
117 #else
118 #define MAYBE_GlobalCommand GlobalCommand
119 #endif
121 // Test the basics of global commands and make sure they work when Chrome
122 // doesn't have focus. Also test that non-global commands are not treated as
123 // global and that keys beyond Ctrl+Shift+[0..9] cannot be auto-assigned by an
124 // extension.
125 IN_PROC_BROWSER_TEST_F(GlobalCommandsApiTest, MAYBE_GlobalCommand) {
126 FeatureSwitch::ScopedOverride enable_global_commands(
127 FeatureSwitch::global_commands(), true);
129 // Load the extension in the non-incognito browser.
130 ResultCatcher catcher;
131 ASSERT_TRUE(RunExtensionTest("keybinding/global")) << message_;
132 ASSERT_TRUE(catcher.GetNextResult());
134 #if defined(OS_WIN)
135 // Our infrastructure for sending keys expects a browser to send them to, but
136 // to properly test global shortcuts you need to send them to another target.
137 // So, create an incognito browser to use as a target to send the shortcuts
138 // to. It will ignore all of them and allow us test whether the global
139 // shortcut really is global in nature and also that the non-global shortcut
140 // is non-global.
141 Browser* incognito_browser = CreateIncognitoBrowser();
143 // Try to activate the non-global shortcut (Ctrl+Shift+1) and the
144 // non-assignable shortcut (Ctrl+Shift+A) by sending the keystrokes to the
145 // incognito browser. Both shortcuts should have no effect (extension is not
146 // loaded there).
147 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
148 incognito_browser, ui::VKEY_1, true, true, false, false));
149 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
150 incognito_browser, ui::VKEY_A, true, true, false, false));
152 // Activate the shortcut (Ctrl+Shift+9). This should have an effect.
153 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
154 incognito_browser, ui::VKEY_9, true, true, false, false));
155 #elif defined(OS_LINUX)
156 // Create an incognito browser to capture the focus.
157 CreateIncognitoBrowser();
159 // On Linux, our infrastructure for sending keys just synthesize keyboard
160 // event and send them directly to the specified window, without notifying the
161 // X root window. It didn't work while testing global shortcut because the
162 // stuff of global shortcut on Linux need to be notified when KeyPress event
163 // is happening on X root window. So we simulate the keyboard input here.
164 SendNativeKeyEventToXDisplay(ui::VKEY_1, true, true, false);
165 SendNativeKeyEventToXDisplay(ui::VKEY_A, true, true, false);
166 SendNativeKeyEventToXDisplay(ui::VKEY_9, true, true, false);
167 #elif defined(OS_MACOSX)
168 // Create an incognito browser to capture the focus.
169 CreateIncognitoBrowser();
171 // Send some native mac key events.
172 SendNativeCommandShift(kVK_ANSI_1);
173 SendNativeCommandShift(kVK_ANSI_A);
174 SendNativeCommandShift(kVK_ANSI_9);
175 #endif
177 // If this fails, it might be because the global shortcut failed to work,
178 // but it might also be because the non-global shortcuts unexpectedly
179 // worked.
180 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
183 #if defined(OS_WIN)
184 // The feature is only fully implemented on Windows, other platforms coming.
185 // TODO(smus): On mac, SendKeyPress must first support media keys.
186 #define MAYBE_GlobalDuplicatedMediaKey GlobalDuplicatedMediaKey
187 #else
188 #define MAYBE_GlobalDuplicatedMediaKey DISABLED_GlobalDuplicatedMediaKey
189 #endif
191 IN_PROC_BROWSER_TEST_F(GlobalCommandsApiTest, MAYBE_GlobalDuplicatedMediaKey) {
192 FeatureSwitch::ScopedOverride enable_global_commands(
193 FeatureSwitch::global_commands(), true);
195 ResultCatcher catcher;
196 ASSERT_TRUE(RunExtensionTest("keybinding/global_media_keys_0")) << message_;
197 ASSERT_TRUE(catcher.GetNextResult());
198 ASSERT_TRUE(RunExtensionTest("keybinding/global_media_keys_1")) << message_;
199 ASSERT_TRUE(catcher.GetNextResult());
201 Browser* incognito_browser = CreateIncognitoBrowser(); // Ditto.
202 WindowController* controller =
203 incognito_browser->extension_window_controller();
205 ui_controls::SendKeyPress(controller->window()->GetNativeWindow(),
206 ui::VKEY_MEDIA_NEXT_TRACK,
207 false,
208 false,
209 false,
210 false);
212 // We should get two success result.
213 ASSERT_TRUE(catcher.GetNextResult());
214 ASSERT_TRUE(catcher.GetNextResult());
217 } // namespace extensions