Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / extensions / extension_keybinding_apitest.cc
blob6985b547e1881d4e16fa030b5b0d3ee07e33cdad
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 {
37 namespace {
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";
54 #else
55 const char kBookmarkKeybinding[] = "Ctrl+D";
56 #endif // defined(OS_MACOSX)
58 bool SendBookmarkKeyPressSync(Browser* browser) {
59 return ui_test_utils::SendKeyPressSync(
60 browser, ui::VKEY_D,
61 #if defined(OS_MACOSX)
62 false, false, false, true
63 #else
64 true, false, false, false
65 #endif
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 {
74 public:
75 explicit DomMessageListener(content::WebContents* web_contents);
76 ~DomMessageListener() override;
78 // Wait until a message is received.
79 void Wait();
81 // Clears and resets the observer.
82 void Clear();
84 const std::string& message() const { return message_; }
86 private:
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.
93 std::string message_;
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() {
108 observer_.Run();
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).
114 observer_.Reset();
117 content::TestMessageHandler::MessageResponse DomMessageListener::HandleMessage(
118 const std::string& json) {
119 message_ = json;
120 return DONE;
123 void DomMessageListener::Reset() {
124 TestMessageHandler::Reset();
125 message_.clear();
128 } // namespace
130 class CommandsApiTest : public ExtensionApiTest {
131 public:
132 CommandsApiTest() {}
133 ~CommandsApiTest() override {}
135 protected:
136 bool IsGrantedForTab(const Extension* extension,
137 const content::WebContents* web_contents) {
138 return extension->permissions_data()->HasAPIPermissionForTab(
139 SessionTabHelper::IdForTab(web_contents), APIPermission::kTab);
142 #if defined(OS_CHROMEOS)
143 void RunChromeOSConversionTest(const std::string& extension_path) {
144 // Setup the environment.
145 ASSERT_TRUE(test_server()->Start());
146 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
147 ASSERT_TRUE(RunExtensionTest(extension_path)) << message_;
148 ui_test_utils::NavigateToURL(
149 browser(), test_server()->GetURL("files/extensions/test_file.txt"));
151 ResultCatcher catcher;
153 // Send all expected keys (Search+Shift+{Left, Up, Right, Down}).
154 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
155 browser(), ui::VKEY_LEFT, false, true, false, true));
156 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
157 browser(), ui::VKEY_UP, false, true, false, true));
158 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
159 browser(), ui::VKEY_RIGHT, false, true, false, true));
160 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
161 browser(), ui::VKEY_DOWN, false, true, false, true));
163 ASSERT_TRUE(catcher.GetNextResult());
165 #endif // OS_CHROMEOS
168 // Test the basic functionality of the Keybinding API:
169 // - That pressing the shortcut keys should perform actions (activate the
170 // browser action or send an event).
171 // - Note: Page action keybindings are tested in PageAction test below.
172 // - The shortcut keys taken by one extension are not overwritten by the last
173 // installed extension.
174 IN_PROC_BROWSER_TEST_F(CommandsApiTest, Basic) {
175 ASSERT_TRUE(test_server()->Start());
176 ASSERT_TRUE(RunExtensionTest("keybinding/basics")) << message_;
177 const Extension* extension = GetSingleLoadedExtension();
178 ASSERT_TRUE(extension) << message_;
180 // Load this extension, which uses the same keybindings but sets the page
181 // to different colors. This is so we can see that it doesn't interfere. We
182 // don't test this extension in any other way (it should otherwise be
183 // immaterial to this test).
184 ASSERT_TRUE(RunExtensionTest("keybinding/conflicting")) << message_;
186 BrowserActionTestUtil browser_actions_bar(browser());
187 // Test that there are two browser actions in the toolbar.
188 ASSERT_EQ(2, browser_actions_bar.NumberOfBrowserActions());
190 ui_test_utils::NavigateToURL(
191 browser(), test_server()->GetURL("files/extensions/test_file.txt"));
193 // activeTab shouldn't have been granted yet.
194 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
195 ASSERT_TRUE(tab);
197 EXPECT_FALSE(IsGrantedForTab(extension, tab));
199 ExtensionTestMessageListener test_listener(false); // Won't reply.
200 // Activate the browser action shortcut (Ctrl+Shift+F).
201 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
202 browser(), ui::VKEY_F, true, true, false, false));
203 EXPECT_TRUE(test_listener.WaitUntilSatisfied());
204 // activeTab should now be granted.
205 EXPECT_TRUE(IsGrantedForTab(extension, tab));
206 // Verify the command worked.
207 EXPECT_EQ(std::string("basics browser action"), test_listener.message());
209 test_listener.Reset();
210 // Activate the command shortcut (Ctrl+Shift+Y).
211 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
212 browser(), ui::VKEY_Y, true, true, false, false));
213 EXPECT_TRUE(test_listener.WaitUntilSatisfied());
214 EXPECT_EQ(std::string(kBasicsShortcutCommandName), test_listener.message());
217 IN_PROC_BROWSER_TEST_F(CommandsApiTest, PageAction) {
218 ASSERT_TRUE(test_server()->Start());
219 ASSERT_TRUE(RunExtensionTest("keybinding/page_action")) << message_;
220 const Extension* extension = GetSingleLoadedExtension();
221 ASSERT_TRUE(extension) << message_;
224 // Load a page, the extension will detect the navigation and request to show
225 // the page action icon.
226 ResultCatcher catcher;
227 ui_test_utils::NavigateToURL(
228 browser(), test_server()->GetURL("files/extensions/test_file.txt"));
229 ASSERT_TRUE(catcher.GetNextResult());
232 // Make sure it appears and is the right one.
233 ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1));
234 int tab_id = SessionTabHelper::FromWebContents(
235 browser()->tab_strip_model()->GetActiveWebContents())->session_id().id();
236 ExtensionAction* action =
237 ExtensionActionManager::Get(browser()->profile())->
238 GetPageAction(*extension);
239 ASSERT_TRUE(action);
240 EXPECT_EQ("Send message", action->GetTitle(tab_id));
242 ExtensionTestMessageListener test_listener(false); // Won't reply.
243 test_listener.set_extension_id(extension->id());
245 // Activate the shortcut (Alt+Shift+F).
246 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
247 browser(), ui::VKEY_F, false, true, true, false));
249 test_listener.WaitUntilSatisfied();
250 EXPECT_EQ("clicked", test_listener.message());
253 IN_PROC_BROWSER_TEST_F(CommandsApiTest, PageActionKeyUpdated) {
254 ASSERT_TRUE(test_server()->Start());
255 ASSERT_TRUE(RunExtensionTest("keybinding/page_action")) << message_;
256 const Extension* extension = GetSingleLoadedExtension();
257 ASSERT_TRUE(extension) << message_;
259 CommandService* command_service = CommandService::Get(browser()->profile());
260 // Simulate the user setting the keybinding to Alt+Shift+G.
261 command_service->UpdateKeybindingPrefs(
262 extension->id(), manifest_values::kPageActionCommandEvent, kAltShiftG);
265 // Load a page. The extension will detect the navigation and request to show
266 // the page action icon.
267 ResultCatcher catcher;
268 ui_test_utils::NavigateToURL(
269 browser(), test_server()->GetURL("files/extensions/test_file.txt"));
270 ASSERT_TRUE(catcher.GetNextResult());
273 ExtensionTestMessageListener test_listener(false); // Won't reply.
274 test_listener.set_extension_id(extension->id());
276 // Activate the shortcut.
277 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
278 browser(), ui::VKEY_G, false, true, true, false));
280 test_listener.WaitUntilSatisfied();
281 EXPECT_EQ("clicked", test_listener.message());
284 // This test validates that the getAll query API function returns registered
285 // commands as well as synthesized ones and that inactive commands (like the
286 // synthesized ones are in nature) have no shortcuts.
287 IN_PROC_BROWSER_TEST_F(CommandsApiTest, SynthesizedCommand) {
288 ASSERT_TRUE(test_server()->Start());
289 ASSERT_TRUE(RunExtensionTest("keybinding/synthesized")) << message_;
292 // This test validates that an extension cannot request a shortcut that is
293 // already in use by Chrome.
294 IN_PROC_BROWSER_TEST_F(CommandsApiTest, DontOverwriteSystemShortcuts) {
295 ASSERT_TRUE(test_server()->Start());
297 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
299 ASSERT_TRUE(RunExtensionTest("keybinding/dont_overwrite_system")) << message_;
301 ui_test_utils::NavigateToURL(
302 browser(), test_server()->GetURL("files/extensions/test_file.txt"));
304 // Activate the regular shortcut (Alt+Shift+F).
305 ExtensionTestMessageListener alt_shift_f_listener("alt_shift_f", false);
306 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
307 browser(), ui::VKEY_F, false, true, true, false));
308 EXPECT_TRUE(alt_shift_f_listener.WaitUntilSatisfied());
310 // Try to activate the bookmark shortcut (Ctrl+D). This should not work
311 // without requesting via chrome_settings_overrides.
313 // Since keypresses are sent synchronously, we can check this by first sending
314 // Ctrl+D (which shouldn't work), followed by Alt+Shift+F (which should work),
315 // and listening for both. If, by the time we receive the Alt+Shift+F
316 // response, we haven't received a response for Ctrl+D, it is safe to say we
317 // won't receive one.
319 ExtensionTestMessageListener ctrl_d_listener("ctrl_d", false);
320 alt_shift_f_listener.Reset();
321 // Send Ctrl+D.
322 ASSERT_TRUE(SendBookmarkKeyPressSync(browser()));
323 // Send Alt+Shift+F.
324 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
325 browser(), ui::VKEY_F, false, true, true, false));
326 EXPECT_TRUE(alt_shift_f_listener.WaitUntilSatisfied());
327 EXPECT_FALSE(ctrl_d_listener.was_satisfied());
330 // Try to activate the Ctrl+F shortcut (shouldn't work).
332 ExtensionTestMessageListener ctrl_f_listener("ctrl_f", false);
333 alt_shift_f_listener.Reset();
334 // Send Ctrl+F.
335 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
336 browser(), ui::VKEY_F, true, false, false, false));
337 // Send Alt+Shift+F.
338 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
339 browser(), ui::VKEY_F, false, true, true, false));
340 EXPECT_TRUE(alt_shift_f_listener.WaitUntilSatisfied());
341 EXPECT_FALSE(ctrl_f_listener.was_satisfied());
345 // This test validates that an extension can remove the Chrome bookmark shortcut
346 // if it has requested to do so.
347 IN_PROC_BROWSER_TEST_F(CommandsApiTest, RemoveBookmarkShortcut) {
348 ASSERT_TRUE(test_server()->Start());
350 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
352 // This functionality requires a feature flag.
353 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
354 "--enable-override-bookmarks-ui", "1");
356 ASSERT_TRUE(RunExtensionTest("keybinding/remove_bookmark_shortcut"))
357 << message_;
359 EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_BOOKMARK_PAGE));
362 // This test validates that an extension cannot remove the Chrome bookmark
363 // shortcut without being given permission with a feature flag.
364 IN_PROC_BROWSER_TEST_F(CommandsApiTest,
365 RemoveBookmarkShortcutWithoutPermission) {
366 ASSERT_TRUE(test_server()->Start());
368 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
370 EXPECT_TRUE(RunExtensionTestIgnoreManifestWarnings(
371 "keybinding/remove_bookmark_shortcut"));
373 EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_BOOKMARK_PAGE));
376 // This test validates that an extension that removes the Chrome bookmark
377 // shortcut continues to remove the bookmark shortcut with a user-assigned
378 // Ctrl+D shortcut (i.e. it does not trigger the overwrite functionality).
379 IN_PROC_BROWSER_TEST_F(CommandsApiTest,
380 RemoveBookmarkShortcutWithUserKeyBinding) {
381 ASSERT_TRUE(test_server()->Start());
383 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
385 // This functionality requires a feature flag.
386 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
387 "--enable-override-bookmarks-ui", "1");
389 ASSERT_TRUE(RunExtensionTest("keybinding/remove_bookmark_shortcut"))
390 << message_;
392 // Check that the shortcut is removed.
393 CommandService* command_service = CommandService::Get(browser()->profile());
394 const Extension* extension = GetSingleLoadedExtension();
395 // Simulate the user setting a keybinding to Ctrl+D.
396 command_service->UpdateKeybindingPrefs(
397 extension->id(), manifest_values::kBrowserActionCommandEvent,
398 kBookmarkKeybinding);
400 // Force the command enable state to be recalculated.
401 browser()->command_controller()->ExtensionStateChanged();
403 EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_BOOKMARK_PAGE));
406 // This test validates that an extension can override the Chrome bookmark
407 // shortcut if it has requested to do so.
408 IN_PROC_BROWSER_TEST_F(CommandsApiTest, OverwriteBookmarkShortcut) {
409 ASSERT_TRUE(test_server()->Start());
411 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
413 // This functionality requires a feature flag.
414 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
415 "--enable-override-bookmarks-ui", "1");
417 ASSERT_TRUE(RunExtensionTest("keybinding/overwrite_bookmark_shortcut"))
418 << message_;
420 ui_test_utils::NavigateToURL(
421 browser(), test_server()->GetURL("files/extensions/test_file.txt"));
423 // Activate the shortcut (Ctrl+D) to send a test message.
424 ExtensionTestMessageListener test_listener(false); // Won't reply.
425 ASSERT_TRUE(SendBookmarkKeyPressSync(browser()));
426 EXPECT_TRUE(test_listener.WaitUntilSatisfied());
427 EXPECT_EQ(std::string(kOverwriteBookmarkShortcutCommandName),
428 test_listener.message());
431 // This test validates that an extension that requests to override the Chrome
432 // bookmark shortcut, but does not get the keybinding, does not remove the
433 // bookmark UI.
434 IN_PROC_BROWSER_TEST_F(CommandsApiTest,
435 OverwriteBookmarkShortcutWithoutKeybinding) {
436 // This functionality requires a feature flag.
437 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
438 "--enable-override-bookmarks-ui", "1");
440 ASSERT_TRUE(test_server()->Start());
442 EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_BOOKMARK_PAGE));
444 ASSERT_TRUE(RunExtensionTest("keybinding/overwrite_bookmark_shortcut"))
445 << message_;
447 const Extension* extension = GetSingleLoadedExtension();
448 CommandService* command_service = CommandService::Get(browser()->profile());
449 CommandMap commands;
450 // Verify the expected command is present.
451 EXPECT_TRUE(command_service->GetNamedCommands(
452 extension->id(), CommandService::SUGGESTED, CommandService::ANY_SCOPE,
453 &commands));
454 EXPECT_EQ(1u, commands.count(kOverwriteBookmarkShortcutCommandName));
456 // Simulate the user removing the Ctrl+D keybinding from the command.
457 command_service->RemoveKeybindingPrefs(
458 extension->id(), kOverwriteBookmarkShortcutCommandName);
460 // Force the command enable state to be recalculated.
461 browser()->command_controller()->ExtensionStateChanged();
463 EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_BOOKMARK_PAGE));
466 // This test validates that an extension override of the Chrome bookmark
467 // shortcut does not supersede the same keybinding by web pages.
468 IN_PROC_BROWSER_TEST_F(CommandsApiTest,
469 OverwriteBookmarkShortcutDoesNotOverrideWebKeybinding) {
470 ASSERT_TRUE(test_server()->Start());
472 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
474 // This functionality requires a feature flag.
475 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
476 "--enable-override-bookmarks-ui", "1");
478 ASSERT_TRUE(RunExtensionTest("keybinding/overwrite_bookmark_shortcut"))
479 << message_;
481 ui_test_utils::NavigateToURL(
482 browser(),
483 test_server()->GetURL(
484 "files/extensions/test_file_with_ctrl-d_keybinding.html"));
486 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
487 ASSERT_TRUE(tab);
489 // Activate the shortcut (Ctrl+D) which should be handled by the page and send
490 // a test message.
491 DomMessageListener listener(tab);
492 ASSERT_TRUE(SendBookmarkKeyPressSync(browser()));
493 listener.Wait();
494 EXPECT_EQ(std::string("\"web page received\""), listener.message());
497 // This test validates that user-set override of the Chrome bookmark shortcut in
498 // an extension that does not request it does supersede the same keybinding by
499 // web pages.
500 IN_PROC_BROWSER_TEST_F(CommandsApiTest,
501 OverwriteBookmarkShortcutByUserOverridesWebKeybinding) {
502 ASSERT_TRUE(test_server()->Start());
504 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
506 // This functionality requires a feature flag.
507 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
508 "--enable-override-bookmarks-ui", "1");
510 ASSERT_TRUE(RunExtensionTest("keybinding/basics"))
511 << message_;
513 CommandService* command_service = CommandService::Get(browser()->profile());
515 const Extension* extension = GetSingleLoadedExtension();
516 // Simulate the user setting the keybinding to Ctrl+D.
517 command_service->UpdateKeybindingPrefs(
518 extension->id(), manifest_values::kBrowserActionCommandEvent,
519 kBookmarkKeybinding);
521 ui_test_utils::NavigateToURL(
522 browser(),
523 test_server()->GetURL(
524 "files/extensions/test_file_with_ctrl-d_keybinding.html"));
526 ExtensionTestMessageListener test_listener(false); // Won't reply.
527 // Activate the shortcut (Ctrl+D) which should be handled by the extension.
528 ASSERT_TRUE(SendBookmarkKeyPressSync(browser()));
529 EXPECT_TRUE(test_listener.WaitUntilSatisfied());
530 EXPECT_EQ(std::string("basics browser action"), test_listener.message());
533 #if defined(OS_WIN)
534 // Currently this feature is implemented on Windows only.
535 #define MAYBE_AllowDuplicatedMediaKeys AllowDuplicatedMediaKeys
536 #else
537 #define MAYBE_AllowDuplicatedMediaKeys DISABLED_AllowDuplicatedMediaKeys
538 #endif
540 // Test that media keys go to all extensions that register for them.
541 IN_PROC_BROWSER_TEST_F(CommandsApiTest, MAYBE_AllowDuplicatedMediaKeys) {
542 ResultCatcher catcher;
543 ASSERT_TRUE(RunExtensionTest("keybinding/non_global_media_keys_0"))
544 << message_;
545 ASSERT_TRUE(catcher.GetNextResult());
546 ASSERT_TRUE(RunExtensionTest("keybinding/non_global_media_keys_1"))
547 << message_;
548 ASSERT_TRUE(catcher.GetNextResult());
550 // Activate the Media Stop key.
551 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
552 browser(), ui::VKEY_MEDIA_STOP, false, false, false, false));
554 // We should get two success result.
555 ASSERT_TRUE(catcher.GetNextResult());
556 ASSERT_TRUE(catcher.GetNextResult());
559 IN_PROC_BROWSER_TEST_F(CommandsApiTest, ShortcutAddedOnUpdate) {
560 base::ScopedTempDir scoped_temp_dir;
561 EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
562 base::FilePath pem_path = test_data_dir_.
563 AppendASCII("keybinding").AppendASCII("keybinding.pem");
564 base::FilePath path_v1_unassigned = PackExtensionWithOptions(
565 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
566 .AppendASCII("v1_unassigned"),
567 scoped_temp_dir.path().AppendASCII("v1_unassigned.crx"),
568 pem_path,
569 base::FilePath());
570 base::FilePath path_v2 = PackExtensionWithOptions(
571 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
572 .AppendASCII("v2"),
573 scoped_temp_dir.path().AppendASCII("v2.crx"),
574 pem_path,
575 base::FilePath());
577 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
578 CommandService* command_service = CommandService::Get(browser()->profile());
580 // Install v1 of the extension without keybinding assigned.
581 ASSERT_TRUE(InstallExtension(path_v1_unassigned, 1));
582 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
583 NULL);
585 // Verify it is set to nothing.
586 ui::Accelerator accelerator = command_service->FindCommandByName(
587 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
588 EXPECT_EQ(ui::VKEY_UNKNOWN, accelerator.key_code());
590 // Update to version 2 with keybinding.
591 EXPECT_TRUE(UpdateExtension(kId, path_v2, 0));
592 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
593 NULL);
595 // Verify it has a command of Alt+Shift+F.
596 accelerator = command_service->FindCommandByName(
597 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
598 EXPECT_EQ(ui::VKEY_F, accelerator.key_code());
599 EXPECT_FALSE(accelerator.IsCtrlDown());
600 EXPECT_TRUE(accelerator.IsShiftDown());
601 EXPECT_TRUE(accelerator.IsAltDown());
604 IN_PROC_BROWSER_TEST_F(CommandsApiTest, ShortcutChangedOnUpdate) {
605 base::ScopedTempDir scoped_temp_dir;
606 EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
607 base::FilePath pem_path = test_data_dir_.
608 AppendASCII("keybinding").AppendASCII("keybinding.pem");
609 base::FilePath path_v1 = PackExtensionWithOptions(
610 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
611 .AppendASCII("v1"),
612 scoped_temp_dir.path().AppendASCII("v1.crx"),
613 pem_path,
614 base::FilePath());
615 base::FilePath path_v2_reassigned = PackExtensionWithOptions(
616 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
617 .AppendASCII("v2_reassigned"),
618 scoped_temp_dir.path().AppendASCII("v2_reassigned.crx"),
619 pem_path,
620 base::FilePath());
622 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
623 CommandService* command_service = CommandService::Get(browser()->profile());
625 // Install v1 of the extension.
626 ASSERT_TRUE(InstallExtension(path_v1, 1));
627 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
628 NULL);
630 // Verify it has a command of Alt+Shift+F.
631 ui::Accelerator accelerator = command_service->FindCommandByName(
632 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
633 EXPECT_EQ(ui::VKEY_F, accelerator.key_code());
634 EXPECT_FALSE(accelerator.IsCtrlDown());
635 EXPECT_TRUE(accelerator.IsShiftDown());
636 EXPECT_TRUE(accelerator.IsAltDown());
638 // Update to version 2 with different keybinding assigned.
639 EXPECT_TRUE(UpdateExtension(kId, path_v2_reassigned, 0));
640 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
641 NULL);
643 // Verify it has a command of Alt+Shift+H.
644 accelerator = command_service->FindCommandByName(
645 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
646 EXPECT_EQ(ui::VKEY_H, accelerator.key_code());
647 EXPECT_FALSE(accelerator.IsCtrlDown());
648 EXPECT_TRUE(accelerator.IsShiftDown());
649 EXPECT_TRUE(accelerator.IsAltDown());
652 IN_PROC_BROWSER_TEST_F(CommandsApiTest, ShortcutRemovedOnUpdate) {
653 base::ScopedTempDir scoped_temp_dir;
654 EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
655 base::FilePath pem_path = test_data_dir_.
656 AppendASCII("keybinding").AppendASCII("keybinding.pem");
657 base::FilePath path_v1 = PackExtensionWithOptions(
658 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
659 .AppendASCII("v1"),
660 scoped_temp_dir.path().AppendASCII("v1.crx"),
661 pem_path,
662 base::FilePath());
663 base::FilePath path_v2_unassigned = PackExtensionWithOptions(
664 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
665 .AppendASCII("v2_unassigned"),
666 scoped_temp_dir.path().AppendASCII("v2_unassigned.crx"),
667 pem_path,
668 base::FilePath());
670 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
671 CommandService* command_service = CommandService::Get(browser()->profile());
673 // Install v1 of the extension.
674 ASSERT_TRUE(InstallExtension(path_v1, 1));
675 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
676 NULL);
678 // Verify it has a command of Alt+Shift+F.
679 ui::Accelerator accelerator = command_service->FindCommandByName(
680 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
681 EXPECT_EQ(ui::VKEY_F, accelerator.key_code());
682 EXPECT_FALSE(accelerator.IsCtrlDown());
683 EXPECT_TRUE(accelerator.IsShiftDown());
684 EXPECT_TRUE(accelerator.IsAltDown());
686 // Update to version 2 without keybinding assigned.
687 EXPECT_TRUE(UpdateExtension(kId, path_v2_unassigned, 0));
688 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
689 NULL);
691 // Verify the keybinding gets set to nothing.
692 accelerator = command_service->FindCommandByName(
693 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
694 EXPECT_EQ(ui::VKEY_UNKNOWN, accelerator.key_code());
697 IN_PROC_BROWSER_TEST_F(CommandsApiTest,
698 ShortcutAddedOnUpdateAfterBeingAssignedByUser) {
699 base::ScopedTempDir scoped_temp_dir;
700 EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
701 base::FilePath pem_path = test_data_dir_.
702 AppendASCII("keybinding").AppendASCII("keybinding.pem");
703 base::FilePath path_v1_unassigned = PackExtensionWithOptions(
704 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
705 .AppendASCII("v1_unassigned"),
706 scoped_temp_dir.path().AppendASCII("v1_unassigned.crx"),
707 pem_path,
708 base::FilePath());
709 base::FilePath path_v2 = PackExtensionWithOptions(
710 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
711 .AppendASCII("v2"),
712 scoped_temp_dir.path().AppendASCII("v2.crx"),
713 pem_path,
714 base::FilePath());
716 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
717 CommandService* command_service = CommandService::Get(browser()->profile());
719 // Install v1 of the extension without keybinding assigned.
720 ASSERT_TRUE(InstallExtension(path_v1_unassigned, 1));
721 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
722 NULL);
724 // Verify it is set to nothing.
725 ui::Accelerator accelerator = command_service->FindCommandByName(
726 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
727 EXPECT_EQ(ui::VKEY_UNKNOWN, accelerator.key_code());
729 // Simulate the user setting the keybinding to Alt+Shift+G.
730 command_service->UpdateKeybindingPrefs(
731 kId, manifest_values::kBrowserActionCommandEvent, kAltShiftG);
733 // Update to version 2 with keybinding.
734 EXPECT_TRUE(UpdateExtension(kId, path_v2, 0));
735 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
736 NULL);
738 // Verify the previously-set keybinding is still set.
739 accelerator = command_service->FindCommandByName(
740 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
741 EXPECT_EQ(ui::VKEY_G, accelerator.key_code());
742 EXPECT_FALSE(accelerator.IsCtrlDown());
743 EXPECT_TRUE(accelerator.IsShiftDown());
744 EXPECT_TRUE(accelerator.IsAltDown());
747 IN_PROC_BROWSER_TEST_F(CommandsApiTest,
748 ShortcutChangedOnUpdateAfterBeingReassignedByUser) {
749 base::ScopedTempDir scoped_temp_dir;
750 EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
751 base::FilePath pem_path = test_data_dir_.
752 AppendASCII("keybinding").AppendASCII("keybinding.pem");
753 base::FilePath path_v1 = PackExtensionWithOptions(
754 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
755 .AppendASCII("v1"),
756 scoped_temp_dir.path().AppendASCII("v1.crx"),
757 pem_path,
758 base::FilePath());
759 base::FilePath path_v2_reassigned = PackExtensionWithOptions(
760 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
761 .AppendASCII("v2_reassigned"),
762 scoped_temp_dir.path().AppendASCII("v2_reassigned.crx"),
763 pem_path,
764 base::FilePath());
766 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
767 CommandService* command_service = CommandService::Get(browser()->profile());
769 // Install v1 of the extension.
770 ASSERT_TRUE(InstallExtension(path_v1, 1));
771 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
772 NULL);
774 // Verify it has a command of Alt+Shift+F.
775 ui::Accelerator accelerator = command_service->FindCommandByName(
776 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
777 EXPECT_EQ(ui::VKEY_F, accelerator.key_code());
778 EXPECT_FALSE(accelerator.IsCtrlDown());
779 EXPECT_TRUE(accelerator.IsShiftDown());
780 EXPECT_TRUE(accelerator.IsAltDown());
782 // Simulate the user setting the keybinding to Alt+Shift+G.
783 command_service->UpdateKeybindingPrefs(
784 kId, manifest_values::kBrowserActionCommandEvent, kAltShiftG);
786 // Update to version 2 with different keybinding assigned.
787 EXPECT_TRUE(UpdateExtension(kId, path_v2_reassigned, 0));
788 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
789 NULL);
791 // Verify it has a command of Alt+Shift+G.
792 accelerator = command_service->FindCommandByName(
793 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
794 EXPECT_EQ(ui::VKEY_G, accelerator.key_code());
795 EXPECT_FALSE(accelerator.IsCtrlDown());
796 EXPECT_TRUE(accelerator.IsShiftDown());
797 EXPECT_TRUE(accelerator.IsAltDown());
800 // Test that Media keys do not overwrite previous settings.
801 IN_PROC_BROWSER_TEST_F(CommandsApiTest,
802 MediaKeyShortcutChangedOnUpdateAfterBeingReassignedByUser) {
803 base::ScopedTempDir scoped_temp_dir;
804 EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
805 base::FilePath pem_path = test_data_dir_.
806 AppendASCII("keybinding").AppendASCII("keybinding.pem");
807 base::FilePath path_v1 = PackExtensionWithOptions(
808 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
809 .AppendASCII("mk_v1"),
810 scoped_temp_dir.path().AppendASCII("mk_v1.crx"),
811 pem_path,
812 base::FilePath());
813 base::FilePath path_v2_reassigned = PackExtensionWithOptions(
814 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
815 .AppendASCII("mk_v2"),
816 scoped_temp_dir.path().AppendASCII("mk_v2.crx"),
817 pem_path,
818 base::FilePath());
820 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
821 CommandService* command_service = CommandService::Get(browser()->profile());
823 // Install v1 of the extension.
824 ASSERT_TRUE(InstallExtension(path_v1, 1));
825 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
826 NULL);
828 // Verify it has a command of MediaPlayPause.
829 ui::Accelerator accelerator = command_service->FindCommandByName(
830 kId, kMediaKeyTestCommand).accelerator();
831 EXPECT_EQ(ui::VKEY_MEDIA_PLAY_PAUSE, accelerator.key_code());
832 EXPECT_FALSE(accelerator.IsCtrlDown());
833 EXPECT_FALSE(accelerator.IsShiftDown());
834 EXPECT_FALSE(accelerator.IsAltDown());
836 // Simulate the user setting the keybinding to Alt+Shift+G.
837 command_service->UpdateKeybindingPrefs(
838 kId, kMediaKeyTestCommand, kAltShiftG);
840 // Update to version 2 with different keybinding assigned.
841 EXPECT_TRUE(UpdateExtension(kId, path_v2_reassigned, 0));
842 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
843 NULL);
845 // Verify it has a command of Alt+Shift+G.
846 accelerator = command_service->FindCommandByName(
847 kId, kMediaKeyTestCommand).accelerator();
848 EXPECT_EQ(ui::VKEY_G, accelerator.key_code());
849 EXPECT_FALSE(accelerator.IsCtrlDown());
850 EXPECT_TRUE(accelerator.IsShiftDown());
851 EXPECT_TRUE(accelerator.IsAltDown());
854 IN_PROC_BROWSER_TEST_F(CommandsApiTest,
855 ShortcutRemovedOnUpdateAfterBeingReassignedByUser) {
856 base::ScopedTempDir scoped_temp_dir;
857 EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
858 base::FilePath pem_path = test_data_dir_.
859 AppendASCII("keybinding").AppendASCII("keybinding.pem");
860 base::FilePath path_v1 = PackExtensionWithOptions(
861 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
862 .AppendASCII("v1"),
863 scoped_temp_dir.path().AppendASCII("v1.crx"),
864 pem_path,
865 base::FilePath());
866 base::FilePath path_v2_unassigned = PackExtensionWithOptions(
867 test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
868 .AppendASCII("v2_unassigned"),
869 scoped_temp_dir.path().AppendASCII("v2_unassigned.crx"),
870 pem_path,
871 base::FilePath());
873 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
874 CommandService* command_service = CommandService::Get(browser()->profile());
876 // Install v1 of the extension.
877 ASSERT_TRUE(InstallExtension(path_v1, 1));
878 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
879 NULL);
881 // Verify it has a command of Alt+Shift+F.
882 ui::Accelerator accelerator = command_service->FindCommandByName(
883 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
884 EXPECT_EQ(ui::VKEY_F, accelerator.key_code());
885 EXPECT_FALSE(accelerator.IsCtrlDown());
886 EXPECT_TRUE(accelerator.IsShiftDown());
887 EXPECT_TRUE(accelerator.IsAltDown());
889 // Simulate the user reassigning the keybinding to Alt+Shift+G.
890 command_service->UpdateKeybindingPrefs(
891 kId, manifest_values::kBrowserActionCommandEvent, kAltShiftG);
893 // Update to version 2 without keybinding assigned.
894 EXPECT_TRUE(UpdateExtension(kId, path_v2_unassigned, 0));
895 EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
896 NULL);
898 // Verify the keybinding is still set.
899 accelerator = command_service->FindCommandByName(
900 kId, manifest_values::kBrowserActionCommandEvent).accelerator();
901 EXPECT_EQ(ui::VKEY_G, accelerator.key_code());
902 EXPECT_FALSE(accelerator.IsCtrlDown());
903 EXPECT_TRUE(accelerator.IsShiftDown());
904 EXPECT_TRUE(accelerator.IsAltDown());
908 #if defined(OS_CHROMEOS) && !defined(NDEBUG)
909 // TODO(dtseng): Test times out on Chrome OS debug. See http://crbug.com/412456.
910 #define MAYBE_ContinuePropagation DISABLED_ContinuePropagation
911 #else
912 #define MAYBE_ContinuePropagation ContinuePropagation
913 #endif
915 IN_PROC_BROWSER_TEST_F(CommandsApiTest, MAYBE_ContinuePropagation) {
916 // Setup the environment.
917 ASSERT_TRUE(test_server()->Start());
918 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
919 ASSERT_TRUE(RunExtensionTest("keybinding/continue_propagation")) << message_;
920 ui_test_utils::NavigateToURL(
921 browser(), test_server()->GetURL("files/extensions/test_file.txt"));
923 ResultCatcher catcher;
925 // Activate the shortcut (Ctrl+Shift+F). The page should capture the
926 // keystroke and not the extension since |onCommand| has no event listener
927 // initially.
928 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
929 browser(), ui::VKEY_F, true, true, false, false));
930 ASSERT_TRUE(catcher.GetNextResult());
932 // Now, the extension should have added an |onCommand| event listener.
933 // Send the same key, but the |onCommand| listener should now receive it.
934 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
935 browser(), ui::VKEY_F, true, true, false, false));
936 ASSERT_TRUE(catcher.GetNextResult());
938 // The extension should now have removed its |onCommand| event listener.
939 // Finally, the page should again receive the key.
940 ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
941 browser(), ui::VKEY_F, true, true, false, false));
942 ASSERT_TRUE(catcher.GetNextResult());
945 // Test is only applicable on Chrome OS.
946 #if defined(OS_CHROMEOS)
947 // http://crbug.com/410534
948 #if defined(USE_OZONE)
949 #define MAYBE_ChromeOSConversions DISABLED_ChromeOSConversions
950 #else
951 #define MAYBE_ChromeOSConversions ChromeOSConversions
952 #endif
953 IN_PROC_BROWSER_TEST_F(CommandsApiTest, MAYBE_ChromeOSConversions) {
954 RunChromeOSConversionTest("keybinding/chromeos_conversions");
956 #endif // OS_CHROMEOS
958 // Make sure component extensions retain keybindings after removal then
959 // re-adding.
960 IN_PROC_BROWSER_TEST_F(CommandsApiTest, AddRemoveAddComponentExtension) {
961 ASSERT_TRUE(test_server()->Start());
962 ASSERT_TRUE(RunComponentExtensionTest("keybinding/component")) << message_;
964 extensions::ExtensionSystem::Get(browser()->profile())
965 ->extension_service()
966 ->component_loader()
967 ->Remove("pkplfbidichfdicaijlchgnapepdginl");
969 ASSERT_TRUE(RunComponentExtensionTest("keybinding/component")) << message_;
972 } // namespace extensions