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/browser/extensions/active_tab_permission_granter.h"
7 #include "chrome/browser/extensions/api/commands/command_service.h"
8 #include "chrome/browser/extensions/browser_action_test_util.h"
9 #include "chrome/browser/extensions/extension_action.h"
10 #include "chrome/browser/extensions/extension_action_manager.h"
11 #include "chrome/browser/extensions/extension_apitest.h"
12 #include "chrome/browser/extensions/tab_helper.h"
13 #include "chrome/browser/sessions/session_tab_helper.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/tabs/tab_strip_model.h"
16 #include "chrome/test/base/interactive_test_utils.h"
17 #include "chrome/test/base/ui_test_utils.h"
18 #include "content/public/browser/notification_service.h"
19 #include "content/public/browser/web_contents.h"
20 #include "content/public/test/browser_test_utils.h"
21 #include "extensions/browser/extension_registry.h"
22 #include "extensions/common/extension.h"
23 #include "extensions/common/feature_switch.h"
24 #include "extensions/common/manifest_constants.h"
25 #include "extensions/common/permissions/permissions_data.h"
26 #include "extensions/test/result_catcher.h"
28 using content::WebContents;
30 namespace extensions {
33 // This extension ID is used for tests require a stable ID over multiple
34 // extension installs.
35 const char kId[] = "pgoakhfeplldmjheffidklpoklkppipp";
37 // Default keybinding to use for emulating user-defined shortcut overrides. The
38 // test extensions use Alt+Shift+F and Alt+Shift+H.
39 const char kAltShiftG[] = "Alt+Shift+G";
41 // Named command for media key overwrite test.
42 const char kMediaKeyTestCommand[] = "test_mediakeys_update";
46 class CommandsApiTest : public ExtensionApiTest {
49 ~CommandsApiTest() override {}
52 BrowserActionTestUtil GetBrowserActionsBar() {
53 return BrowserActionTestUtil(browser());
56 bool IsGrantedForTab(const Extension* extension,
57 const content::WebContents* web_contents) {
58 return extension->permissions_data()->HasAPIPermissionForTab(
59 SessionTabHelper::IdForTab(web_contents), APIPermission::kTab);
62 #if defined(OS_CHROMEOS)
63 void RunChromeOSConversionTest(const std::string& extension_path) {
64 // Setup the environment.
65 ASSERT_TRUE(test_server()->Start());
66 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
67 ASSERT_TRUE(RunExtensionTest(extension_path)) << message_;
68 ui_test_utils::NavigateToURL(
69 browser(), test_server()->GetURL("files/extensions/test_file.txt"));
71 ResultCatcher catcher;
73 // Send all expected keys (Search+Shift+{Left, Up, Right, Down}).
74 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
75 browser(), ui::VKEY_LEFT, false, true, false, true));
76 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
77 browser(), ui::VKEY_UP, false, true, false, true));
78 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
79 browser(), ui::VKEY_RIGHT, false, true, false, true));
80 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
81 browser(), ui::VKEY_DOWN, false, true, false, true));
83 ASSERT_TRUE(catcher.GetNextResult());
88 // Test the basic functionality of the Keybinding API:
89 // - That pressing the shortcut keys should perform actions (activate the
90 // browser action or send an event).
91 // - Note: Page action keybindings are tested in PageAction test below.
92 // - The shortcut keys taken by one extension are not overwritten by the last
93 // installed extension.
94 IN_PROC_BROWSER_TEST_F(CommandsApiTest, Basic) {
95 ASSERT_TRUE(test_server()->Start());
96 ASSERT_TRUE(RunExtensionTest("keybinding/basics")) << message_;
97 const Extension* extension = GetSingleLoadedExtension();
98 ASSERT_TRUE(extension) << message_;
100 // Load this extension, which uses the same keybindings but sets the page
101 // to different colors. This is so we can see that it doesn't interfere. We
102 // don't test this extension in any other way (it should otherwise be
103 // immaterial to this test).
104 ASSERT_TRUE(RunExtensionTest("keybinding/conflicting")) << message_;
106 // Test that there are two browser actions in the toolbar.
107 ASSERT_EQ(2, GetBrowserActionsBar().NumberOfBrowserActions());
109 ui_test_utils::NavigateToURL(browser(),
110 test_server()->GetURL("files/extensions/test_file.txt"));
112 // activeTab shouldn't have been granted yet.
113 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
116 EXPECT_FALSE(IsGrantedForTab(extension, tab));
118 // Activate the shortcut (Ctrl+Shift+F).
119 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
120 browser(), ui::VKEY_F, true, true, false, false));
122 // activeTab should now be granted.
123 EXPECT_TRUE(IsGrantedForTab(extension, tab));
125 // Verify the command worked.
127 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
129 "setInterval(function(){"
130 " if(document.body.bgColor == 'red'){"
131 " window.domAutomationController.send(true)}}, 100)",
135 // Activate the shortcut (Ctrl+Shift+Y).
136 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
137 browser(), ui::VKEY_Y, true, true, false, false));
140 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
142 "setInterval(function(){"
143 " if(document.body.bgColor == 'blue'){"
144 " window.domAutomationController.send(true)}}, 100)",
149 // Flaky on linux and chromeos, http://crbug.com/165825
150 #if defined(OS_MACOSX) || defined(OS_WIN)
151 #define MAYBE_PageAction PageAction
153 #define MAYBE_PageAction DISABLED_PageAction
155 IN_PROC_BROWSER_TEST_F(CommandsApiTest, MAYBE_PageAction) {
156 ASSERT_TRUE(test_server()->Start());
157 ASSERT_TRUE(RunExtensionTest("keybinding/page_action")) << message_;
158 const Extension* extension = GetSingleLoadedExtension();
159 ASSERT_TRUE(extension) << message_;
162 // Load a page, the extension will detect the navigation and request to show
163 // the page action icon.
164 ResultCatcher catcher;
165 ui_test_utils::NavigateToURL(browser(),
166 test_server()->GetURL("files/extensions/test_file.txt"));
167 ASSERT_TRUE(catcher.GetNextResult());
170 // Make sure it appears and is the right one.
171 ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1));
172 int tab_id = SessionTabHelper::FromWebContents(
173 browser()->tab_strip_model()->GetActiveWebContents())->session_id().id();
174 ExtensionAction* action =
175 ExtensionActionManager::Get(browser()->profile())->
176 GetPageAction(*extension);
178 EXPECT_EQ("Make this page red", action->GetTitle(tab_id));
180 // Activate the shortcut (Alt+Shift+F).
181 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
182 browser(), ui::VKEY_F, false, true, true, false));
184 // Verify the command worked (the page action turns the page red).
185 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
187 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
189 "setInterval(function(){"
190 " if(document.body.bgColor == 'red'){"
191 " window.domAutomationController.send(true)}}, 100)",
196 // This test validates that the getAll query API function returns registered
197 // commands as well as synthesized ones and that inactive commands (like the
198 // synthesized ones are in nature) have no shortcuts.
199 IN_PROC_BROWSER_TEST_F(CommandsApiTest, SynthesizedCommand) {
200 ASSERT_TRUE(test_server()->Start());
201 ASSERT_TRUE(RunExtensionTest("keybinding/synthesized")) << message_;
204 // This test validates that an extension cannot request a shortcut that is
205 // already in use by Chrome.
206 IN_PROC_BROWSER_TEST_F(CommandsApiTest, DontOverwriteSystemShortcuts) {
207 ASSERT_TRUE(test_server()->Start());
209 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
211 ASSERT_TRUE(RunExtensionTest("keybinding/dont_overwrite_system")) << message_;
213 ui_test_utils::NavigateToURL(browser(),
214 test_server()->GetURL("files/extensions/test_file.txt"));
216 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
219 // Activate the shortcut (Alt+Shift+F) to make the page blue.
221 ResultCatcher catcher;
222 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
223 browser(), ui::VKEY_F, false, true, true, false));
224 ASSERT_TRUE(catcher.GetNextResult());
228 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
230 "setInterval(function() {"
231 " if (document.body.bgColor == 'blue') {"
232 " window.domAutomationController.send(true)}}, 100)",
236 // Activate the bookmark shortcut (Ctrl+D) to make the page green (should not
237 // work without requesting via chrome_settings_overrides).
238 #if defined(OS_MACOSX)
239 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
240 browser(), ui::VKEY_D, false, false, false, true));
242 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
243 browser(), ui::VKEY_D, true, false, false, false));
246 // The page should still be blue.
248 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
250 "setInterval(function() {"
251 " if (document.body.bgColor == 'blue') {"
252 " window.domAutomationController.send(true)}}, 100)",
256 // Activate the shortcut (Ctrl+F) to make the page red (should not work).
257 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
258 browser(), ui::VKEY_F, true, false, false, false));
260 // The page should still be blue.
262 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
264 "setInterval(function() {"
265 " if (document.body.bgColor == 'blue') {"
266 " window.domAutomationController.send(true)}}, 100)",
271 // This test validates that an extension can override the Chrome bookmark
272 // shortcut if it has requested to do so.
273 IN_PROC_BROWSER_TEST_F(CommandsApiTest, OverwriteBookmarkShortcut) {
274 ASSERT_TRUE(test_server()->Start());
276 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
278 // This functionality requires a feature flag.
279 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
280 "--enable-override-bookmarks-ui",
283 ASSERT_TRUE(RunExtensionTest("keybinding/overwrite_bookmark_shortcut"))
286 ui_test_utils::NavigateToURL(browser(),
287 test_server()->GetURL("files/extensions/test_file.txt"));
289 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
292 // Activate the shortcut (Ctrl+D) to make the page green.
294 ResultCatcher catcher;
295 #if defined(OS_MACOSX)
296 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
297 browser(), ui::VKEY_D, false, false, false, true));
299 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
300 browser(), ui::VKEY_D, true, false, false, false));
302 ASSERT_TRUE(catcher.GetNextResult());
306 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
308 "setInterval(function() {"
309 " if (document.body.bgColor == 'green') {"
310 " window.domAutomationController.send(true)}}, 100)",
315 // This test validates that an extension override of the Chrome bookmark
316 // shortcut does not supersede the same keybinding by web pages.
317 IN_PROC_BROWSER_TEST_F(CommandsApiTest,
318 OverwriteBookmarkShortcutDoesNotOverrideWebKeybinding) {
319 ASSERT_TRUE(test_server()->Start());
321 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
323 // This functionality requires a feature flag.
324 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
325 "--enable-override-bookmarks-ui",
328 ASSERT_TRUE(RunExtensionTest("keybinding/overwrite_bookmark_shortcut"))
331 ui_test_utils::NavigateToURL(browser(),
332 test_server()->GetURL(
333 "files/extensions/test_file_with_ctrl-d_keybinding.html"));
335 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
338 // Activate the shortcut (Ctrl+D) which should be handled by the page and make
339 // the background color magenta.
340 #if defined(OS_MACOSX)
341 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
342 browser(), ui::VKEY_D, false, false, false, true));
344 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
345 browser(), ui::VKEY_D, true, false, false, false));
349 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
351 "setInterval(function() {"
352 " if (document.body.bgColor == 'magenta') {"
353 " window.domAutomationController.send(true)}}, 100)",
358 // This test validates that user-set override of the Chrome bookmark shortcut in
359 // an extension that does not request it does supersede the same keybinding by
361 IN_PROC_BROWSER_TEST_F(CommandsApiTest,
362 OverwriteBookmarkShortcutByUserOverridesWebKeybinding) {
363 ASSERT_TRUE(test_server()->Start());
365 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
367 // This functionality requires a feature flag.
368 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
369 "--enable-override-bookmarks-ui",
372 ASSERT_TRUE(RunExtensionTest("keybinding/basics"))
375 CommandService* command_service = CommandService::Get(browser()->profile());
377 const Extension* extension = GetSingleLoadedExtension();
378 // Simulate the user setting the keybinding to Ctrl+D.
379 #if defined(OS_MACOSX)
380 const char hotkey[] = "Command+D";
382 const char hotkey[] = "Ctrl+D";
383 #endif // defined(OS_MACOSX)
384 command_service->UpdateKeybindingPrefs(
385 extension->id(), manifest_values::kBrowserActionCommandEvent, hotkey);
387 ui_test_utils::NavigateToURL(browser(),
388 test_server()->GetURL(
389 "files/extensions/test_file_with_ctrl-d_keybinding.html"));
391 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
394 // Activate the shortcut (Ctrl+D) which should be handled by the extension and
395 // make the background color red.
396 #if defined(OS_MACOSX)
397 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
398 browser(), ui::VKEY_D, false, false, false, true));
400 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
401 browser(), ui::VKEY_D, true, false, false, false));
405 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
407 "setInterval(function() {"
408 " if (document.body.bgColor == 'red') {"
409 " window.domAutomationController.send(true)}}, 100)",
415 // Currently this feature is implemented on Windows only.
416 #define MAYBE_AllowDuplicatedMediaKeys AllowDuplicatedMediaKeys
418 #define MAYBE_AllowDuplicatedMediaKeys DISABLED_AllowDuplicatedMediaKeys
421 // Test that media keys go to all extensions that register for them.
422 IN_PROC_BROWSER_TEST_F(CommandsApiTest, MAYBE_AllowDuplicatedMediaKeys) {
423 ResultCatcher catcher;
424 ASSERT_TRUE(RunExtensionTest("keybinding/non_global_media_keys_0"))
426 ASSERT_TRUE(catcher.GetNextResult());
427 ASSERT_TRUE(RunExtensionTest("keybinding/non_global_media_keys_1"))
429 ASSERT_TRUE(catcher.GetNextResult());
431 // Activate the Media Stop key.
432 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
433 browser(), ui::VKEY_MEDIA_STOP, false, false, false, false));
435 // We should get two success result.
436 ASSERT_TRUE(catcher.GetNextResult());
437 ASSERT_TRUE(catcher.GetNextResult());
440 IN_PROC_BROWSER_TEST_F(CommandsApiTest, ShortcutAddedOnUpdate) {
441 base::ScopedTempDir scoped_temp_dir;
442 EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
443 base::FilePath pem_path = test_data_dir_.
444 AppendASCII("keybinding").AppendASCII("keybinding.pem");
445 base::FilePath path_v1_unassigned = PackExtensionWithOptions(
446 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
447 .AppendASCII("v1_unassigned"),
448 scoped_temp_dir.path().AppendASCII("v1_unassigned.crx"),
451 base::FilePath path_v2 = PackExtensionWithOptions(
452 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
454 scoped_temp_dir.path().AppendASCII("v2.crx"),
458 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
459 CommandService* command_service = CommandService::Get(browser()->profile());
461 // Install v1 of the extension without keybinding assigned.
462 ASSERT_TRUE(InstallExtension(path_v1_unassigned, 1));
463 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
466 // Verify it is set to nothing.
467 ui::Accelerator accelerator = command_service->FindCommandByName(
468 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
469 EXPECT_EQ(ui::VKEY_UNKNOWN, accelerator.key_code());
471 // Update to version 2 with keybinding.
472 EXPECT_TRUE(UpdateExtension(kId, path_v2, 0));
473 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
476 // Verify it has a command of Alt+Shift+F.
477 accelerator = command_service->FindCommandByName(
478 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
479 EXPECT_EQ(ui::VKEY_F, accelerator.key_code());
480 EXPECT_FALSE(accelerator.IsCtrlDown());
481 EXPECT_TRUE(accelerator.IsShiftDown());
482 EXPECT_TRUE(accelerator.IsAltDown());
485 IN_PROC_BROWSER_TEST_F(CommandsApiTest, ShortcutChangedOnUpdate) {
486 base::ScopedTempDir scoped_temp_dir;
487 EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
488 base::FilePath pem_path = test_data_dir_.
489 AppendASCII("keybinding").AppendASCII("keybinding.pem");
490 base::FilePath path_v1 = PackExtensionWithOptions(
491 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
493 scoped_temp_dir.path().AppendASCII("v1.crx"),
496 base::FilePath path_v2_reassigned = PackExtensionWithOptions(
497 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
498 .AppendASCII("v2_reassigned"),
499 scoped_temp_dir.path().AppendASCII("v2_reassigned.crx"),
503 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
504 CommandService* command_service = CommandService::Get(browser()->profile());
506 // Install v1 of the extension.
507 ASSERT_TRUE(InstallExtension(path_v1, 1));
508 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
511 // Verify it has a command of Alt+Shift+F.
512 ui::Accelerator accelerator = command_service->FindCommandByName(
513 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
514 EXPECT_EQ(ui::VKEY_F, accelerator.key_code());
515 EXPECT_FALSE(accelerator.IsCtrlDown());
516 EXPECT_TRUE(accelerator.IsShiftDown());
517 EXPECT_TRUE(accelerator.IsAltDown());
519 // Update to version 2 with different keybinding assigned.
520 EXPECT_TRUE(UpdateExtension(kId, path_v2_reassigned, 0));
521 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
524 // Verify it has a command of Alt+Shift+H.
525 accelerator = command_service->FindCommandByName(
526 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
527 EXPECT_EQ(ui::VKEY_H, accelerator.key_code());
528 EXPECT_FALSE(accelerator.IsCtrlDown());
529 EXPECT_TRUE(accelerator.IsShiftDown());
530 EXPECT_TRUE(accelerator.IsAltDown());
533 IN_PROC_BROWSER_TEST_F(CommandsApiTest, ShortcutRemovedOnUpdate) {
534 base::ScopedTempDir scoped_temp_dir;
535 EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
536 base::FilePath pem_path = test_data_dir_.
537 AppendASCII("keybinding").AppendASCII("keybinding.pem");
538 base::FilePath path_v1 = PackExtensionWithOptions(
539 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
541 scoped_temp_dir.path().AppendASCII("v1.crx"),
544 base::FilePath path_v2_unassigned = PackExtensionWithOptions(
545 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
546 .AppendASCII("v2_unassigned"),
547 scoped_temp_dir.path().AppendASCII("v2_unassigned.crx"),
551 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
552 CommandService* command_service = CommandService::Get(browser()->profile());
554 // Install v1 of the extension.
555 ASSERT_TRUE(InstallExtension(path_v1, 1));
556 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
559 // Verify it has a command of Alt+Shift+F.
560 ui::Accelerator accelerator = command_service->FindCommandByName(
561 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
562 EXPECT_EQ(ui::VKEY_F, accelerator.key_code());
563 EXPECT_FALSE(accelerator.IsCtrlDown());
564 EXPECT_TRUE(accelerator.IsShiftDown());
565 EXPECT_TRUE(accelerator.IsAltDown());
567 // Update to version 2 without keybinding assigned.
568 EXPECT_TRUE(UpdateExtension(kId, path_v2_unassigned, 0));
569 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
572 // Verify the keybinding gets set to nothing.
573 accelerator = command_service->FindCommandByName(
574 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
575 EXPECT_EQ(ui::VKEY_UNKNOWN, accelerator.key_code());
578 IN_PROC_BROWSER_TEST_F(CommandsApiTest,
579 ShortcutAddedOnUpdateAfterBeingAssignedByUser) {
580 base::ScopedTempDir scoped_temp_dir;
581 EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
582 base::FilePath pem_path = test_data_dir_.
583 AppendASCII("keybinding").AppendASCII("keybinding.pem");
584 base::FilePath path_v1_unassigned = PackExtensionWithOptions(
585 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
586 .AppendASCII("v1_unassigned"),
587 scoped_temp_dir.path().AppendASCII("v1_unassigned.crx"),
590 base::FilePath path_v2 = PackExtensionWithOptions(
591 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
593 scoped_temp_dir.path().AppendASCII("v2.crx"),
597 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
598 CommandService* command_service = CommandService::Get(browser()->profile());
600 // Install v1 of the extension without keybinding assigned.
601 ASSERT_TRUE(InstallExtension(path_v1_unassigned, 1));
602 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
605 // Verify it is set to nothing.
606 ui::Accelerator accelerator = command_service->FindCommandByName(
607 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
608 EXPECT_EQ(ui::VKEY_UNKNOWN, accelerator.key_code());
610 // Simulate the user setting the keybinding to Alt+Shift+G.
611 command_service->UpdateKeybindingPrefs(
612 kId, manifest_values::kBrowserActionCommandEvent, kAltShiftG);
614 // Update to version 2 with keybinding.
615 EXPECT_TRUE(UpdateExtension(kId, path_v2, 0));
616 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
619 // Verify the previously-set keybinding is still set.
620 accelerator = command_service->FindCommandByName(
621 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
622 EXPECT_EQ(ui::VKEY_G, accelerator.key_code());
623 EXPECT_FALSE(accelerator.IsCtrlDown());
624 EXPECT_TRUE(accelerator.IsShiftDown());
625 EXPECT_TRUE(accelerator.IsAltDown());
628 IN_PROC_BROWSER_TEST_F(CommandsApiTest,
629 ShortcutChangedOnUpdateAfterBeingReassignedByUser) {
630 base::ScopedTempDir scoped_temp_dir;
631 EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
632 base::FilePath pem_path = test_data_dir_.
633 AppendASCII("keybinding").AppendASCII("keybinding.pem");
634 base::FilePath path_v1 = PackExtensionWithOptions(
635 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
637 scoped_temp_dir.path().AppendASCII("v1.crx"),
640 base::FilePath path_v2_reassigned = PackExtensionWithOptions(
641 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
642 .AppendASCII("v2_reassigned"),
643 scoped_temp_dir.path().AppendASCII("v2_reassigned.crx"),
647 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
648 CommandService* command_service = CommandService::Get(browser()->profile());
650 // Install v1 of the extension.
651 ASSERT_TRUE(InstallExtension(path_v1, 1));
652 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
655 // Verify it has a command of Alt+Shift+F.
656 ui::Accelerator accelerator = command_service->FindCommandByName(
657 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
658 EXPECT_EQ(ui::VKEY_F, accelerator.key_code());
659 EXPECT_FALSE(accelerator.IsCtrlDown());
660 EXPECT_TRUE(accelerator.IsShiftDown());
661 EXPECT_TRUE(accelerator.IsAltDown());
663 // Simulate the user setting the keybinding to Alt+Shift+G.
664 command_service->UpdateKeybindingPrefs(
665 kId, manifest_values::kBrowserActionCommandEvent, kAltShiftG);
667 // Update to version 2 with different keybinding assigned.
668 EXPECT_TRUE(UpdateExtension(kId, path_v2_reassigned, 0));
669 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
672 // Verify it has a command of Alt+Shift+G.
673 accelerator = command_service->FindCommandByName(
674 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
675 EXPECT_EQ(ui::VKEY_G, accelerator.key_code());
676 EXPECT_FALSE(accelerator.IsCtrlDown());
677 EXPECT_TRUE(accelerator.IsShiftDown());
678 EXPECT_TRUE(accelerator.IsAltDown());
681 // Test that Media keys do not overwrite previous settings.
682 IN_PROC_BROWSER_TEST_F(CommandsApiTest,
683 MediaKeyShortcutChangedOnUpdateAfterBeingReassignedByUser) {
684 base::ScopedTempDir scoped_temp_dir;
685 EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
686 base::FilePath pem_path = test_data_dir_.
687 AppendASCII("keybinding").AppendASCII("keybinding.pem");
688 base::FilePath path_v1 = PackExtensionWithOptions(
689 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
690 .AppendASCII("mk_v1"),
691 scoped_temp_dir.path().AppendASCII("mk_v1.crx"),
694 base::FilePath path_v2_reassigned = PackExtensionWithOptions(
695 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
696 .AppendASCII("mk_v2"),
697 scoped_temp_dir.path().AppendASCII("mk_v2.crx"),
701 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
702 CommandService* command_service = CommandService::Get(browser()->profile());
704 // Install v1 of the extension.
705 ASSERT_TRUE(InstallExtension(path_v1, 1));
706 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
709 // Verify it has a command of MediaPlayPause.
710 ui::Accelerator accelerator = command_service->FindCommandByName(
711 kId, kMediaKeyTestCommand).accelerator();
712 EXPECT_EQ(ui::VKEY_MEDIA_PLAY_PAUSE, accelerator.key_code());
713 EXPECT_FALSE(accelerator.IsCtrlDown());
714 EXPECT_FALSE(accelerator.IsShiftDown());
715 EXPECT_FALSE(accelerator.IsAltDown());
717 // Simulate the user setting the keybinding to Alt+Shift+G.
718 command_service->UpdateKeybindingPrefs(
719 kId, kMediaKeyTestCommand, kAltShiftG);
721 // Update to version 2 with different keybinding assigned.
722 EXPECT_TRUE(UpdateExtension(kId, path_v2_reassigned, 0));
723 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
726 // Verify it has a command of Alt+Shift+G.
727 accelerator = command_service->FindCommandByName(
728 kId, kMediaKeyTestCommand).accelerator();
729 EXPECT_EQ(ui::VKEY_G, accelerator.key_code());
730 EXPECT_FALSE(accelerator.IsCtrlDown());
731 EXPECT_TRUE(accelerator.IsShiftDown());
732 EXPECT_TRUE(accelerator.IsAltDown());
735 IN_PROC_BROWSER_TEST_F(CommandsApiTest,
736 ShortcutRemovedOnUpdateAfterBeingReassignedByUser) {
737 base::ScopedTempDir scoped_temp_dir;
738 EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
739 base::FilePath pem_path = test_data_dir_.
740 AppendASCII("keybinding").AppendASCII("keybinding.pem");
741 base::FilePath path_v1 = PackExtensionWithOptions(
742 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
744 scoped_temp_dir.path().AppendASCII("v1.crx"),
747 base::FilePath path_v2_unassigned = PackExtensionWithOptions(
748 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
749 .AppendASCII("v2_unassigned"),
750 scoped_temp_dir.path().AppendASCII("v2_unassigned.crx"),
754 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
755 CommandService* command_service = CommandService::Get(browser()->profile());
757 // Install v1 of the extension.
758 ASSERT_TRUE(InstallExtension(path_v1, 1));
759 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
762 // Verify it has a command of Alt+Shift+F.
763 ui::Accelerator accelerator = command_service->FindCommandByName(
764 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
765 EXPECT_EQ(ui::VKEY_F, accelerator.key_code());
766 EXPECT_FALSE(accelerator.IsCtrlDown());
767 EXPECT_TRUE(accelerator.IsShiftDown());
768 EXPECT_TRUE(accelerator.IsAltDown());
770 // Simulate the user reassigning the keybinding to Alt+Shift+G.
771 command_service->UpdateKeybindingPrefs(
772 kId, manifest_values::kBrowserActionCommandEvent, kAltShiftG);
774 // Update to version 2 without keybinding assigned.
775 EXPECT_TRUE(UpdateExtension(kId, path_v2_unassigned, 0));
776 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
779 // Verify the keybinding is still set.
780 accelerator = command_service->FindCommandByName(
781 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
782 EXPECT_EQ(ui::VKEY_G, accelerator.key_code());
783 EXPECT_FALSE(accelerator.IsCtrlDown());
784 EXPECT_TRUE(accelerator.IsShiftDown());
785 EXPECT_TRUE(accelerator.IsAltDown());
789 #if defined(OS_CHROMEOS) && !defined(NDEBUG)
790 // TODO(dtseng): Test times out on Chrome OS debug. See http://crbug.com/412456.
791 #define MAYBE_ContinuePropagation DISABLED_ContinuePropagation
793 #define MAYBE_ContinuePropagation ContinuePropagation
796 IN_PROC_BROWSER_TEST_F(CommandsApiTest, MAYBE_ContinuePropagation) {
797 // Setup the environment.
798 ASSERT_TRUE(test_server()->Start());
799 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
800 ASSERT_TRUE(RunExtensionTest("keybinding/continue_propagation")) << message_;
801 ui_test_utils::NavigateToURL(
802 browser(), test_server()->GetURL("files/extensions/test_file.txt"));
804 ResultCatcher catcher;
806 // Activate the shortcut (Ctrl+Shift+F). The page should capture the
807 // keystroke and not the extension since |onCommand| has no event listener
809 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
810 browser(), ui::VKEY_F, true, true, false, false));
811 ASSERT_TRUE(catcher.GetNextResult());
813 // Now, the extension should have added an |onCommand| event listener.
814 // Send the same key, but the |onCommand| listener should now receive it.
815 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
816 browser(), ui::VKEY_F, true, true, false, false));
817 ASSERT_TRUE(catcher.GetNextResult());
819 // The extension should now have removed its |onCommand| event listener.
820 // Finally, the page should again receive the key.
821 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
822 browser(), ui::VKEY_F, true, true, false, false));
823 ASSERT_TRUE(catcher.GetNextResult());
826 // Test is only applicable on Chrome OS.
827 #if defined(OS_CHROMEOS)
828 // http://crbug.com/410534
829 #if defined(USE_OZONE)
830 #define MAYBE_ChromeOSConversions DISABLED_ChromeOSConversions
832 #define MAYBE_ChromeOSConversions ChromeOSConversions
834 IN_PROC_BROWSER_TEST_F(CommandsApiTest, MAYBE_ChromeOSConversions) {
835 RunChromeOSConversionTest("keybinding/chromeos_conversions");
837 #endif // OS_CHROMEOS
839 } // namespace extensions