• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
27 using content::WebContents;
28 
29 namespace extensions {
30 
31 namespace {
32 // This extension ID is used for tests require a stable ID over multiple
33 // extension installs.
34 const char kId[] = "pgoakhfeplldmjheffidklpoklkppipp";
35 
36 // Default keybinding to use for emulating user-defined shortcut overrides. The
37 // test extensions use Alt+Shift+F and Alt+Shift+H.
38 const char kAltShiftG[] = "Alt+Shift+G";
39 }
40 
41 class CommandsApiTest : public ExtensionApiTest {
42  public:
CommandsApiTest()43   CommandsApiTest() {}
~CommandsApiTest()44   virtual ~CommandsApiTest() {}
45 
46  protected:
GetBrowserActionsBar()47   BrowserActionTestUtil GetBrowserActionsBar() {
48     return BrowserActionTestUtil(browser());
49   }
50 
IsGrantedForTab(const Extension * extension,const content::WebContents * web_contents)51   bool IsGrantedForTab(const Extension* extension,
52                        const content::WebContents* web_contents) {
53     return extension->permissions_data()->HasAPIPermissionForTab(
54         SessionID::IdForTab(web_contents), APIPermission::kTab);
55   }
56 };
57 
58 // Test the basic functionality of the Keybinding API:
59 // - That pressing the shortcut keys should perform actions (activate the
60 //   browser action or send an event).
61 // - Note: Page action keybindings are tested in PageAction test below.
62 // - The shortcut keys taken by one extension are not overwritten by the last
63 //   installed extension.
IN_PROC_BROWSER_TEST_F(CommandsApiTest,Basic)64 IN_PROC_BROWSER_TEST_F(CommandsApiTest, Basic) {
65   ASSERT_TRUE(test_server()->Start());
66   ASSERT_TRUE(RunExtensionTest("keybinding/basics")) << message_;
67   const Extension* extension = GetSingleLoadedExtension();
68   ASSERT_TRUE(extension) << message_;
69 
70   // Load this extension, which uses the same keybindings but sets the page
71   // to different colors. This is so we can see that it doesn't interfere. We
72   // don't test this extension in any other way (it should otherwise be
73   // immaterial to this test).
74   ASSERT_TRUE(RunExtensionTest("keybinding/conflicting")) << message_;
75 
76   // Test that there are two browser actions in the toolbar.
77   ASSERT_EQ(2, GetBrowserActionsBar().NumberOfBrowserActions());
78 
79   ui_test_utils::NavigateToURL(browser(),
80       test_server()->GetURL("files/extensions/test_file.txt"));
81 
82   // activeTab shouldn't have been granted yet.
83   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
84   ASSERT_TRUE(tab);
85 
86   EXPECT_FALSE(IsGrantedForTab(extension, tab));
87 
88   // Activate the shortcut (Ctrl+Shift+F).
89   ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
90       browser(), ui::VKEY_F, true, true, false, false));
91 
92   // activeTab should now be granted.
93   EXPECT_TRUE(IsGrantedForTab(extension, tab));
94 
95   // Verify the command worked.
96   bool result = false;
97   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
98       tab,
99       "setInterval(function(){"
100       "  if(document.body.bgColor == 'red'){"
101       "    window.domAutomationController.send(true)}}, 100)",
102       &result));
103   ASSERT_TRUE(result);
104 
105   // Activate the shortcut (Ctrl+Shift+Y).
106   ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
107       browser(), ui::VKEY_Y, true, true, false, false));
108 
109   result = false;
110   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
111       tab,
112       "setInterval(function(){"
113       "  if(document.body.bgColor == 'blue'){"
114       "    window.domAutomationController.send(true)}}, 100)",
115       &result));
116   ASSERT_TRUE(result);
117 }
118 
119 // Flaky on linux and chromeos, http://crbug.com/165825
120 #if defined(OS_MACOSX) || defined(OS_WIN)
121 #define MAYBE_PageAction PageAction
122 #else
123 #define MAYBE_PageAction DISABLED_PageAction
124 #endif
IN_PROC_BROWSER_TEST_F(CommandsApiTest,MAYBE_PageAction)125 IN_PROC_BROWSER_TEST_F(CommandsApiTest, MAYBE_PageAction) {
126   ASSERT_TRUE(test_server()->Start());
127   ASSERT_TRUE(RunExtensionTest("keybinding/page_action")) << message_;
128   const Extension* extension = GetSingleLoadedExtension();
129   ASSERT_TRUE(extension) << message_;
130 
131   {
132     // Load a page, the extension will detect the navigation and request to show
133     // the page action icon.
134     ResultCatcher catcher;
135     ui_test_utils::NavigateToURL(browser(),
136         test_server()->GetURL("files/extensions/test_file.txt"));
137     ASSERT_TRUE(catcher.GetNextResult());
138   }
139 
140   // Make sure it appears and is the right one.
141   ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1));
142   int tab_id = SessionTabHelper::FromWebContents(
143       browser()->tab_strip_model()->GetActiveWebContents())->session_id().id();
144   ExtensionAction* action =
145       ExtensionActionManager::Get(browser()->profile())->
146       GetPageAction(*extension);
147   ASSERT_TRUE(action);
148   EXPECT_EQ("Make this page red", action->GetTitle(tab_id));
149 
150   // Activate the shortcut (Alt+Shift+F).
151   ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
152       browser(), ui::VKEY_F, false, true, true, false));
153 
154   // Verify the command worked (the page action turns the page red).
155   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
156   bool result = false;
157   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
158       tab,
159       "setInterval(function(){"
160       "  if(document.body.bgColor == 'red'){"
161       "    window.domAutomationController.send(true)}}, 100)",
162       &result));
163   ASSERT_TRUE(result);
164 }
165 
166 // This test validates that the getAll query API function returns registered
167 // commands as well as synthesized ones and that inactive commands (like the
168 // synthesized ones are in nature) have no shortcuts.
IN_PROC_BROWSER_TEST_F(CommandsApiTest,SynthesizedCommand)169 IN_PROC_BROWSER_TEST_F(CommandsApiTest, SynthesizedCommand) {
170   ASSERT_TRUE(test_server()->Start());
171   ASSERT_TRUE(RunExtensionTest("keybinding/synthesized")) << message_;
172 }
173 
174 // This test validates that an extension cannot request a shortcut that is
175 // already in use by Chrome.
IN_PROC_BROWSER_TEST_F(CommandsApiTest,DontOverwriteSystemShortcuts)176 IN_PROC_BROWSER_TEST_F(CommandsApiTest, DontOverwriteSystemShortcuts) {
177   ASSERT_TRUE(test_server()->Start());
178 
179   ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
180 
181   ASSERT_TRUE(RunExtensionTest("keybinding/dont_overwrite_system")) << message_;
182 
183   ui_test_utils::NavigateToURL(browser(),
184       test_server()->GetURL("files/extensions/test_file.txt"));
185 
186   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
187   ASSERT_TRUE(tab);
188 
189   // Activate the shortcut (Alt+Shift+F) to make the page blue.
190   {
191     ResultCatcher catcher;
192     ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
193         browser(), ui::VKEY_F, false, true, true, false));
194     ASSERT_TRUE(catcher.GetNextResult());
195   }
196 
197   bool result = false;
198   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
199       tab,
200       "setInterval(function() {"
201       "  if (document.body.bgColor == 'blue') {"
202       "    window.domAutomationController.send(true)}}, 100)",
203       &result));
204   ASSERT_TRUE(result);
205 
206   // Activate the bookmark shortcut (Ctrl+D) to make the page green (should not
207   // work without requesting via chrome_settings_overrides).
208 #if defined(OS_MACOSX)
209     ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
210         browser(), ui::VKEY_D, false, false, false, true));
211 #else
212     ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
213         browser(), ui::VKEY_D, true, false, false, false));
214 #endif
215 
216   // The page should still be blue.
217   result = false;
218   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
219       tab,
220       "setInterval(function() {"
221       "  if (document.body.bgColor == 'blue') {"
222       "    window.domAutomationController.send(true)}}, 100)",
223       &result));
224   ASSERT_TRUE(result);
225 
226   // Activate the shortcut (Ctrl+F) to make the page red (should not work).
227   ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
228       browser(), ui::VKEY_F, true, false, false, false));
229 
230   // The page should still be blue.
231   result = false;
232   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
233       tab,
234       "setInterval(function() {"
235       "  if (document.body.bgColor == 'blue') {"
236       "    window.domAutomationController.send(true)}}, 100)",
237       &result));
238   ASSERT_TRUE(result);
239 }
240 
241 // This test validates that an extension can override the Chrome bookmark
242 // shortcut if it has requested to do so.
IN_PROC_BROWSER_TEST_F(CommandsApiTest,OverwriteBookmarkShortcut)243 IN_PROC_BROWSER_TEST_F(CommandsApiTest, OverwriteBookmarkShortcut) {
244   ASSERT_TRUE(test_server()->Start());
245 
246   ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
247 
248   // This functionality requires a feature flag.
249   CommandLine::ForCurrentProcess()->AppendSwitchASCII(
250       "--enable-override-bookmarks-ui",
251       "1");
252 
253   ASSERT_TRUE(RunExtensionTest("keybinding/overwrite_bookmark_shortcut"))
254       << message_;
255 
256   ui_test_utils::NavigateToURL(browser(),
257       test_server()->GetURL("files/extensions/test_file.txt"));
258 
259   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
260   ASSERT_TRUE(tab);
261 
262   // Activate the shortcut (Ctrl+D) to make the page green.
263   {
264     ResultCatcher catcher;
265 #if defined(OS_MACOSX)
266     ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
267         browser(), ui::VKEY_D, false, false, false, true));
268 #else
269     ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
270         browser(), ui::VKEY_D, true, false, false, false));
271 #endif
272     ASSERT_TRUE(catcher.GetNextResult());
273   }
274 
275   bool result = false;
276   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
277       tab,
278       "setInterval(function() {"
279       "  if (document.body.bgColor == 'green') {"
280       "    window.domAutomationController.send(true)}}, 100)",
281       &result));
282   ASSERT_TRUE(result);
283 }
284 
285 #if defined(OS_WIN)
286 // Currently this feature is implemented on Windows only.
287 #define MAYBE_AllowDuplicatedMediaKeys AllowDuplicatedMediaKeys
288 #else
289 #define MAYBE_AllowDuplicatedMediaKeys DISABLED_AllowDuplicatedMediaKeys
290 #endif
291 
292 // Test that media keys go to all extensions that register for them.
IN_PROC_BROWSER_TEST_F(CommandsApiTest,MAYBE_AllowDuplicatedMediaKeys)293 IN_PROC_BROWSER_TEST_F(CommandsApiTest, MAYBE_AllowDuplicatedMediaKeys) {
294   ResultCatcher catcher;
295   ASSERT_TRUE(RunExtensionTest("keybinding/non_global_media_keys_0"))
296       << message_;
297   ASSERT_TRUE(catcher.GetNextResult());
298   ASSERT_TRUE(RunExtensionTest("keybinding/non_global_media_keys_1"))
299       << message_;
300   ASSERT_TRUE(catcher.GetNextResult());
301 
302   // Activate the Media Stop key.
303   ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
304       browser(), ui::VKEY_MEDIA_STOP, false, false, false, false));
305 
306   // We should get two success result.
307   ASSERT_TRUE(catcher.GetNextResult());
308   ASSERT_TRUE(catcher.GetNextResult());
309 }
310 
IN_PROC_BROWSER_TEST_F(CommandsApiTest,ShortcutAddedOnUpdate)311 IN_PROC_BROWSER_TEST_F(CommandsApiTest, ShortcutAddedOnUpdate) {
312   base::ScopedTempDir scoped_temp_dir;
313   EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
314   base::FilePath pem_path = test_data_dir_.
315       AppendASCII("keybinding").AppendASCII("keybinding.pem");
316   base::FilePath path_v1_unassigned = PackExtensionWithOptions(
317       test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
318                     .AppendASCII("v1_unassigned"),
319       scoped_temp_dir.path().AppendASCII("v1_unassigned.crx"),
320       pem_path,
321       base::FilePath());
322   base::FilePath path_v2 = PackExtensionWithOptions(
323       test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
324                     .AppendASCII("v2"),
325       scoped_temp_dir.path().AppendASCII("v2.crx"),
326       pem_path,
327       base::FilePath());
328 
329   ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
330   CommandService* command_service = CommandService::Get(browser()->profile());
331 
332   // Install v1 of the extension without keybinding assigned.
333   ASSERT_TRUE(InstallExtension(path_v1_unassigned, 1));
334   EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
335               NULL);
336 
337   // Verify it is set to nothing.
338   ui::Accelerator accelerator = command_service->FindCommandByName(
339       kId, manifest_values::kBrowserActionCommandEvent).accelerator();
340   EXPECT_EQ(ui::VKEY_UNKNOWN, accelerator.key_code());
341 
342   // Update to version 2 with keybinding.
343   EXPECT_TRUE(UpdateExtension(kId, path_v2, 0));
344   EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
345               NULL);
346 
347   // Verify it has a command of Alt+Shift+F.
348   accelerator = command_service->FindCommandByName(
349       kId, manifest_values::kBrowserActionCommandEvent).accelerator();
350   EXPECT_EQ(ui::VKEY_F, accelerator.key_code());
351   EXPECT_FALSE(accelerator.IsCtrlDown());
352   EXPECT_TRUE(accelerator.IsShiftDown());
353   EXPECT_TRUE(accelerator.IsAltDown());
354 }
355 
IN_PROC_BROWSER_TEST_F(CommandsApiTest,ShortcutChangedOnUpdate)356 IN_PROC_BROWSER_TEST_F(CommandsApiTest, ShortcutChangedOnUpdate) {
357   base::ScopedTempDir scoped_temp_dir;
358   EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
359   base::FilePath pem_path = test_data_dir_.
360       AppendASCII("keybinding").AppendASCII("keybinding.pem");
361   base::FilePath path_v1 = PackExtensionWithOptions(
362       test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
363                     .AppendASCII("v1"),
364       scoped_temp_dir.path().AppendASCII("v1.crx"),
365       pem_path,
366       base::FilePath());
367   base::FilePath path_v2_reassigned = PackExtensionWithOptions(
368       test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
369                     .AppendASCII("v2_reassigned"),
370       scoped_temp_dir.path().AppendASCII("v2_reassigned.crx"),
371       pem_path,
372       base::FilePath());
373 
374   ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
375   CommandService* command_service = CommandService::Get(browser()->profile());
376 
377   // Install v1 of the extension.
378   ASSERT_TRUE(InstallExtension(path_v1, 1));
379   EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
380               NULL);
381 
382   // Verify it has a command of Alt+Shift+F.
383   ui::Accelerator accelerator = command_service->FindCommandByName(
384       kId, manifest_values::kBrowserActionCommandEvent).accelerator();
385   EXPECT_EQ(ui::VKEY_F, accelerator.key_code());
386   EXPECT_FALSE(accelerator.IsCtrlDown());
387   EXPECT_TRUE(accelerator.IsShiftDown());
388   EXPECT_TRUE(accelerator.IsAltDown());
389 
390   // Update to version 2 with different keybinding assigned.
391   EXPECT_TRUE(UpdateExtension(kId, path_v2_reassigned, 0));
392   EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
393               NULL);
394 
395   // Verify it has a command of Alt+Shift+H.
396   accelerator = command_service->FindCommandByName(
397       kId, manifest_values::kBrowserActionCommandEvent).accelerator();
398   EXPECT_EQ(ui::VKEY_H, accelerator.key_code());
399   EXPECT_FALSE(accelerator.IsCtrlDown());
400   EXPECT_TRUE(accelerator.IsShiftDown());
401   EXPECT_TRUE(accelerator.IsAltDown());
402 }
403 
IN_PROC_BROWSER_TEST_F(CommandsApiTest,ShortcutRemovedOnUpdate)404 IN_PROC_BROWSER_TEST_F(CommandsApiTest, ShortcutRemovedOnUpdate) {
405   base::ScopedTempDir scoped_temp_dir;
406   EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
407   base::FilePath pem_path = test_data_dir_.
408       AppendASCII("keybinding").AppendASCII("keybinding.pem");
409   base::FilePath path_v1 = PackExtensionWithOptions(
410       test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
411                     .AppendASCII("v1"),
412       scoped_temp_dir.path().AppendASCII("v1.crx"),
413       pem_path,
414       base::FilePath());
415   base::FilePath path_v2_unassigned = PackExtensionWithOptions(
416       test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
417                     .AppendASCII("v2_unassigned"),
418       scoped_temp_dir.path().AppendASCII("v2_unassigned.crx"),
419       pem_path,
420       base::FilePath());
421 
422   ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
423   CommandService* command_service = CommandService::Get(browser()->profile());
424 
425   // Install v1 of the extension.
426   ASSERT_TRUE(InstallExtension(path_v1, 1));
427   EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
428               NULL);
429 
430   // Verify it has a command of Alt+Shift+F.
431   ui::Accelerator accelerator = command_service->FindCommandByName(
432       kId, manifest_values::kBrowserActionCommandEvent).accelerator();
433   EXPECT_EQ(ui::VKEY_F, accelerator.key_code());
434   EXPECT_FALSE(accelerator.IsCtrlDown());
435   EXPECT_TRUE(accelerator.IsShiftDown());
436   EXPECT_TRUE(accelerator.IsAltDown());
437 
438   // Update to version 2 without keybinding assigned.
439   EXPECT_TRUE(UpdateExtension(kId, path_v2_unassigned, 0));
440   EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
441               NULL);
442 
443   // Verify the keybinding gets set to nothing.
444   accelerator = command_service->FindCommandByName(
445       kId, manifest_values::kBrowserActionCommandEvent).accelerator();
446   EXPECT_EQ(ui::VKEY_UNKNOWN, accelerator.key_code());
447 }
448 
IN_PROC_BROWSER_TEST_F(CommandsApiTest,ShortcutAddedOnUpdateAfterBeingAssignedByUser)449 IN_PROC_BROWSER_TEST_F(CommandsApiTest,
450                        ShortcutAddedOnUpdateAfterBeingAssignedByUser) {
451   base::ScopedTempDir scoped_temp_dir;
452   EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
453   base::FilePath pem_path = test_data_dir_.
454       AppendASCII("keybinding").AppendASCII("keybinding.pem");
455   base::FilePath path_v1_unassigned = PackExtensionWithOptions(
456       test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
457                     .AppendASCII("v1_unassigned"),
458       scoped_temp_dir.path().AppendASCII("v1_unassigned.crx"),
459       pem_path,
460       base::FilePath());
461   base::FilePath path_v2 = PackExtensionWithOptions(
462       test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
463                     .AppendASCII("v2"),
464       scoped_temp_dir.path().AppendASCII("v2.crx"),
465       pem_path,
466       base::FilePath());
467 
468   ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
469   CommandService* command_service = CommandService::Get(browser()->profile());
470 
471   // Install v1 of the extension without keybinding assigned.
472   ASSERT_TRUE(InstallExtension(path_v1_unassigned, 1));
473   EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
474               NULL);
475 
476   // Verify it is set to nothing.
477   ui::Accelerator accelerator = command_service->FindCommandByName(
478       kId, manifest_values::kBrowserActionCommandEvent).accelerator();
479   EXPECT_EQ(ui::VKEY_UNKNOWN, accelerator.key_code());
480 
481   // Simulate the user setting the keybinding to Alt+Shift+G.
482   command_service->UpdateKeybindingPrefs(
483       kId, manifest_values::kBrowserActionCommandEvent, kAltShiftG);
484 
485   // Update to version 2 with keybinding.
486   EXPECT_TRUE(UpdateExtension(kId, path_v2, 0));
487   EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
488               NULL);
489 
490   // Verify the previously-set keybinding is still set.
491   accelerator = command_service->FindCommandByName(
492       kId, manifest_values::kBrowserActionCommandEvent).accelerator();
493   EXPECT_EQ(ui::VKEY_G, accelerator.key_code());
494   EXPECT_FALSE(accelerator.IsCtrlDown());
495   EXPECT_TRUE(accelerator.IsShiftDown());
496   EXPECT_TRUE(accelerator.IsAltDown());
497 }
498 
IN_PROC_BROWSER_TEST_F(CommandsApiTest,ShortcutChangedOnUpdateAfterBeingReassignedByUser)499 IN_PROC_BROWSER_TEST_F(CommandsApiTest,
500                        ShortcutChangedOnUpdateAfterBeingReassignedByUser) {
501   base::ScopedTempDir scoped_temp_dir;
502   EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
503   base::FilePath pem_path = test_data_dir_.
504       AppendASCII("keybinding").AppendASCII("keybinding.pem");
505   base::FilePath path_v1 = PackExtensionWithOptions(
506       test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
507                     .AppendASCII("v1"),
508       scoped_temp_dir.path().AppendASCII("v1.crx"),
509       pem_path,
510       base::FilePath());
511   base::FilePath path_v2_reassigned = PackExtensionWithOptions(
512       test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
513                     .AppendASCII("v2_reassigned"),
514       scoped_temp_dir.path().AppendASCII("v2_reassigned.crx"),
515       pem_path,
516       base::FilePath());
517 
518   ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
519   CommandService* command_service = CommandService::Get(browser()->profile());
520 
521   // Install v1 of the extension.
522   ASSERT_TRUE(InstallExtension(path_v1, 1));
523   EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
524               NULL);
525 
526   // Verify it has a command of Alt+Shift+F.
527   ui::Accelerator accelerator = command_service->FindCommandByName(
528       kId, manifest_values::kBrowserActionCommandEvent).accelerator();
529   EXPECT_EQ(ui::VKEY_F, accelerator.key_code());
530   EXPECT_FALSE(accelerator.IsCtrlDown());
531   EXPECT_TRUE(accelerator.IsShiftDown());
532   EXPECT_TRUE(accelerator.IsAltDown());
533 
534   // Simulate the user setting the keybinding to Alt+Shift+G.
535   command_service->UpdateKeybindingPrefs(
536       kId, manifest_values::kBrowserActionCommandEvent, kAltShiftG);
537 
538   // Update to version 2 with different keybinding assigned.
539   EXPECT_TRUE(UpdateExtension(kId, path_v2_reassigned, 0));
540   EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
541               NULL);
542 
543   // Verify it has a command of Alt+Shift+G.
544   accelerator = command_service->FindCommandByName(
545       kId, manifest_values::kBrowserActionCommandEvent).accelerator();
546   EXPECT_EQ(ui::VKEY_G, accelerator.key_code());
547   EXPECT_FALSE(accelerator.IsCtrlDown());
548   EXPECT_TRUE(accelerator.IsShiftDown());
549   EXPECT_TRUE(accelerator.IsAltDown());
550 }
551 
IN_PROC_BROWSER_TEST_F(CommandsApiTest,ShortcutRemovedOnUpdateAfterBeingReassignedByUser)552 IN_PROC_BROWSER_TEST_F(CommandsApiTest,
553                        ShortcutRemovedOnUpdateAfterBeingReassignedByUser) {
554   base::ScopedTempDir scoped_temp_dir;
555   EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
556   base::FilePath pem_path = test_data_dir_.
557       AppendASCII("keybinding").AppendASCII("keybinding.pem");
558   base::FilePath path_v1 = PackExtensionWithOptions(
559       test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
560                     .AppendASCII("v1"),
561       scoped_temp_dir.path().AppendASCII("v1.crx"),
562       pem_path,
563       base::FilePath());
564   base::FilePath path_v2_unassigned = PackExtensionWithOptions(
565       test_data_dir_.AppendASCII("keybinding").AppendASCII("update")
566                     .AppendASCII("v2_unassigned"),
567       scoped_temp_dir.path().AppendASCII("v2_unassigned.crx"),
568       pem_path,
569       base::FilePath());
570 
571   ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
572   CommandService* command_service = CommandService::Get(browser()->profile());
573 
574   // Install v1 of the extension.
575   ASSERT_TRUE(InstallExtension(path_v1, 1));
576   EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
577               NULL);
578 
579   // Verify it has a command of Alt+Shift+F.
580   ui::Accelerator accelerator = command_service->FindCommandByName(
581       kId, manifest_values::kBrowserActionCommandEvent).accelerator();
582   EXPECT_EQ(ui::VKEY_F, accelerator.key_code());
583   EXPECT_FALSE(accelerator.IsCtrlDown());
584   EXPECT_TRUE(accelerator.IsShiftDown());
585   EXPECT_TRUE(accelerator.IsAltDown());
586 
587   // Simulate the user reassigning the keybinding to Alt+Shift+G.
588   command_service->UpdateKeybindingPrefs(
589       kId, manifest_values::kBrowserActionCommandEvent, kAltShiftG);
590 
591   // Update to version 2 without keybinding assigned.
592   EXPECT_TRUE(UpdateExtension(kId, path_v2_unassigned, 0));
593   EXPECT_TRUE(registry->GetExtensionById(kId, ExtensionRegistry::ENABLED) !=
594               NULL);
595 
596   // Verify the keybinding is still set.
597   accelerator = command_service->FindCommandByName(
598       kId, manifest_values::kBrowserActionCommandEvent).accelerator();
599   EXPECT_EQ(ui::VKEY_G, accelerator.key_code());
600   EXPECT_FALSE(accelerator.IsCtrlDown());
601   EXPECT_TRUE(accelerator.IsShiftDown());
602   EXPECT_TRUE(accelerator.IsAltDown());
603 }
604 
605 }  // namespace extensions
606