1 // Copyright (c) 2012 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 "base/command_line.h"
6 #include "chrome/app/chrome_command_ids.h"
7 #include "chrome/browser/extensions/active_tab_permission_granter.h"
8 #include "chrome/browser/extensions/api/commands/command_service.h"
9 #include "chrome/browser/extensions/browser_action_test_util.h"
10 #include "chrome/browser/extensions/component_loader.h"
11 #include "chrome/browser/extensions/extension_action.h"
12 #include "chrome/browser/extensions/extension_action_manager.h"
13 #include "chrome/browser/extensions/extension_apitest.h"
14 #include "chrome/browser/extensions/extension_service.h"
15 #include "chrome/browser/sessions/session_tab_helper.h"
16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/browser_command_controller.h"
18 #include "chrome/browser/ui/browser_commands.h"
19 #include "chrome/browser/ui/tabs/tab_strip_model.h"
20 #include "chrome/test/base/interactive_test_utils.h"
21 #include "chrome/test/base/ui_test_utils.h"
22 #include "content/public/browser/notification_service.h"
23 #include "content/public/browser/web_contents.h"
24 #include "content/public/test/javascript_test_observer.h"
25 #include "extensions/browser/extension_registry.h"
26 #include "extensions/common/extension.h"
27 #include "extensions/common/feature_switch.h"
28 #include "extensions/common/manifest_constants.h"
29 #include "extensions/common/permissions/permissions_data.h"
30 #include "extensions/test/extension_test_message_listener.h"
31 #include "extensions/test/result_catcher.h"
33 using content::WebContents
;
35 namespace extensions
{
39 // This extension ID is used for tests require a stable ID over multiple
40 // extension installs.
41 const char kId
[] = "pgoakhfeplldmjheffidklpoklkppipp";
43 // Default keybinding to use for emulating user-defined shortcut overrides. The
44 // test extensions use Alt+Shift+F and Alt+Shift+H.
45 const char kAltShiftG
[] = "Alt+Shift+G";
47 // Name of the command for the "basics" test extension.
48 const char kBasicsShortcutCommandName
[] = "toggle-feature";
49 // Name of the command for the overwrite_bookmark_shortcut test extension.
50 const char kOverwriteBookmarkShortcutCommandName
[] = "send message";
52 #if defined(OS_MACOSX)
53 const char kBookmarkKeybinding
[] = "Command+D";
55 const char kBookmarkKeybinding
[] = "Ctrl+D";
56 #endif // defined(OS_MACOSX)
58 bool SendBookmarkKeyPressSync(Browser
* browser
) {
59 return ui_test_utils::SendKeyPressSync(
61 #if defined(OS_MACOSX)
62 false, false, false, true
64 true, false, false, false
69 // Named command for media key overwrite test.
70 const char kMediaKeyTestCommand
[] = "test_mediakeys_update";
72 // A scoped observer that listens for dom automation messages.
73 class DomMessageListener
: public content::TestMessageHandler
{
75 explicit DomMessageListener(content::WebContents
* web_contents
);
76 ~DomMessageListener() override
;
78 // Wait until a message is received.
81 // Clears and resets the observer.
84 const std::string
& message() const { return message_
; }
87 // content::TestMessageHandler:
88 MessageResponse
HandleMessage(const std::string
& json
) override
;
89 void Reset() override
;
91 // The message received. Note that this will be JSON, so if it is a string,
92 // it will be wrapped in quotes.
95 content::JavascriptTestObserver observer_
;
97 DISALLOW_COPY_AND_ASSIGN(DomMessageListener
);
100 DomMessageListener::DomMessageListener(content::WebContents
* web_contents
)
101 : observer_(web_contents
, this) {
104 DomMessageListener::~DomMessageListener() {
107 void DomMessageListener::Wait() {
111 void DomMessageListener::Clear() {
112 // We don't just call this in DomMessageListener::Reset() because the
113 // JavascriptTestObserver's Reset() method also resets its handler (this).
117 content::TestMessageHandler::MessageResponse
DomMessageListener::HandleMessage(
118 const std::string
& json
) {
123 void DomMessageListener::Reset() {
124 TestMessageHandler::Reset();
130 class CommandsApiTest
: public ExtensionApiTest
{
133 ~CommandsApiTest() override
{}
136 BrowserActionTestUtil
GetBrowserActionsBar() {
137 return BrowserActionTestUtil(browser());
140 bool IsGrantedForTab(const Extension
* extension
,
141 const content::WebContents
* web_contents
) {
142 return extension
->permissions_data()->HasAPIPermissionForTab(
143 SessionTabHelper::IdForTab(web_contents
), APIPermission::kTab
);
146 #if defined(OS_CHROMEOS)
147 void RunChromeOSConversionTest(const std::string
& extension_path
) {
148 // Setup the environment.
149 ASSERT_TRUE(test_server()->Start());
150 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
151 ASSERT_TRUE(RunExtensionTest(extension_path
)) << message_
;
152 ui_test_utils::NavigateToURL(
153 browser(), test_server()->GetURL("files/extensions/test_file.txt"));
155 ResultCatcher catcher
;
157 // Send all expected keys (Search+Shift+{Left, Up, Right, Down}).
158 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
159 browser(), ui::VKEY_LEFT
, false, true, false, true));
160 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
161 browser(), ui::VKEY_UP
, false, true, false, true));
162 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
163 browser(), ui::VKEY_RIGHT
, false, true, false, true));
164 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
165 browser(), ui::VKEY_DOWN
, false, true, false, true));
167 ASSERT_TRUE(catcher
.GetNextResult());
169 #endif // OS_CHROMEOS
172 // Test the basic functionality of the Keybinding API:
173 // - That pressing the shortcut keys should perform actions (activate the
174 // browser action or send an event).
175 // - Note: Page action keybindings are tested in PageAction test below.
176 // - The shortcut keys taken by one extension are not overwritten by the last
177 // installed extension.
178 IN_PROC_BROWSER_TEST_F(CommandsApiTest
, Basic
) {
179 ASSERT_TRUE(test_server()->Start());
180 ASSERT_TRUE(RunExtensionTest("keybinding/basics")) << message_
;
181 const Extension
* extension
= GetSingleLoadedExtension();
182 ASSERT_TRUE(extension
) << message_
;
184 // Load this extension, which uses the same keybindings but sets the page
185 // to different colors. This is so we can see that it doesn't interfere. We
186 // don't test this extension in any other way (it should otherwise be
187 // immaterial to this test).
188 ASSERT_TRUE(RunExtensionTest("keybinding/conflicting")) << message_
;
190 // Test that there are two browser actions in the toolbar.
191 ASSERT_EQ(2, GetBrowserActionsBar().NumberOfBrowserActions());
193 ui_test_utils::NavigateToURL(
194 browser(), test_server()->GetURL("files/extensions/test_file.txt"));
196 // activeTab shouldn't have been granted yet.
197 WebContents
* tab
= browser()->tab_strip_model()->GetActiveWebContents();
200 EXPECT_FALSE(IsGrantedForTab(extension
, tab
));
202 ExtensionTestMessageListener
test_listener(false); // Won't reply.
203 // Activate the browser action shortcut (Ctrl+Shift+F).
204 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
205 browser(), ui::VKEY_F
, true, true, false, false));
206 EXPECT_TRUE(test_listener
.WaitUntilSatisfied());
207 // activeTab should now be granted.
208 EXPECT_TRUE(IsGrantedForTab(extension
, tab
));
209 // Verify the command worked.
210 EXPECT_EQ(std::string("basics browser action"), test_listener
.message());
212 test_listener
.Reset();
213 // Activate the command shortcut (Ctrl+Shift+Y).
214 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
215 browser(), ui::VKEY_Y
, true, true, false, false));
216 EXPECT_TRUE(test_listener
.WaitUntilSatisfied());
217 EXPECT_EQ(std::string(kBasicsShortcutCommandName
), test_listener
.message());
220 IN_PROC_BROWSER_TEST_F(CommandsApiTest
, PageAction
) {
221 ASSERT_TRUE(test_server()->Start());
222 ASSERT_TRUE(RunExtensionTest("keybinding/page_action")) << message_
;
223 const Extension
* extension
= GetSingleLoadedExtension();
224 ASSERT_TRUE(extension
) << message_
;
227 // Load a page, the extension will detect the navigation and request to show
228 // the page action icon.
229 ResultCatcher catcher
;
230 ui_test_utils::NavigateToURL(
231 browser(), test_server()->GetURL("files/extensions/test_file.txt"));
232 ASSERT_TRUE(catcher
.GetNextResult());
235 // Make sure it appears and is the right one.
236 ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1));
237 int tab_id
= SessionTabHelper::FromWebContents(
238 browser()->tab_strip_model()->GetActiveWebContents())->session_id().id();
239 ExtensionAction
* action
=
240 ExtensionActionManager::Get(browser()->profile())->
241 GetPageAction(*extension
);
243 EXPECT_EQ("Send message", action
->GetTitle(tab_id
));
245 ExtensionTestMessageListener
test_listener(false); // Won't reply.
246 test_listener
.set_extension_id(extension
->id());
248 // Activate the shortcut (Alt+Shift+F).
249 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
250 browser(), ui::VKEY_F
, false, true, true, false));
252 test_listener
.WaitUntilSatisfied();
253 EXPECT_EQ("clicked", test_listener
.message());
256 IN_PROC_BROWSER_TEST_F(CommandsApiTest
, PageActionKeyUpdated
) {
257 ASSERT_TRUE(test_server()->Start());
258 ASSERT_TRUE(RunExtensionTest("keybinding/page_action")) << message_
;
259 const Extension
* extension
= GetSingleLoadedExtension();
260 ASSERT_TRUE(extension
) << message_
;
262 CommandService
* command_service
= CommandService::Get(browser()->profile());
263 // Simulate the user setting the keybinding to Alt+Shift+G.
264 command_service
->UpdateKeybindingPrefs(
265 extension
->id(), manifest_values::kPageActionCommandEvent
, kAltShiftG
);
268 // Load a page. The extension will detect the navigation and request to show
269 // the page action icon.
270 ResultCatcher catcher
;
271 ui_test_utils::NavigateToURL(
272 browser(), test_server()->GetURL("files/extensions/test_file.txt"));
273 ASSERT_TRUE(catcher
.GetNextResult());
276 ExtensionTestMessageListener
test_listener(false); // Won't reply.
277 test_listener
.set_extension_id(extension
->id());
279 // Activate the shortcut.
280 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
281 browser(), ui::VKEY_G
, false, true, true, false));
283 test_listener
.WaitUntilSatisfied();
284 EXPECT_EQ("clicked", test_listener
.message());
287 // This test validates that the getAll query API function returns registered
288 // commands as well as synthesized ones and that inactive commands (like the
289 // synthesized ones are in nature) have no shortcuts.
290 IN_PROC_BROWSER_TEST_F(CommandsApiTest
, SynthesizedCommand
) {
291 ASSERT_TRUE(test_server()->Start());
292 ASSERT_TRUE(RunExtensionTest("keybinding/synthesized")) << message_
;
295 // This test validates that an extension cannot request a shortcut that is
296 // already in use by Chrome.
297 IN_PROC_BROWSER_TEST_F(CommandsApiTest
, DontOverwriteSystemShortcuts
) {
298 ASSERT_TRUE(test_server()->Start());
300 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
302 ASSERT_TRUE(RunExtensionTest("keybinding/dont_overwrite_system")) << message_
;
304 ui_test_utils::NavigateToURL(
305 browser(), test_server()->GetURL("files/extensions/test_file.txt"));
307 // Activate the regular shortcut (Alt+Shift+F).
308 ExtensionTestMessageListener
alt_shift_f_listener("alt_shift_f", false);
309 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
310 browser(), ui::VKEY_F
, false, true, true, false));
311 EXPECT_TRUE(alt_shift_f_listener
.WaitUntilSatisfied());
313 // Try to activate the bookmark shortcut (Ctrl+D). This should not work
314 // without requesting via chrome_settings_overrides.
316 // Since keypresses are sent synchronously, we can check this by first sending
317 // Ctrl+D (which shouldn't work), followed by Alt+Shift+F (which should work),
318 // and listening for both. If, by the time we receive the Alt+Shift+F
319 // response, we haven't received a response for Ctrl+D, it is safe to say we
320 // won't receive one.
322 ExtensionTestMessageListener
ctrl_d_listener("ctrl_d", false);
323 alt_shift_f_listener
.Reset();
325 ASSERT_TRUE(SendBookmarkKeyPressSync(browser()));
327 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
328 browser(), ui::VKEY_F
, false, true, true, false));
329 EXPECT_TRUE(alt_shift_f_listener
.WaitUntilSatisfied());
330 EXPECT_FALSE(ctrl_d_listener
.was_satisfied());
333 // Try to activate the Ctrl+F shortcut (shouldn't work).
335 ExtensionTestMessageListener
ctrl_f_listener("ctrl_f", false);
336 alt_shift_f_listener
.Reset();
338 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
339 browser(), ui::VKEY_F
, true, false, false, false));
341 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
342 browser(), ui::VKEY_F
, false, true, true, false));
343 EXPECT_TRUE(alt_shift_f_listener
.WaitUntilSatisfied());
344 EXPECT_FALSE(ctrl_f_listener
.was_satisfied());
348 // This test validates that an extension can remove the Chrome bookmark shortcut
349 // if it has requested to do so.
350 IN_PROC_BROWSER_TEST_F(CommandsApiTest
, RemoveBookmarkShortcut
) {
351 ASSERT_TRUE(test_server()->Start());
353 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
355 // This functionality requires a feature flag.
356 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
357 "--enable-override-bookmarks-ui", "1");
359 ASSERT_TRUE(RunExtensionTest("keybinding/remove_bookmark_shortcut"))
362 EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_BOOKMARK_PAGE
));
365 // This test validates that an extension cannot remove the Chrome bookmark
366 // shortcut without being given permission with a feature flag.
367 IN_PROC_BROWSER_TEST_F(CommandsApiTest
,
368 RemoveBookmarkShortcutWithoutPermission
) {
369 ASSERT_TRUE(test_server()->Start());
371 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
373 EXPECT_TRUE(RunExtensionTestIgnoreManifestWarnings(
374 "keybinding/remove_bookmark_shortcut"));
376 EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_BOOKMARK_PAGE
));
379 // This test validates that an extension that removes the Chrome bookmark
380 // shortcut continues to remove the bookmark shortcut with a user-assigned
381 // Ctrl+D shortcut (i.e. it does not trigger the overwrite functionality).
382 IN_PROC_BROWSER_TEST_F(CommandsApiTest
,
383 RemoveBookmarkShortcutWithUserKeyBinding
) {
384 ASSERT_TRUE(test_server()->Start());
386 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
388 // This functionality requires a feature flag.
389 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
390 "--enable-override-bookmarks-ui", "1");
392 ASSERT_TRUE(RunExtensionTest("keybinding/remove_bookmark_shortcut"))
395 // Check that the shortcut is removed.
396 CommandService
* command_service
= CommandService::Get(browser()->profile());
397 const Extension
* extension
= GetSingleLoadedExtension();
398 // Simulate the user setting a keybinding to Ctrl+D.
399 command_service
->UpdateKeybindingPrefs(
400 extension
->id(), manifest_values::kBrowserActionCommandEvent
,
401 kBookmarkKeybinding
);
403 // Force the command enable state to be recalculated.
404 browser()->command_controller()->ExtensionStateChanged();
406 EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_BOOKMARK_PAGE
));
409 // This test validates that an extension can override the Chrome bookmark
410 // shortcut if it has requested to do so.
411 IN_PROC_BROWSER_TEST_F(CommandsApiTest
, OverwriteBookmarkShortcut
) {
412 ASSERT_TRUE(test_server()->Start());
414 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
416 // This functionality requires a feature flag.
417 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
418 "--enable-override-bookmarks-ui", "1");
420 ASSERT_TRUE(RunExtensionTest("keybinding/overwrite_bookmark_shortcut"))
423 ui_test_utils::NavigateToURL(
424 browser(), test_server()->GetURL("files/extensions/test_file.txt"));
426 // Activate the shortcut (Ctrl+D) to send a test message.
427 ExtensionTestMessageListener
test_listener(false); // Won't reply.
428 ASSERT_TRUE(SendBookmarkKeyPressSync(browser()));
429 EXPECT_TRUE(test_listener
.WaitUntilSatisfied());
430 EXPECT_EQ(std::string(kOverwriteBookmarkShortcutCommandName
),
431 test_listener
.message());
434 // This test validates that an extension that requests to override the Chrome
435 // bookmark shortcut, but does not get the keybinding, does not remove the
437 IN_PROC_BROWSER_TEST_F(CommandsApiTest
,
438 OverwriteBookmarkShortcutWithoutKeybinding
) {
439 // This functionality requires a feature flag.
440 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
441 "--enable-override-bookmarks-ui", "1");
443 ASSERT_TRUE(test_server()->Start());
445 EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_BOOKMARK_PAGE
));
447 ASSERT_TRUE(RunExtensionTest("keybinding/overwrite_bookmark_shortcut"))
450 const Extension
* extension
= GetSingleLoadedExtension();
451 CommandService
* command_service
= CommandService::Get(browser()->profile());
453 // Verify the expected command is present.
454 EXPECT_TRUE(command_service
->GetNamedCommands(
455 extension
->id(), CommandService::SUGGESTED
, CommandService::ANY_SCOPE
,
457 EXPECT_EQ(1u, commands
.count(kOverwriteBookmarkShortcutCommandName
));
459 // Simulate the user removing the Ctrl+D keybinding from the command.
460 command_service
->RemoveKeybindingPrefs(
461 extension
->id(), kOverwriteBookmarkShortcutCommandName
);
463 // Force the command enable state to be recalculated.
464 browser()->command_controller()->ExtensionStateChanged();
466 EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_BOOKMARK_PAGE
));
469 // This test validates that an extension override of the Chrome bookmark
470 // shortcut does not supersede the same keybinding by web pages.
471 IN_PROC_BROWSER_TEST_F(CommandsApiTest
,
472 OverwriteBookmarkShortcutDoesNotOverrideWebKeybinding
) {
473 ASSERT_TRUE(test_server()->Start());
475 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
477 // This functionality requires a feature flag.
478 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
479 "--enable-override-bookmarks-ui", "1");
481 ASSERT_TRUE(RunExtensionTest("keybinding/overwrite_bookmark_shortcut"))
484 ui_test_utils::NavigateToURL(
486 test_server()->GetURL(
487 "files/extensions/test_file_with_ctrl-d_keybinding.html"));
489 WebContents
* tab
= browser()->tab_strip_model()->GetActiveWebContents();
492 // Activate the shortcut (Ctrl+D) which should be handled by the page and send
494 DomMessageListener
listener(tab
);
495 ASSERT_TRUE(SendBookmarkKeyPressSync(browser()));
497 EXPECT_EQ(std::string("\"web page received\""), listener
.message());
500 // This test validates that user-set override of the Chrome bookmark shortcut in
501 // an extension that does not request it does supersede the same keybinding by
503 IN_PROC_BROWSER_TEST_F(CommandsApiTest
,
504 OverwriteBookmarkShortcutByUserOverridesWebKeybinding
) {
505 ASSERT_TRUE(test_server()->Start());
507 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
509 // This functionality requires a feature flag.
510 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
511 "--enable-override-bookmarks-ui", "1");
513 ASSERT_TRUE(RunExtensionTest("keybinding/basics"))
516 CommandService
* command_service
= CommandService::Get(browser()->profile());
518 const Extension
* extension
= GetSingleLoadedExtension();
519 // Simulate the user setting the keybinding to Ctrl+D.
520 command_service
->UpdateKeybindingPrefs(
521 extension
->id(), manifest_values::kBrowserActionCommandEvent
,
522 kBookmarkKeybinding
);
524 ui_test_utils::NavigateToURL(
526 test_server()->GetURL(
527 "files/extensions/test_file_with_ctrl-d_keybinding.html"));
529 ExtensionTestMessageListener
test_listener(false); // Won't reply.
530 // Activate the shortcut (Ctrl+D) which should be handled by the extension.
531 ASSERT_TRUE(SendBookmarkKeyPressSync(browser()));
532 EXPECT_TRUE(test_listener
.WaitUntilSatisfied());
533 EXPECT_EQ(std::string("basics browser action"), test_listener
.message());
537 // Currently this feature is implemented on Windows only.
538 #define MAYBE_AllowDuplicatedMediaKeys AllowDuplicatedMediaKeys
540 #define MAYBE_AllowDuplicatedMediaKeys DISABLED_AllowDuplicatedMediaKeys
543 // Test that media keys go to all extensions that register for them.
544 IN_PROC_BROWSER_TEST_F(CommandsApiTest
, MAYBE_AllowDuplicatedMediaKeys
) {
545 ResultCatcher catcher
;
546 ASSERT_TRUE(RunExtensionTest("keybinding/non_global_media_keys_0"))
548 ASSERT_TRUE(catcher
.GetNextResult());
549 ASSERT_TRUE(RunExtensionTest("keybinding/non_global_media_keys_1"))
551 ASSERT_TRUE(catcher
.GetNextResult());
553 // Activate the Media Stop key.
554 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
555 browser(), ui::VKEY_MEDIA_STOP
, false, false, false, false));
557 // We should get two success result.
558 ASSERT_TRUE(catcher
.GetNextResult());
559 ASSERT_TRUE(catcher
.GetNextResult());
562 IN_PROC_BROWSER_TEST_F(CommandsApiTest
, ShortcutAddedOnUpdate
) {
563 base::ScopedTempDir scoped_temp_dir
;
564 EXPECT_TRUE(scoped_temp_dir
.CreateUniqueTempDir());
565 base::FilePath pem_path
= test_data_dir_
.
566 AppendASCII("keybinding").AppendASCII("keybinding.pem");
567 base::FilePath path_v1_unassigned
= PackExtensionWithOptions(
568 test_data_dir_
.AppendASCII("keybinding").AppendASCII("update")
569 .AppendASCII("v1_unassigned"),
570 scoped_temp_dir
.path().AppendASCII("v1_unassigned.crx"),
573 base::FilePath path_v2
= PackExtensionWithOptions(
574 test_data_dir_
.AppendASCII("keybinding").AppendASCII("update")
576 scoped_temp_dir
.path().AppendASCII("v2.crx"),
580 ExtensionRegistry
* registry
= ExtensionRegistry::Get(browser()->profile());
581 CommandService
* command_service
= CommandService::Get(browser()->profile());
583 // Install v1 of the extension without keybinding assigned.
584 ASSERT_TRUE(InstallExtension(path_v1_unassigned
, 1));
585 EXPECT_TRUE(registry
->GetExtensionById(kId
, ExtensionRegistry::ENABLED
) !=
588 // Verify it is set to nothing.
589 ui::Accelerator accelerator
= command_service
->FindCommandByName(
590 kId
, manifest_values::kBrowserActionCommandEvent
).accelerator();
591 EXPECT_EQ(ui::VKEY_UNKNOWN
, accelerator
.key_code());
593 // Update to version 2 with keybinding.
594 EXPECT_TRUE(UpdateExtension(kId
, path_v2
, 0));
595 EXPECT_TRUE(registry
->GetExtensionById(kId
, ExtensionRegistry::ENABLED
) !=
598 // Verify it has a command of Alt+Shift+F.
599 accelerator
= command_service
->FindCommandByName(
600 kId
, manifest_values::kBrowserActionCommandEvent
).accelerator();
601 EXPECT_EQ(ui::VKEY_F
, accelerator
.key_code());
602 EXPECT_FALSE(accelerator
.IsCtrlDown());
603 EXPECT_TRUE(accelerator
.IsShiftDown());
604 EXPECT_TRUE(accelerator
.IsAltDown());
607 IN_PROC_BROWSER_TEST_F(CommandsApiTest
, ShortcutChangedOnUpdate
) {
608 base::ScopedTempDir scoped_temp_dir
;
609 EXPECT_TRUE(scoped_temp_dir
.CreateUniqueTempDir());
610 base::FilePath pem_path
= test_data_dir_
.
611 AppendASCII("keybinding").AppendASCII("keybinding.pem");
612 base::FilePath path_v1
= PackExtensionWithOptions(
613 test_data_dir_
.AppendASCII("keybinding").AppendASCII("update")
615 scoped_temp_dir
.path().AppendASCII("v1.crx"),
618 base::FilePath path_v2_reassigned
= PackExtensionWithOptions(
619 test_data_dir_
.AppendASCII("keybinding").AppendASCII("update")
620 .AppendASCII("v2_reassigned"),
621 scoped_temp_dir
.path().AppendASCII("v2_reassigned.crx"),
625 ExtensionRegistry
* registry
= ExtensionRegistry::Get(browser()->profile());
626 CommandService
* command_service
= CommandService::Get(browser()->profile());
628 // Install v1 of the extension.
629 ASSERT_TRUE(InstallExtension(path_v1
, 1));
630 EXPECT_TRUE(registry
->GetExtensionById(kId
, ExtensionRegistry::ENABLED
) !=
633 // Verify it has a command of Alt+Shift+F.
634 ui::Accelerator accelerator
= command_service
->FindCommandByName(
635 kId
, manifest_values::kBrowserActionCommandEvent
).accelerator();
636 EXPECT_EQ(ui::VKEY_F
, accelerator
.key_code());
637 EXPECT_FALSE(accelerator
.IsCtrlDown());
638 EXPECT_TRUE(accelerator
.IsShiftDown());
639 EXPECT_TRUE(accelerator
.IsAltDown());
641 // Update to version 2 with different keybinding assigned.
642 EXPECT_TRUE(UpdateExtension(kId
, path_v2_reassigned
, 0));
643 EXPECT_TRUE(registry
->GetExtensionById(kId
, ExtensionRegistry::ENABLED
) !=
646 // Verify it has a command of Alt+Shift+H.
647 accelerator
= command_service
->FindCommandByName(
648 kId
, manifest_values::kBrowserActionCommandEvent
).accelerator();
649 EXPECT_EQ(ui::VKEY_H
, accelerator
.key_code());
650 EXPECT_FALSE(accelerator
.IsCtrlDown());
651 EXPECT_TRUE(accelerator
.IsShiftDown());
652 EXPECT_TRUE(accelerator
.IsAltDown());
655 IN_PROC_BROWSER_TEST_F(CommandsApiTest
, ShortcutRemovedOnUpdate
) {
656 base::ScopedTempDir scoped_temp_dir
;
657 EXPECT_TRUE(scoped_temp_dir
.CreateUniqueTempDir());
658 base::FilePath pem_path
= test_data_dir_
.
659 AppendASCII("keybinding").AppendASCII("keybinding.pem");
660 base::FilePath path_v1
= PackExtensionWithOptions(
661 test_data_dir_
.AppendASCII("keybinding").AppendASCII("update")
663 scoped_temp_dir
.path().AppendASCII("v1.crx"),
666 base::FilePath path_v2_unassigned
= PackExtensionWithOptions(
667 test_data_dir_
.AppendASCII("keybinding").AppendASCII("update")
668 .AppendASCII("v2_unassigned"),
669 scoped_temp_dir
.path().AppendASCII("v2_unassigned.crx"),
673 ExtensionRegistry
* registry
= ExtensionRegistry::Get(browser()->profile());
674 CommandService
* command_service
= CommandService::Get(browser()->profile());
676 // Install v1 of the extension.
677 ASSERT_TRUE(InstallExtension(path_v1
, 1));
678 EXPECT_TRUE(registry
->GetExtensionById(kId
, ExtensionRegistry::ENABLED
) !=
681 // Verify it has a command of Alt+Shift+F.
682 ui::Accelerator accelerator
= command_service
->FindCommandByName(
683 kId
, manifest_values::kBrowserActionCommandEvent
).accelerator();
684 EXPECT_EQ(ui::VKEY_F
, accelerator
.key_code());
685 EXPECT_FALSE(accelerator
.IsCtrlDown());
686 EXPECT_TRUE(accelerator
.IsShiftDown());
687 EXPECT_TRUE(accelerator
.IsAltDown());
689 // Update to version 2 without keybinding assigned.
690 EXPECT_TRUE(UpdateExtension(kId
, path_v2_unassigned
, 0));
691 EXPECT_TRUE(registry
->GetExtensionById(kId
, ExtensionRegistry::ENABLED
) !=
694 // Verify the keybinding gets set to nothing.
695 accelerator
= command_service
->FindCommandByName(
696 kId
, manifest_values::kBrowserActionCommandEvent
).accelerator();
697 EXPECT_EQ(ui::VKEY_UNKNOWN
, accelerator
.key_code());
700 IN_PROC_BROWSER_TEST_F(CommandsApiTest
,
701 ShortcutAddedOnUpdateAfterBeingAssignedByUser
) {
702 base::ScopedTempDir scoped_temp_dir
;
703 EXPECT_TRUE(scoped_temp_dir
.CreateUniqueTempDir());
704 base::FilePath pem_path
= test_data_dir_
.
705 AppendASCII("keybinding").AppendASCII("keybinding.pem");
706 base::FilePath path_v1_unassigned
= PackExtensionWithOptions(
707 test_data_dir_
.AppendASCII("keybinding").AppendASCII("update")
708 .AppendASCII("v1_unassigned"),
709 scoped_temp_dir
.path().AppendASCII("v1_unassigned.crx"),
712 base::FilePath path_v2
= PackExtensionWithOptions(
713 test_data_dir_
.AppendASCII("keybinding").AppendASCII("update")
715 scoped_temp_dir
.path().AppendASCII("v2.crx"),
719 ExtensionRegistry
* registry
= ExtensionRegistry::Get(browser()->profile());
720 CommandService
* command_service
= CommandService::Get(browser()->profile());
722 // Install v1 of the extension without keybinding assigned.
723 ASSERT_TRUE(InstallExtension(path_v1_unassigned
, 1));
724 EXPECT_TRUE(registry
->GetExtensionById(kId
, ExtensionRegistry::ENABLED
) !=
727 // Verify it is set to nothing.
728 ui::Accelerator accelerator
= command_service
->FindCommandByName(
729 kId
, manifest_values::kBrowserActionCommandEvent
).accelerator();
730 EXPECT_EQ(ui::VKEY_UNKNOWN
, accelerator
.key_code());
732 // Simulate the user setting the keybinding to Alt+Shift+G.
733 command_service
->UpdateKeybindingPrefs(
734 kId
, manifest_values::kBrowserActionCommandEvent
, kAltShiftG
);
736 // Update to version 2 with keybinding.
737 EXPECT_TRUE(UpdateExtension(kId
, path_v2
, 0));
738 EXPECT_TRUE(registry
->GetExtensionById(kId
, ExtensionRegistry::ENABLED
) !=
741 // Verify the previously-set keybinding is still set.
742 accelerator
= command_service
->FindCommandByName(
743 kId
, manifest_values::kBrowserActionCommandEvent
).accelerator();
744 EXPECT_EQ(ui::VKEY_G
, accelerator
.key_code());
745 EXPECT_FALSE(accelerator
.IsCtrlDown());
746 EXPECT_TRUE(accelerator
.IsShiftDown());
747 EXPECT_TRUE(accelerator
.IsAltDown());
750 IN_PROC_BROWSER_TEST_F(CommandsApiTest
,
751 ShortcutChangedOnUpdateAfterBeingReassignedByUser
) {
752 base::ScopedTempDir scoped_temp_dir
;
753 EXPECT_TRUE(scoped_temp_dir
.CreateUniqueTempDir());
754 base::FilePath pem_path
= test_data_dir_
.
755 AppendASCII("keybinding").AppendASCII("keybinding.pem");
756 base::FilePath path_v1
= PackExtensionWithOptions(
757 test_data_dir_
.AppendASCII("keybinding").AppendASCII("update")
759 scoped_temp_dir
.path().AppendASCII("v1.crx"),
762 base::FilePath path_v2_reassigned
= PackExtensionWithOptions(
763 test_data_dir_
.AppendASCII("keybinding").AppendASCII("update")
764 .AppendASCII("v2_reassigned"),
765 scoped_temp_dir
.path().AppendASCII("v2_reassigned.crx"),
769 ExtensionRegistry
* registry
= ExtensionRegistry::Get(browser()->profile());
770 CommandService
* command_service
= CommandService::Get(browser()->profile());
772 // Install v1 of the extension.
773 ASSERT_TRUE(InstallExtension(path_v1
, 1));
774 EXPECT_TRUE(registry
->GetExtensionById(kId
, ExtensionRegistry::ENABLED
) !=
777 // Verify it has a command of Alt+Shift+F.
778 ui::Accelerator accelerator
= command_service
->FindCommandByName(
779 kId
, manifest_values::kBrowserActionCommandEvent
).accelerator();
780 EXPECT_EQ(ui::VKEY_F
, accelerator
.key_code());
781 EXPECT_FALSE(accelerator
.IsCtrlDown());
782 EXPECT_TRUE(accelerator
.IsShiftDown());
783 EXPECT_TRUE(accelerator
.IsAltDown());
785 // Simulate the user setting the keybinding to Alt+Shift+G.
786 command_service
->UpdateKeybindingPrefs(
787 kId
, manifest_values::kBrowserActionCommandEvent
, kAltShiftG
);
789 // Update to version 2 with different keybinding assigned.
790 EXPECT_TRUE(UpdateExtension(kId
, path_v2_reassigned
, 0));
791 EXPECT_TRUE(registry
->GetExtensionById(kId
, ExtensionRegistry::ENABLED
) !=
794 // Verify it has a command of Alt+Shift+G.
795 accelerator
= command_service
->FindCommandByName(
796 kId
, manifest_values::kBrowserActionCommandEvent
).accelerator();
797 EXPECT_EQ(ui::VKEY_G
, accelerator
.key_code());
798 EXPECT_FALSE(accelerator
.IsCtrlDown());
799 EXPECT_TRUE(accelerator
.IsShiftDown());
800 EXPECT_TRUE(accelerator
.IsAltDown());
803 // Test that Media keys do not overwrite previous settings.
804 IN_PROC_BROWSER_TEST_F(CommandsApiTest
,
805 MediaKeyShortcutChangedOnUpdateAfterBeingReassignedByUser
) {
806 base::ScopedTempDir scoped_temp_dir
;
807 EXPECT_TRUE(scoped_temp_dir
.CreateUniqueTempDir());
808 base::FilePath pem_path
= test_data_dir_
.
809 AppendASCII("keybinding").AppendASCII("keybinding.pem");
810 base::FilePath path_v1
= PackExtensionWithOptions(
811 test_data_dir_
.AppendASCII("keybinding").AppendASCII("update")
812 .AppendASCII("mk_v1"),
813 scoped_temp_dir
.path().AppendASCII("mk_v1.crx"),
816 base::FilePath path_v2_reassigned
= PackExtensionWithOptions(
817 test_data_dir_
.AppendASCII("keybinding").AppendASCII("update")
818 .AppendASCII("mk_v2"),
819 scoped_temp_dir
.path().AppendASCII("mk_v2.crx"),
823 ExtensionRegistry
* registry
= ExtensionRegistry::Get(browser()->profile());
824 CommandService
* command_service
= CommandService::Get(browser()->profile());
826 // Install v1 of the extension.
827 ASSERT_TRUE(InstallExtension(path_v1
, 1));
828 EXPECT_TRUE(registry
->GetExtensionById(kId
, ExtensionRegistry::ENABLED
) !=
831 // Verify it has a command of MediaPlayPause.
832 ui::Accelerator accelerator
= command_service
->FindCommandByName(
833 kId
, kMediaKeyTestCommand
).accelerator();
834 EXPECT_EQ(ui::VKEY_MEDIA_PLAY_PAUSE
, accelerator
.key_code());
835 EXPECT_FALSE(accelerator
.IsCtrlDown());
836 EXPECT_FALSE(accelerator
.IsShiftDown());
837 EXPECT_FALSE(accelerator
.IsAltDown());
839 // Simulate the user setting the keybinding to Alt+Shift+G.
840 command_service
->UpdateKeybindingPrefs(
841 kId
, kMediaKeyTestCommand
, kAltShiftG
);
843 // Update to version 2 with different keybinding assigned.
844 EXPECT_TRUE(UpdateExtension(kId
, path_v2_reassigned
, 0));
845 EXPECT_TRUE(registry
->GetExtensionById(kId
, ExtensionRegistry::ENABLED
) !=
848 // Verify it has a command of Alt+Shift+G.
849 accelerator
= command_service
->FindCommandByName(
850 kId
, kMediaKeyTestCommand
).accelerator();
851 EXPECT_EQ(ui::VKEY_G
, accelerator
.key_code());
852 EXPECT_FALSE(accelerator
.IsCtrlDown());
853 EXPECT_TRUE(accelerator
.IsShiftDown());
854 EXPECT_TRUE(accelerator
.IsAltDown());
857 IN_PROC_BROWSER_TEST_F(CommandsApiTest
,
858 ShortcutRemovedOnUpdateAfterBeingReassignedByUser
) {
859 base::ScopedTempDir scoped_temp_dir
;
860 EXPECT_TRUE(scoped_temp_dir
.CreateUniqueTempDir());
861 base::FilePath pem_path
= test_data_dir_
.
862 AppendASCII("keybinding").AppendASCII("keybinding.pem");
863 base::FilePath path_v1
= PackExtensionWithOptions(
864 test_data_dir_
.AppendASCII("keybinding").AppendASCII("update")
866 scoped_temp_dir
.path().AppendASCII("v1.crx"),
869 base::FilePath path_v2_unassigned
= PackExtensionWithOptions(
870 test_data_dir_
.AppendASCII("keybinding").AppendASCII("update")
871 .AppendASCII("v2_unassigned"),
872 scoped_temp_dir
.path().AppendASCII("v2_unassigned.crx"),
876 ExtensionRegistry
* registry
= ExtensionRegistry::Get(browser()->profile());
877 CommandService
* command_service
= CommandService::Get(browser()->profile());
879 // Install v1 of the extension.
880 ASSERT_TRUE(InstallExtension(path_v1
, 1));
881 EXPECT_TRUE(registry
->GetExtensionById(kId
, ExtensionRegistry::ENABLED
) !=
884 // Verify it has a command of Alt+Shift+F.
885 ui::Accelerator accelerator
= command_service
->FindCommandByName(
886 kId
, manifest_values::kBrowserActionCommandEvent
).accelerator();
887 EXPECT_EQ(ui::VKEY_F
, accelerator
.key_code());
888 EXPECT_FALSE(accelerator
.IsCtrlDown());
889 EXPECT_TRUE(accelerator
.IsShiftDown());
890 EXPECT_TRUE(accelerator
.IsAltDown());
892 // Simulate the user reassigning the keybinding to Alt+Shift+G.
893 command_service
->UpdateKeybindingPrefs(
894 kId
, manifest_values::kBrowserActionCommandEvent
, kAltShiftG
);
896 // Update to version 2 without keybinding assigned.
897 EXPECT_TRUE(UpdateExtension(kId
, path_v2_unassigned
, 0));
898 EXPECT_TRUE(registry
->GetExtensionById(kId
, ExtensionRegistry::ENABLED
) !=
901 // Verify the keybinding is still set.
902 accelerator
= command_service
->FindCommandByName(
903 kId
, manifest_values::kBrowserActionCommandEvent
).accelerator();
904 EXPECT_EQ(ui::VKEY_G
, accelerator
.key_code());
905 EXPECT_FALSE(accelerator
.IsCtrlDown());
906 EXPECT_TRUE(accelerator
.IsShiftDown());
907 EXPECT_TRUE(accelerator
.IsAltDown());
911 #if defined(OS_CHROMEOS) && !defined(NDEBUG)
912 // TODO(dtseng): Test times out on Chrome OS debug. See http://crbug.com/412456.
913 #define MAYBE_ContinuePropagation DISABLED_ContinuePropagation
915 #define MAYBE_ContinuePropagation ContinuePropagation
918 IN_PROC_BROWSER_TEST_F(CommandsApiTest
, MAYBE_ContinuePropagation
) {
919 // Setup the environment.
920 ASSERT_TRUE(test_server()->Start());
921 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
922 ASSERT_TRUE(RunExtensionTest("keybinding/continue_propagation")) << message_
;
923 ui_test_utils::NavigateToURL(
924 browser(), test_server()->GetURL("files/extensions/test_file.txt"));
926 ResultCatcher catcher
;
928 // Activate the shortcut (Ctrl+Shift+F). The page should capture the
929 // keystroke and not the extension since |onCommand| has no event listener
931 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
932 browser(), ui::VKEY_F
, true, true, false, false));
933 ASSERT_TRUE(catcher
.GetNextResult());
935 // Now, the extension should have added an |onCommand| event listener.
936 // Send the same key, but the |onCommand| listener should now receive it.
937 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
938 browser(), ui::VKEY_F
, true, true, false, false));
939 ASSERT_TRUE(catcher
.GetNextResult());
941 // The extension should now have removed its |onCommand| event listener.
942 // Finally, the page should again receive the key.
943 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
944 browser(), ui::VKEY_F
, true, true, false, false));
945 ASSERT_TRUE(catcher
.GetNextResult());
948 // Test is only applicable on Chrome OS.
949 #if defined(OS_CHROMEOS)
950 // http://crbug.com/410534
951 #if defined(USE_OZONE)
952 #define MAYBE_ChromeOSConversions DISABLED_ChromeOSConversions
954 #define MAYBE_ChromeOSConversions ChromeOSConversions
956 IN_PROC_BROWSER_TEST_F(CommandsApiTest
, MAYBE_ChromeOSConversions
) {
957 RunChromeOSConversionTest("keybinding/chromeos_conversions");
959 #endif // OS_CHROMEOS
961 // Make sure component extensions retain keybindings after removal then
963 IN_PROC_BROWSER_TEST_F(CommandsApiTest
, AddRemoveAddComponentExtension
) {
964 ASSERT_TRUE(test_server()->Start());
965 ASSERT_TRUE(RunComponentExtensionTest("keybinding/component")) << message_
;
967 extensions::ExtensionSystem::Get(browser()->profile())
968 ->extension_service()
970 ->Remove("pkplfbidichfdicaijlchgnapepdginl");
972 ASSERT_TRUE(RunComponentExtensionTest("keybinding/component")) << message_
;
975 } // namespace extensions