Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(216)

Side by Side Diff: chrome/browser/extensions/extension_commands_global_registry_apitest.cc

Issue 60353008: Mac global keybindings (Closed) Base URL: https://src.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 #include "ui/base/test/ui_controls.h" 12 #include "ui/base/test/ui_controls.h"
13 13
14 #if defined(OS_LINUX) 14 #if defined(OS_LINUX)
15 #include <X11/Xlib.h> 15 #include <X11/Xlib.h>
16 #include <X11/extensions/XTest.h> 16 #include <X11/extensions/XTest.h>
17 #include <X11/keysym.h> 17 #include <X11/keysym.h>
18 18
19 #include "ui/events/keycodes/keyboard_code_conversion_x.h" 19 #include "ui/events/keycodes/keyboard_code_conversion_x.h"
20 #include "ui/gfx/x/x11_types.h" 20 #include "ui/gfx/x/x11_types.h"
21 #endif 21 #endif
22 22
23 #if defined(OS_MACOSX)
24 #include <Carbon/Carbon.h>
25 #endif
26
23 namespace extensions { 27 namespace extensions {
24 28
25 typedef ExtensionApiTest GlobalCommandsApiTest; 29 typedef ExtensionApiTest GlobalCommandsApiTest;
26 30
27 #if defined(OS_LINUX) 31 #if defined(OS_LINUX)
28 // Send a simulated key press and release event, where |control|, |shift| or 32 // Send a simulated key press and release event, where |control|, |shift| or
29 // |alt| indicates whether the key is struck with corresponding modifier. 33 // |alt| indicates whether the key is struck with corresponding modifier.
30 void SendNativeKeyEventToXDisplay(ui::KeyboardCode key, 34 void SendNativeKeyEventToXDisplay(ui::KeyboardCode key,
31 bool control, 35 bool control,
32 bool shift, 36 bool shift,
(...skipping 27 matching lines...) Expand all
60 XTestFakeKeyEvent(display, *it, True, CurrentTime); 64 XTestFakeKeyEvent(display, *it, True, CurrentTime);
61 65
62 // Simulate the keys being released. 66 // Simulate the keys being released.
63 for (KeyCodes::iterator it = key_codes.begin(); it != key_codes.end(); it++) 67 for (KeyCodes::iterator it = key_codes.begin(); it != key_codes.end(); it++)
64 XTestFakeKeyEvent(display, *it, False, CurrentTime); 68 XTestFakeKeyEvent(display, *it, False, CurrentTime);
65 69
66 XFlush(display); 70 XFlush(display);
67 } 71 }
68 #endif // OS_LINUX 72 #endif // OS_LINUX
69 73
70 #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS)) 74 #if defined(OS_MACOSX)
75 void SendNativeCommandShift(int key_code) {
76 CGEventSourceRef src =
77 CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
78
79 CGEventRef cmd_d = CGEventCreateKeyboardEvent(src, kVK_Command, true);
Robert Sesek 2013/12/09 19:17:42 You should place these in a ScopedCFTypeRef so tha
Mark Mentovai 2013/12/09 19:31:54 This sounds like the key event is for command-D, c
smus 2013/12/09 23:37:06 Done.
80 CGEventRef cmd_u = CGEventCreateKeyboardEvent(src, kVK_Command, false);
Mark Mentovai 2013/12/09 19:31:54 Why don’t you create these in the order that they
smus 2013/12/09 23:37:06 Done.
81 CGEventRef shift_d = CGEventCreateKeyboardEvent(src, kVK_Shift, true);
82 CGEventRef shift_u = CGEventCreateKeyboardEvent(src, kVK_Shift, false);
83 CGEventRef key_d = CGEventCreateKeyboardEvent(src, key_code, true);
84 CGEventRef key_u = CGEventCreateKeyboardEvent(src, key_code, false);
85
86 CGEventSetFlags(key_d, kCGEventFlagMaskCommand | kCGEventFlagMaskShift);
Mark Mentovai 2013/12/09 19:31:54 This should immediately follow the creation of key
smus 2013/12/09 23:37:06 Done.
87 CGEventSetFlags(key_u, kCGEventFlagMaskCommand | kCGEventFlagMaskShift);
Mark Mentovai 2013/12/09 19:31:54 Ditto, key_u.
smus 2013/12/09 23:37:06 Done.
88
89 CGEventTapLocation loc = kCGHIDEventTap; // kCGSessionEventTap also works
Mark Mentovai 2013/12/09 19:31:54 http://google-styleguide.googlecode.com/svn/trunk/
smus 2013/12/09 23:37:06 Done.
90 CGEventPost(loc, cmd_d);
91 CGEventPost(loc, shift_d);
92 CGEventPost(loc, key_d);
93 CGEventPost(loc, key_u);
94 CGEventPost(loc, shift_u);
95 CGEventPost(loc, cmd_u);
96
97 CFRelease(cmd_d);
Mark Mentovai 2013/12/09 19:31:54 Use a base::ScopedCFTypeRef (base/mac/scoped_cftyp
smus 2013/12/09 23:37:06 Done.
98 CFRelease(cmd_u);
99 CFRelease(shift_d);
100 CFRelease(shift_u);
101 CFRelease(key_d);
102 CFRelease(key_u);
103 CFRelease(src);
104 }
105 #endif
106
107 #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS)) || defined(O S_MACOSX)
71 // The feature is only fully implemented on Windows and Linux, other platforms 108 // The feature is only fully implemented on Windows and Linux, other platforms
72 // coming. 109 // coming.
73 #define MAYBE_GlobalCommand GlobalCommand 110 #define MAYBE_GlobalCommand GlobalCommand
74 #else 111 #else
75 #define MAYBE_GlobalCommand DISABLED_GlobalCommand 112 #define MAYBE_GlobalCommand DISABLED_GlobalCommand
76 #endif 113 #endif
77 114
78 // Test the basics of global commands and make sure they work when Chrome 115 // Test the basics of global commands and make sure they work when Chrome
79 // doesn't have focus. Also test that non-global commands are not treated as 116 // doesn't have focus. Also test that non-global commands are not treated as
80 // global and that keys beyond Ctrl+Shift+[0..9] cannot be auto-assigned by an 117 // global and that keys beyond Ctrl+Shift+[0..9] cannot be auto-assigned by an
81 // extension. 118 // extension.
82 IN_PROC_BROWSER_TEST_F(GlobalCommandsApiTest, MAYBE_GlobalCommand) { 119 IN_PROC_BROWSER_TEST_F(GlobalCommandsApiTest, MAYBE_GlobalCommand) {
83 FeatureSwitch::ScopedOverride enable_global_commands( 120 FeatureSwitch::ScopedOverride enable_global_commands(
84 FeatureSwitch::global_commands(), true); 121 FeatureSwitch::global_commands(), true);
85 122
86 // Load the extension in the non-incognito browser. 123 // Load the extension in the non-incognito browser.
87 ResultCatcher catcher; 124 ResultCatcher catcher;
88 ASSERT_TRUE(RunExtensionTest("keybinding/global")) << message_; 125 ASSERT_TRUE(RunExtensionTest("keybinding/global")) << message_;
89 ASSERT_TRUE(catcher.GetNextResult()); 126 ASSERT_TRUE(catcher.GetNextResult());
90 127
91 #if !defined(OS_LINUX) 128 #if defined(OS_WIN)
92 // Our infrastructure for sending keys expects a browser to send them to, but 129 // Our infrastructure for sending keys expects a browser to send them to, but
93 // to properly test global shortcuts you need to send them to another target. 130 // to properly test global shortcuts you need to send them to another target.
94 // So, create an incognito browser to use as a target to send the shortcuts 131 // So, create an incognito browser to use as a target to send the shortcuts
95 // to. It will ignore all of them and allow us test whether the global 132 // to. It will ignore all of them and allow us test whether the global
96 // shortcut really is global in nature and also that the non-global shortcut 133 // shortcut really is global in nature and also that the non-global shortcut
97 // is non-global. 134 // is non-global.
98 Browser* incognito_browser = CreateIncognitoBrowser(); 135 Browser* incognito_browser = CreateIncognitoBrowser();
99 136
100 // Try to activate the non-global shortcut (Ctrl+Shift+1) and the 137 // Try to activate the non-global shortcut (Ctrl+Shift+1) and the
101 // non-assignable shortcut (Ctrl+Shift+A) by sending the keystrokes to the 138 // non-assignable shortcut (Ctrl+Shift+A) by sending the keystrokes to the
102 // incognito browser. Both shortcuts should have no effect (extension is not 139 // incognito browser. Both shortcuts should have no effect (extension is not
103 // loaded there). 140 // loaded there).
104 ASSERT_TRUE(ui_test_utils::SendKeyPressSync( 141 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
105 incognito_browser, ui::VKEY_1, true, true, false, false)); 142 incognito_browser, ui::VKEY_1, true, true, false, false));
106 ASSERT_TRUE(ui_test_utils::SendKeyPressSync( 143 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
107 incognito_browser, ui::VKEY_A, true, true, false, false)); 144 incognito_browser, ui::VKEY_A, true, true, false, false));
108 145
109 // Activate the shortcut (Ctrl+Shift+9). This should have an effect. 146 // Activate the shortcut (Ctrl+Shift+9). This should have an effect.
110 ASSERT_TRUE(ui_test_utils::SendKeyPressSync( 147 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
111 incognito_browser, ui::VKEY_9, true, true, false, false)); 148 incognito_browser, ui::VKEY_9, true, true, false, false));
112 #else 149 #elif defined(OS_LINUX)
113 // Create an incognito browser to capture the focus. 150 // Create an incognito browser to capture the focus.
114 CreateIncognitoBrowser(); 151 CreateIncognitoBrowser();
115 152
116 // On Linux, our infrastructure for sending keys just synthesize keyboard 153 // On Linux, our infrastructure for sending keys just synthesize keyboard
117 // event and send them directly to the specified window, without notifying the 154 // event and send them directly to the specified window, without notifying the
118 // X root window. It didn't work while testing global shortcut because the 155 // X root window. It didn't work while testing global shortcut because the
119 // stuff of global shortcut on Linux need to be notified when KeyPress event 156 // stuff of global shortcut on Linux need to be notified when KeyPress event
120 // is happening on X root window. So we simulate the keyboard input here. 157 // is happening on X root window. So we simulate the keyboard input here.
121 SendNativeKeyEventToXDisplay(ui::VKEY_1, true, true, false); 158 SendNativeKeyEventToXDisplay(ui::VKEY_1, true, true, false);
122 SendNativeKeyEventToXDisplay(ui::VKEY_A, true, true, false); 159 SendNativeKeyEventToXDisplay(ui::VKEY_A, true, true, false);
123 SendNativeKeyEventToXDisplay(ui::VKEY_9, true, true, false); 160 SendNativeKeyEventToXDisplay(ui::VKEY_9, true, true, false);
161 #elif defined(OS_MACOSX)
162 // Create an incognito browser to capture the focus.
163 CreateIncognitoBrowser();
164
165 // Send some native mac key events.
166 SendNativeCommandShift(kVK_ANSI_1);
167 SendNativeCommandShift(kVK_ANSI_A);
168 SendNativeCommandShift(kVK_ANSI_9);
124 #endif 169 #endif
125 170
126 // If this fails, it might be because the global shortcut failed to work, 171 // If this fails, it might be because the global shortcut failed to work,
127 // but it might also be because the non-global shortcuts unexpectedly 172 // but it might also be because the non-global shortcuts unexpectedly
128 // worked. 173 // worked.
129 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message(); 174 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
130 } 175 }
131 176
132 #if defined(OS_WIN) 177 #if defined(OS_WIN)
133 // The feature is only fully implemented on Windows, other platforms coming. 178 // The feature is only fully implemented on Windows, other platforms coming.
179 // TODO(smus): On mac, SendKeyPress must first support media keys.
134 #define MAYBE_GlobalDuplicatedMediaKey GlobalDuplicatedMediaKey 180 #define MAYBE_GlobalDuplicatedMediaKey GlobalDuplicatedMediaKey
135 #else 181 #else
136 #define MAYBE_GlobalDuplicatedMediaKey DISABLED_GlobalDuplicatedMediaKey 182 #define MAYBE_GlobalDuplicatedMediaKey DISABLED_GlobalDuplicatedMediaKey
137 #endif 183 #endif
138 184
139 IN_PROC_BROWSER_TEST_F(GlobalCommandsApiTest, MAYBE_GlobalDuplicatedMediaKey) { 185 IN_PROC_BROWSER_TEST_F(GlobalCommandsApiTest, MAYBE_GlobalDuplicatedMediaKey) {
140 FeatureSwitch::ScopedOverride enable_global_commands( 186 FeatureSwitch::ScopedOverride enable_global_commands(
141 FeatureSwitch::global_commands(), true); 187 FeatureSwitch::global_commands(), true);
142 188
143 ResultCatcher catcher; 189 ResultCatcher catcher;
(...skipping 12 matching lines...) Expand all
156 false, 202 false,
157 false, 203 false,
158 false); 204 false);
159 205
160 // We should get two success result. 206 // We should get two success result.
161 ASSERT_TRUE(catcher.GetNextResult()); 207 ASSERT_TRUE(catcher.GetNextResult());
162 ASSERT_TRUE(catcher.GetNextResult()); 208 ASSERT_TRUE(catcher.GetNextResult());
163 } 209 }
164 210
165 } // namespace extensions 211 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698