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 27using content::WebContents; 28 29namespace extensions { 30 31namespace { 32// This extension ID is used for tests require a stable ID over multiple 33// extension installs. 34const 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. 38const char kAltShiftG[] = "Alt+Shift+G"; 39} 40 41class CommandsApiTest : public ExtensionApiTest { 42 public: 43 CommandsApiTest() {} 44 virtual ~CommandsApiTest() {} 45 46 protected: 47 BrowserActionTestUtil GetBrowserActionsBar() { 48 return BrowserActionTestUtil(browser()); 49 } 50 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. 64IN_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 125IN_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. 169IN_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. 176IN_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. 243IN_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. 293IN_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 311IN_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 356IN_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 404IN_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 449IN_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 499IN_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 552IN_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