Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / extension_keybinding_apitest.cc
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.
4
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"
27
28 using content::WebContents;
29
30 namespace extensions {
31
32 namespace {
33 // This extension ID is used for tests require a stable ID over multiple
34 // extension installs.
35 const char kId[] = "pgoakhfeplldmjheffidklpoklkppipp";
36
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";
40
41 // Named command for media key overwrite test.
42 const char kMediaKeyTestCommand[] = "test_mediakeys_update";
43
44 } // namespace
45
46 class CommandsApiTest : public ExtensionApiTest {
47  public:
48   CommandsApiTest() {}
49   ~CommandsApiTest() override {}
50
51  protected:
52   BrowserActionTestUtil GetBrowserActionsBar() {
53     return BrowserActionTestUtil(browser());
54   }
55
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);
60   }
61
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"));
70
71     ResultCatcher catcher;
72
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));
82
83     ASSERT_TRUE(catcher.GetNextResult());
84   }
85 #endif  // OS_CHROMEOS
86 };
87
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_;
99
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_;
105
106   // Test that there are two browser actions in the toolbar.
107   ASSERT_EQ(2, GetBrowserActionsBar().NumberOfBrowserActions());
108
109   ui_test_utils::NavigateToURL(browser(),
110       test_server()->GetURL("files/extensions/test_file.txt"));
111
112   // activeTab shouldn't have been granted yet.
113   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
114   ASSERT_TRUE(tab);
115
116   EXPECT_FALSE(IsGrantedForTab(extension, tab));
117
118   // Activate the shortcut (Ctrl+Shift+F).
119   ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
120       browser(), ui::VKEY_F, true, true, false, false));
121
122   // activeTab should now be granted.
123   EXPECT_TRUE(IsGrantedForTab(extension, tab));
124
125   // Verify the command worked.
126   bool result = false;
127   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
128       tab,
129       "setInterval(function(){"
130       "  if(document.body.bgColor == 'red'){"
131       "    window.domAutomationController.send(true)}}, 100)",
132       &result));
133   ASSERT_TRUE(result);
134
135   // Activate the shortcut (Ctrl+Shift+Y).
136   ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
137       browser(), ui::VKEY_Y, true, true, false, false));
138
139   result = false;
140   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
141       tab,
142       "setInterval(function(){"
143       "  if(document.body.bgColor == 'blue'){"
144       "    window.domAutomationController.send(true)}}, 100)",
145       &result));
146   ASSERT_TRUE(result);
147 }
148
149 // Flaky on linux and chromeos, http://crbug.com/165825
150 #if defined(OS_MACOSX) || defined(OS_WIN)
151 #define MAYBE_PageAction PageAction
152 #else
153 #define MAYBE_PageAction DISABLED_PageAction
154 #endif
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_;
160
161   {
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());
168   }
169
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);
177   ASSERT_TRUE(action);
178   EXPECT_EQ("Make this page red", action->GetTitle(tab_id));
179
180   // Activate the shortcut (Alt+Shift+F).
181   ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
182       browser(), ui::VKEY_F, false, true, true, false));
183
184   // Verify the command worked (the page action turns the page red).
185   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
186   bool result = false;
187   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
188       tab,
189       "setInterval(function(){"
190       "  if(document.body.bgColor == 'red'){"
191       "    window.domAutomationController.send(true)}}, 100)",
192       &result));
193   ASSERT_TRUE(result);
194 }
195
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_;
202 }
203
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());
208
209   ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
210
211   ASSERT_TRUE(RunExtensionTest("keybinding/dont_overwrite_system")) << message_;
212
213   ui_test_utils::NavigateToURL(browser(),
214       test_server()->GetURL("files/extensions/test_file.txt"));
215
216   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
217   ASSERT_TRUE(tab);
218
219   // Activate the shortcut (Alt+Shift+F) to make the page blue.
220   {
221     ResultCatcher catcher;
222     ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
223         browser(), ui::VKEY_F, false, true, true, false));
224     ASSERT_TRUE(catcher.GetNextResult());
225   }
226
227   bool result = false;
228   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
229       tab,
230       "setInterval(function() {"
231       "  if (document.body.bgColor == 'blue') {"
232       "    window.domAutomationController.send(true)}}, 100)",
233       &result));
234   ASSERT_TRUE(result);
235
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));
241 #else
242     ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
243         browser(), ui::VKEY_D, true, false, false, false));
244 #endif
245
246   // The page should still be blue.
247   result = false;
248   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
249       tab,
250       "setInterval(function() {"
251       "  if (document.body.bgColor == 'blue') {"
252       "    window.domAutomationController.send(true)}}, 100)",
253       &result));
254   ASSERT_TRUE(result);
255
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));
259
260   // The page should still be blue.
261   result = false;
262   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
263       tab,
264       "setInterval(function() {"
265       "  if (document.body.bgColor == 'blue') {"
266       "    window.domAutomationController.send(true)}}, 100)",
267       &result));
268   ASSERT_TRUE(result);
269 }
270
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());
275
276   ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
277
278   // This functionality requires a feature flag.
279   CommandLine::ForCurrentProcess()->AppendSwitchASCII(
280       "--enable-override-bookmarks-ui",
281       "1");
282
283   ASSERT_TRUE(RunExtensionTest("keybinding/overwrite_bookmark_shortcut"))
284       << message_;
285
286   ui_test_utils::NavigateToURL(browser(),
287       test_server()->GetURL("files/extensions/test_file.txt"));
288
289   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
290   ASSERT_TRUE(tab);
291
292   // Activate the shortcut (Ctrl+D) to make the page green.
293   {
294     ResultCatcher catcher;
295 #if defined(OS_MACOSX)
296     ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
297         browser(), ui::VKEY_D, false, false, false, true));
298 #else
299     ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
300         browser(), ui::VKEY_D, true, false, false, false));
301 #endif
302     ASSERT_TRUE(catcher.GetNextResult());
303   }
304
305   bool result = false;
306   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
307       tab,
308       "setInterval(function() {"
309       "  if (document.body.bgColor == 'green') {"
310       "    window.domAutomationController.send(true)}}, 100)",
311       &result));
312   ASSERT_TRUE(result);
313 }
314
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());
320
321   ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
322
323   // This functionality requires a feature flag.
324   CommandLine::ForCurrentProcess()->AppendSwitchASCII(
325       "--enable-override-bookmarks-ui",
326       "1");
327
328   ASSERT_TRUE(RunExtensionTest("keybinding/overwrite_bookmark_shortcut"))
329       << message_;
330
331   ui_test_utils::NavigateToURL(browser(),
332       test_server()->GetURL(
333           "files/extensions/test_file_with_ctrl-d_keybinding.html"));
334
335   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
336   ASSERT_TRUE(tab);
337
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));
343 #else
344   ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
345       browser(), ui::VKEY_D, true, false, false, false));
346 #endif
347
348   bool result = false;
349   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
350       tab,
351       "setInterval(function() {"
352       "  if (document.body.bgColor == 'magenta') {"
353       "    window.domAutomationController.send(true)}}, 100)",
354       &result));
355   ASSERT_TRUE(result);
356 }
357
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
360 // web pages.
361 IN_PROC_BROWSER_TEST_F(CommandsApiTest,
362                        OverwriteBookmarkShortcutByUserOverridesWebKeybinding) {
363   ASSERT_TRUE(test_server()->Start());
364
365   ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
366
367   // This functionality requires a feature flag.
368   CommandLine::ForCurrentProcess()->AppendSwitchASCII(
369       "--enable-override-bookmarks-ui",
370       "1");
371
372   ASSERT_TRUE(RunExtensionTest("keybinding/basics"))
373       << message_;
374
375   CommandService* command_service = CommandService::Get(browser()->profile());
376
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";
381 #else
382   const char hotkey[] = "Ctrl+D";
383 #endif  // defined(OS_MACOSX)
384   command_service->UpdateKeybindingPrefs(
385       extension->id(), manifest_values::kBrowserActionCommandEvent, hotkey);
386
387   ui_test_utils::NavigateToURL(browser(),
388       test_server()->GetURL(
389           "files/extensions/test_file_with_ctrl-d_keybinding.html"));
390
391   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
392   ASSERT_TRUE(tab);
393
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));
399 #else
400   ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
401       browser(), ui::VKEY_D, true, false, false, false));
402 #endif
403
404   bool result = false;
405   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
406       tab,
407       "setInterval(function() {"
408       "  if (document.body.bgColor == 'red') {"
409       "    window.domAutomationController.send(true)}}, 100)",
410       &result));
411   ASSERT_TRUE(result);
412 }
413
414 #if defined(OS_WIN)
415 // Currently this feature is implemented on Windows only.
416 #define MAYBE_AllowDuplicatedMediaKeys AllowDuplicatedMediaKeys
417 #else
418 #define MAYBE_AllowDuplicatedMediaKeys DISABLED_AllowDuplicatedMediaKeys
419 #endif
420
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"))
425       << message_;
426   ASSERT_TRUE(catcher.GetNextResult());
427   ASSERT_TRUE(RunExtensionTest("keybinding/non_global_media_keys_1"))
428       << message_;
429   ASSERT_TRUE(catcher.GetNextResult());
430
431   // Activate the Media Stop key.
432   ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
433       browser(), ui::VKEY_MEDIA_STOP, false, false, false, false));
434
435   // We should get two success result.
436   ASSERT_TRUE(catcher.GetNextResult());
437   ASSERT_TRUE(catcher.GetNextResult());
438 }
439
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"),
449       pem_path,
450       base::FilePath());
451   base::FilePath path_v2 = PackExtensionWithOptions(
452       test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
453                     .AppendASCII("v2"),
454       scoped_temp_dir.path().AppendASCII("v2.crx"),
455       pem_path,
456       base::FilePath());
457
458   ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
459   CommandService* command_service = CommandService::Get(browser()->profile());
460
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) !=
464               NULL);
465
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());
470
471   // Update to version 2 with keybinding.
472   EXPECT_TRUE(UpdateExtension(kId, path_v2, 0));
473   EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
474               NULL);
475
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());
483 }
484
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")
492                     .AppendASCII("v1"),
493       scoped_temp_dir.path().AppendASCII("v1.crx"),
494       pem_path,
495       base::FilePath());
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"),
500       pem_path,
501       base::FilePath());
502
503   ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
504   CommandService* command_service = CommandService::Get(browser()->profile());
505
506   // Install v1 of the extension.
507   ASSERT_TRUE(InstallExtension(path_v1, 1));
508   EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
509               NULL);
510
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());
518
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) !=
522               NULL);
523
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());
531 }
532
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")
540                     .AppendASCII("v1"),
541       scoped_temp_dir.path().AppendASCII("v1.crx"),
542       pem_path,
543       base::FilePath());
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"),
548       pem_path,
549       base::FilePath());
550
551   ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
552   CommandService* command_service = CommandService::Get(browser()->profile());
553
554   // Install v1 of the extension.
555   ASSERT_TRUE(InstallExtension(path_v1, 1));
556   EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
557               NULL);
558
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());
566
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) !=
570               NULL);
571
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());
576 }
577
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"),
588       pem_path,
589       base::FilePath());
590   base::FilePath path_v2 = PackExtensionWithOptions(
591       test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
592                     .AppendASCII("v2"),
593       scoped_temp_dir.path().AppendASCII("v2.crx"),
594       pem_path,
595       base::FilePath());
596
597   ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
598   CommandService* command_service = CommandService::Get(browser()->profile());
599
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) !=
603               NULL);
604
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());
609
610   // Simulate the user setting the keybinding to Alt+Shift+G.
611   command_service->UpdateKeybindingPrefs(
612       kId, manifest_values::kBrowserActionCommandEvent, kAltShiftG);
613
614   // Update to version 2 with keybinding.
615   EXPECT_TRUE(UpdateExtension(kId, path_v2, 0));
616   EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
617               NULL);
618
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());
626 }
627
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")
636                     .AppendASCII("v1"),
637       scoped_temp_dir.path().AppendASCII("v1.crx"),
638       pem_path,
639       base::FilePath());
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"),
644       pem_path,
645       base::FilePath());
646
647   ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
648   CommandService* command_service = CommandService::Get(browser()->profile());
649
650   // Install v1 of the extension.
651   ASSERT_TRUE(InstallExtension(path_v1, 1));
652   EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
653               NULL);
654
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());
662
663   // Simulate the user setting the keybinding to Alt+Shift+G.
664   command_service->UpdateKeybindingPrefs(
665       kId, manifest_values::kBrowserActionCommandEvent, kAltShiftG);
666
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) !=
670               NULL);
671
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());
679 }
680
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"),
692       pem_path,
693       base::FilePath());
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"),
698       pem_path,
699       base::FilePath());
700
701   ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
702   CommandService* command_service = CommandService::Get(browser()->profile());
703
704   // Install v1 of the extension.
705   ASSERT_TRUE(InstallExtension(path_v1, 1));
706   EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
707               NULL);
708
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());
716
717   // Simulate the user setting the keybinding to Alt+Shift+G.
718   command_service->UpdateKeybindingPrefs(
719       kId, kMediaKeyTestCommand, kAltShiftG);
720
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) !=
724               NULL);
725
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());
733 }
734
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")
743                     .AppendASCII("v1"),
744       scoped_temp_dir.path().AppendASCII("v1.crx"),
745       pem_path,
746       base::FilePath());
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"),
751       pem_path,
752       base::FilePath());
753
754   ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
755   CommandService* command_service = CommandService::Get(browser()->profile());
756
757   // Install v1 of the extension.
758   ASSERT_TRUE(InstallExtension(path_v1, 1));
759   EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
760               NULL);
761
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());
769
770   // Simulate the user reassigning the keybinding to Alt+Shift+G.
771   command_service->UpdateKeybindingPrefs(
772       kId, manifest_values::kBrowserActionCommandEvent, kAltShiftG);
773
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) !=
777               NULL);
778
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());
786 }
787
788 //
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
792 #else
793 #define MAYBE_ContinuePropagation ContinuePropagation
794 #endif
795
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"));
803
804   ResultCatcher catcher;
805
806   // Activate the shortcut (Ctrl+Shift+F). The page should capture the
807   // keystroke and not the extension since |onCommand| has no event listener
808   // initially.
809   ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
810       browser(), ui::VKEY_F, true, true, false, false));
811   ASSERT_TRUE(catcher.GetNextResult());
812
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());
818
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());
824 }
825
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
831 #else
832 #define MAYBE_ChromeOSConversions ChromeOSConversions
833 #endif
834 IN_PROC_BROWSER_TEST_F(CommandsApiTest, MAYBE_ChromeOSConversions) {
835   RunChromeOSConversionTest("keybinding/chromeos_conversions");
836 }
837 #endif  // OS_CHROMEOS
838
839 }  // namespace extensions