| // Copyright 2013 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/extensions/commands/command_service.h" |
| |
| #include <memory> |
| #include <utility> |
| |
| #include "base/files/file_util.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/threading/thread_restrictions.h" |
| #include "base/values.h" |
| #include "build/build_config.h" |
| #include "build/chromeos_buildflags.h" |
| #include "chrome/browser/extensions/extension_apitest.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/common/pref_names.h" |
| #include "components/prefs/scoped_user_pref_update.h" |
| #include "content/public/test/browser_test.h" |
| #include "content/public/test/test_utils.h" |
| #include "extensions/browser/extension_registry.h" |
| #include "extensions/common/api/extension_action/action_info.h" |
| #include "extensions/common/manifest_constants.h" |
| #include "extensions/test/test_extension_dir.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "ui/base/accelerators/command.h" |
| #include "ui/base/accelerators/command_constants.h" |
| #include "ui/events/keycodes/keyboard_codes.h" |
| |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| #include "chrome/browser/ui/browser.h" |
| #endif // BUILDFLAG(ENABLE_EXTENSIONS) |
| |
| namespace { |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| const char kBasicBrowserActionKeybinding[] = "Ctrl+Shift+F"; |
| const char kBasicNamedKeybinding[] = "Ctrl+Shift+Y"; |
| const char kBasicAlternateKeybinding[] = "Ctrl+Shift+G"; |
| const char kBasicNamedCommand[] = "toggle-feature"; |
| #endif // BUILDFLAG(ENABLE_EXTENSIONS) |
| constexpr char kAltNKeybinding[] = "Alt+N"; |
| constexpr char kAltZKeybinding[] = "Alt+Z"; |
| constexpr char kExtensionId[] = "pgoakhfeplldmjheffidklpoklkppipp"; |
| constexpr char kManifestTemplate[] = R"({ |
| "name": "An action to test if upgrading from MV2 to MV3 succeeds.", |
| "version": "1.0", |
| "manifest_version": %d, |
| "commands": { |
| "%s": { |
| "suggested_key": "%s" |
| } |
| }, |
| "%s": {}})"; |
| |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| // Get another command platform, which is used for simulating a command has been |
| // assigned with a shortcut on another platform. |
| std::string GetAnotherCommandPlatform() { |
| #if BUILDFLAG(IS_WIN) |
| return ui::kKeybindingPlatformMac; |
| #elif BUILDFLAG(IS_MAC) |
| return ui::kKeybindingPlatformChromeOs; |
| #elif BUILDFLAG(IS_CHROMEOS) |
| return ui::kKeybindingPlatformLinux; |
| #elif BUILDFLAG(IS_LINUX) |
| return ui::kKeybindingPlatformWin; |
| #else |
| return ""; |
| #endif |
| } |
| #endif |
| |
| // Parameters passed to CommandServiceMv3UpgradeTest parameterized tests. |
| struct ManifestCommandTestParameters { |
| const char* action_name; // e.g. "browser_action", "page_action". |
| const char* action_command_name; // e.g. "_execute_browser_action", |
| // "_execute_page_action". |
| // e.g. the associated folder below |
| // //chrome/test/data/extensions/api_test/keybinding/update/ that contains the |
| // unpacked extension files for webstore and .crx installs. |
| const char* action_command_mv2_extension_path; |
| }; |
| |
| } // namespace |
| |
| namespace extensions { |
| |
| using CommandServiceTest = ExtensionApiTest; |
| // Test class for testing keybinding changes across MV2->MV3 reloads/updates. |
| class CommandServiceMv3UpgradeTest |
| : public ExtensionApiTest, |
| public testing::WithParamInterface<ManifestCommandTestParameters> { |
| protected: |
| // Create a new extension from a manifest for MV2 and verify its command |
| // shortcuts are setup correctly. |
| std::string LoadExtensionMv2(const char* suggested_keybinding); |
| // Reload the extension from a manifest for MV3 and verify its command |
| // shortcut has the new suggested keybinding. |
| void ReloadExtensionMv3(const std::string& id, |
| const char* new_suggested_keybinding); |
| // Install an extension with `id`. `install_from_crx` = false means it will |
| // install from webstore. |
| void InstallExtensionMv2(const std::string& id, |
| bool install_from_crx = false); |
| // Update the extension with `id` (from webstore or via crx) from the |
| // `mv3_extension_upgrade_folder`. |
| void UpdateExtensionMv3(const std::string& id, |
| const char* mv3_extension_upgrade_folder); |
| // Modify the browser action keybinding as if it was modified by the user. |
| void ChangeMv2CommandKeybinding(const std::string& id, |
| const char* new_keybinding); |
| bool CommandHasAltPlusKeybinding(const std::string& id, |
| const char* action_command_name, |
| const ui::KeyboardCode key); |
| bool CommandHasNoKeybinding(const std::string& id, |
| const char* action_command_name); |
| // Checks that extension with `id` no longer has MV2 command action |
| // keybindings and now has an MV3 keybinding of Alt + `keyboard_code`. |
| void CheckMv3UpgradeHasExpectedKeybindings( |
| const std::string& id, |
| const ui::KeyboardCode keyboard_code); |
| |
| TestExtensionDir& test_dir() { return test_dir_; } |
| CommandService* command_service() { return CommandService::Get(profile()); } |
| |
| private: |
| TestExtensionDir test_dir_; |
| base::FilePath test_path_; |
| }; |
| |
| std::string CommandServiceMv3UpgradeTest::LoadExtensionMv2( |
| const char* suggested_keybinding) { |
| ManifestCommandTestParameters test_params = GetParam(); |
| test_dir().WriteManifest( |
| base::StringPrintf(kManifestTemplate, 2, test_params.action_command_name, |
| suggested_keybinding, test_params.action_name)); |
| |
| // Install MV2 of the extension. |
| const Extension* extension = LoadExtension( |
| test_dir().UnpackedPath(), {.wait_for_registration_stored = true}); |
| if (!extension) { |
| ADD_FAILURE() << "Couldn't load extension successfully for test setup."; |
| } |
| const std::string unpacked_extension_id = extension->id(); |
| EXPECT_TRUE(extension_registry()->enabled_extensions().Contains( |
| unpacked_extension_id)); |
| |
| // Verify it has an MV2 action command of Alt+N. |
| EXPECT_TRUE(CommandHasAltPlusKeybinding(unpacked_extension_id.c_str(), |
| test_params.action_command_name, |
| ui::VKEY_N)); |
| // Verify MV3 action command is set to nothing before we upgrade. |
| EXPECT_TRUE(CommandHasNoKeybinding(unpacked_extension_id.c_str(), |
| manifest_values::kActionCommandEvent)); |
| return unpacked_extension_id; |
| } |
| |
| void CommandServiceMv3UpgradeTest::ReloadExtensionMv3( |
| const std::string& id, |
| const char* new_suggested_keybinding) { |
| test_dir().WriteManifest(base::StringPrintf( |
| kManifestTemplate, 3, manifest_values::kActionCommandEvent, |
| new_suggested_keybinding, manifest_keys::kAction)); |
| ReloadExtension(id); |
| EXPECT_TRUE(extension_registry()->enabled_extensions().GetByID(id)); |
| } |
| |
| void CommandServiceMv3UpgradeTest::InstallExtensionMv2(const std::string& id, |
| bool install_from_crx) { |
| // TODO(jlulejian): Try to make these test class members for less repetition. |
| base::ScopedAllowBlockingForTesting allow_blocking; |
| base::ScopedTempDir scoped_temp_dir; |
| base::FilePath pem_path = |
| test_data_dir_.AppendASCII("keybinding").AppendASCII("keybinding.pem"); |
| ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir()); |
| |
| ManifestCommandTestParameters test_params = GetParam(); |
| base::FilePath path_mv2 = PackExtensionWithOptions( |
| test_data_dir_.AppendASCII("keybinding") |
| .AppendASCII("update") |
| .AppendASCII(test_params.action_command_mv2_extension_path), |
| scoped_temp_dir.GetPath().AppendASCII("v1.crx"), pem_path, |
| base::FilePath()); |
| ASSERT_FALSE(path_mv2.empty()); |
| |
| // Install MV2 of the extension. |
| if (install_from_crx) { |
| ASSERT_TRUE(InstallExtension(path_mv2, 1)); |
| } else { |
| ASSERT_TRUE(InstallExtensionFromWebstore(path_mv2, 1)); |
| } |
| EXPECT_TRUE(extension_registry()->enabled_extensions().GetByID(id)); |
| |
| // Verify it has an MV2 action command of Alt+N. |
| EXPECT_TRUE(CommandHasAltPlusKeybinding(id, test_params.action_command_name, |
| ui::VKEY_N)); |
| // Verify MV3 action command is set to nothing before we upgrade. |
| EXPECT_TRUE(CommandHasNoKeybinding(id, manifest_values::kActionCommandEvent)); |
| } |
| |
| void CommandServiceMv3UpgradeTest::UpdateExtensionMv3( |
| const std::string& id, |
| const char* mv3_extension_upgrade_folder) { |
| // TODO(jlulejian): Try to make these test class members for less repetition. |
| base::ScopedAllowBlockingForTesting allow_blocking; |
| base::ScopedTempDir scoped_temp_dir; |
| base::FilePath pem_path = |
| test_data_dir_.AppendASCII("keybinding").AppendASCII("keybinding.pem"); |
| ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir()); |
| |
| base::FilePath path_mv3 = |
| PackExtensionWithOptions(test_data_dir_.AppendASCII("keybinding") |
| .AppendASCII("update") |
| .AppendASCII(mv3_extension_upgrade_folder), |
| scoped_temp_dir.GetPath().AppendASCII("v2.crx"), |
| pem_path, base::FilePath()); |
| ASSERT_FALSE(path_mv3.empty()); |
| |
| // Update to MV3 with an action command instead of a browser action. |
| ASSERT_TRUE(UpdateExtension(id, path_mv3, 0)); |
| EXPECT_TRUE(extension_registry()->enabled_extensions().GetByID(id)); |
| } |
| |
| void CommandServiceMv3UpgradeTest::ChangeMv2CommandKeybinding( |
| const std::string& id, |
| const char* new_keybinding) { |
| const char* action_command_name = GetParam().action_command_name; |
| Command action_command = |
| command_service()->FindCommandByName(id, action_command_name); |
| command_service()->UpdateKeybindingPrefs(id, action_command_name, |
| new_keybinding); |
| } |
| |
| void CommandServiceMv3UpgradeTest::CheckMv3UpgradeHasExpectedKeybindings( |
| const std::string& id, |
| const ui::KeyboardCode keyboard_code) { |
| // Verify both MV2 commands are set to nothing. |
| EXPECT_TRUE( |
| CommandHasNoKeybinding(id, manifest_values::kBrowserActionCommandEvent)); |
| EXPECT_TRUE( |
| CommandHasNoKeybinding(id, manifest_values::kPageActionCommandEvent)); |
| |
| // Verify extension now has an MV3 action command of Alt+<keyboard_code>. |
| EXPECT_TRUE(CommandHasAltPlusKeybinding( |
| id, manifest_values::kActionCommandEvent, keyboard_code)); |
| } |
| |
| bool CommandServiceMv3UpgradeTest::CommandHasAltPlusKeybinding( |
| const std::string& id, |
| const char* action_command_name, |
| const ui::KeyboardCode key) { |
| ui::Accelerator accelerator = command_service() |
| ->FindCommandByName(id, action_command_name) |
| .accelerator(); |
| return key == accelerator.key_code() && accelerator.IsAltDown() && |
| !accelerator.IsShiftDown() && !accelerator.IsCtrlDown(); |
| } |
| bool CommandServiceMv3UpgradeTest::CommandHasNoKeybinding( |
| const std::string& id, |
| const char* action_command_name) { |
| ui::Accelerator accelerator = command_service() |
| ->FindCommandByName(id, action_command_name) |
| .accelerator(); |
| return ui::VKEY_UNKNOWN == accelerator.key_code(); |
| } |
| |
| // Tests that a suggested keybinding for an action command in MV2 persists when |
| // the extension is reloaded (unpacked) and upgraded to MV3 |
| // (_execute_action_command). |
| IN_PROC_BROWSER_TEST_P(CommandServiceMv3UpgradeTest, |
| ActionCommandUpgradesDuringReload) { |
| const std::string unpacked_extension_id = LoadExtensionMv2( |
| /*suggested_keybinding=*/kAltNKeybinding); |
| ReloadExtensionMv3(unpacked_extension_id, |
| /*new_suggested_keybinding=*/kAltNKeybinding); |
| ASSERT_FALSE(HasFatalFailure() && HasNonfatalFailure()); |
| |
| CheckMv3UpgradeHasExpectedKeybindings(unpacked_extension_id, |
| /*keyboard_code=*/ui::VKEY_N); |
| } |
| |
| // Tests that a suggested keybinding for an action command in MV2 persists when |
| // the extension is updated from the webstore and upgraded to MV3 |
| // (_execute_action_command). |
| IN_PROC_BROWSER_TEST_P(CommandServiceMv3UpgradeTest, |
| ActionCommandUpgradesDuringWebstoreUpdate) { |
| InstallExtensionMv2(kExtensionId); |
| UpdateExtensionMv3(kExtensionId, |
| /*mv3_extension_upgrade_folder=*/"v2_upgrade"); |
| ASSERT_FALSE(HasFatalFailure() && HasNonfatalFailure()); |
| |
| CheckMv3UpgradeHasExpectedKeybindings(kExtensionId, |
| /*keyboard_code=*/ui::VKEY_N); |
| } |
| |
| // Tests that a suggested keybinding for an action command in MV2 persists when |
| // the extension is updated (via .crx) and upgraded to MV3 |
| // (_execute_action_command). |
| IN_PROC_BROWSER_TEST_P(CommandServiceMv3UpgradeTest, |
| ActionCommandUpgradesDuringCrxUpdate) { |
| InstallExtensionMv2(kExtensionId, /*install_from_crx=*/true); |
| UpdateExtensionMv3(kExtensionId, |
| /*mv3_extension_upgrade_folder=*/"v2_upgrade"); |
| ASSERT_FALSE(HasFatalFailure() && HasNonfatalFailure()); |
| |
| CheckMv3UpgradeHasExpectedKeybindings(kExtensionId, |
| /*keyboard_code=*/ui::VKEY_N); |
| } |
| |
| // Tests that a user modified keybinding for an action command in MV2 persists |
| // when the extension is reloaded (unpacked) and upgraded to MV3 |
| // (_execute_action_command). |
| IN_PROC_BROWSER_TEST_P(CommandServiceMv3UpgradeTest, |
| UserModifiedActionCommandSurvivesReload) { |
| const std::string unpacked_extension_id = LoadExtensionMv2( |
| /*suggested_keybinding=*/kAltNKeybinding); |
| ChangeMv2CommandKeybinding(unpacked_extension_id, |
| /*new_keybinding=*/kAltZKeybinding); |
| ReloadExtensionMv3(unpacked_extension_id, |
| /*new_suggested_keybinding=*/kAltNKeybinding); |
| ASSERT_FALSE(HasFatalFailure() && HasNonfatalFailure()); |
| |
| CheckMv3UpgradeHasExpectedKeybindings(unpacked_extension_id, |
| /*keyboard_code=*/ui::VKEY_Z); |
| } |
| |
| // Tests that a user-modified keybinding for an action command in MV2 persists |
| // when the extension is updated from the webstore and upgraded to MV3 |
| // (_execute_action_command). |
| IN_PROC_BROWSER_TEST_P(CommandServiceMv3UpgradeTest, |
| UserModifiedCommandSurvivesWebstoreUpdate) { |
| InstallExtensionMv2(kExtensionId); |
| ChangeMv2CommandKeybinding(kExtensionId, |
| /*new_keybinding=*/kAltZKeybinding); |
| UpdateExtensionMv3(kExtensionId, |
| /*mv3_extension_upgrade_folder=*/"v2_upgrade"); |
| ASSERT_FALSE(HasFatalFailure() && HasNonfatalFailure()); |
| |
| CheckMv3UpgradeHasExpectedKeybindings(kExtensionId, |
| /*keyboard_code=*/ui::VKEY_Z); |
| } |
| |
| // Tests that a user modified keybinding for an action command in MV2 persists |
| // when the extension is updated (via .crx) and upgraded to MV3 |
| // (_execute_action_command). |
| IN_PROC_BROWSER_TEST_P(CommandServiceMv3UpgradeTest, |
| UserModifiedCommandSurvivesCrxUpdate) { |
| InstallExtensionMv2(kExtensionId, /*install_from_crx=*/true); |
| ChangeMv2CommandKeybinding(kExtensionId, |
| /*new_keybinding=*/kAltZKeybinding); |
| UpdateExtensionMv3(kExtensionId, |
| /*mv3_extension_upgrade_folder=*/"v2_upgrade"); |
| ASSERT_FALSE(HasFatalFailure() && HasNonfatalFailure()); |
| |
| CheckMv3UpgradeHasExpectedKeybindings(kExtensionId, |
| /*keyboard_code=*/ui::VKEY_Z); |
| } |
| |
| // Tests that a modified suggested keybinding for an action command in MV2 |
| // persists when the extension is reloaded (unpacked) and upgraded to MV3 |
| // (_execute_action_command). |
| IN_PROC_BROWSER_TEST_P(CommandServiceMv3UpgradeTest, |
| SuggestedKeyModifiedActionCommandSurvivesReload) { |
| const std::string unpacked_extension_id = LoadExtensionMv2( |
| /*suggested_keybinding=*/kAltNKeybinding); |
| ReloadExtensionMv3(unpacked_extension_id, |
| /*new_suggested_keybinding=*/"Alt+U"); |
| ASSERT_FALSE(HasFatalFailure() && HasNonfatalFailure()); |
| |
| CheckMv3UpgradeHasExpectedKeybindings(unpacked_extension_id, |
| /*keyboard_code=*/ui::VKEY_U); |
| } |
| |
| // Tests that a modified suggested keybinding for an action command in MV2 |
| // persists when the extension is updated (via webstore) and upgraded to MV3 |
| // (_execute_action_command). |
| IN_PROC_BROWSER_TEST_P(CommandServiceMv3UpgradeTest, |
| SuggestedKeyModifiedActionCommandSurvivesWebstore) { |
| InstallExtensionMv2(kExtensionId); |
| UpdateExtensionMv3(kExtensionId, "v2_upgrade_reassign"); |
| ASSERT_FALSE(HasFatalFailure() && HasNonfatalFailure()); |
| |
| CheckMv3UpgradeHasExpectedKeybindings(kExtensionId, |
| /*keyboard_code=*/ui::VKEY_U); |
| } |
| |
| // Tests that a modified suggested keybinding for an action command in MV2 |
| // persists when the extension is updated (via .crx) and upgraded to MV3 |
| // (_execute_action_command). |
| IN_PROC_BROWSER_TEST_P(CommandServiceMv3UpgradeTest, |
| SuggestedKeyModifiedActionCommandSurvivesCrx) { |
| InstallExtensionMv2(kExtensionId, /*install_from_crx=*/true); |
| UpdateExtensionMv3(kExtensionId, |
| /*mv3_extension_upgrade_folder=*/"v2_upgrade_reassign"); |
| ASSERT_FALSE(HasFatalFailure() && HasNonfatalFailure()); |
| |
| CheckMv3UpgradeHasExpectedKeybindings(kExtensionId, |
| /*keyboard_code=*/ui::VKEY_U); |
| } |
| |
| // TODO(crbug.com/404070124): Enable on desktop android. |
| #if BUILDFLAG(ENABLE_EXTENSIONS) |
| IN_PROC_BROWSER_TEST_F(CommandServiceTest, RemoveShortcutSurvivesUpdate) { |
| base::ScopedAllowBlockingForTesting allow_blocking; |
| base::ScopedTempDir scoped_temp_dir; |
| EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir()); |
| base::FilePath pem_path = test_data_dir_. |
| AppendASCII("keybinding").AppendASCII("keybinding.pem"); |
| base::FilePath path_v1 = |
| PackExtensionWithOptions(test_data_dir_.AppendASCII("keybinding") |
| .AppendASCII("update") |
| .AppendASCII("v1"), |
| scoped_temp_dir.GetPath().AppendASCII("v1.crx"), |
| pem_path, base::FilePath()); |
| base::FilePath path_v2 = |
| PackExtensionWithOptions(test_data_dir_.AppendASCII("keybinding") |
| .AppendASCII("update") |
| .AppendASCII("v2"), |
| scoped_temp_dir.GetPath().AppendASCII("v2.crx"), |
| pem_path, base::FilePath()); |
| |
| ExtensionRegistry* registry = ExtensionRegistry::Get(profile()); |
| CommandService* command_service = CommandService::Get(profile()); |
| |
| // Install v1 of the extension. |
| ASSERT_TRUE(InstallExtension(path_v1, 1)); |
| EXPECT_TRUE(registry->enabled_extensions().GetByID(kExtensionId)); |
| |
| // Verify it has a command of Alt+Shift+F. |
| ui::Accelerator accelerator = |
| command_service |
| ->FindCommandByName(kExtensionId, |
| manifest_values::kBrowserActionCommandEvent) |
| .accelerator(); |
| EXPECT_EQ(ui::VKEY_F, accelerator.key_code()); |
| EXPECT_FALSE(accelerator.IsCtrlDown()); |
| EXPECT_TRUE(accelerator.IsShiftDown()); |
| EXPECT_TRUE(accelerator.IsAltDown()); |
| |
| // Remove the keybinding. |
| command_service->UpdateKeybindingPrefs( |
| kExtensionId, manifest_values::kBrowserActionCommandEvent, |
| /*keystroke=*/""); |
| |
| // Verify it got removed. |
| accelerator = |
| command_service |
| ->FindCommandByName(kExtensionId, |
| manifest_values::kBrowserActionCommandEvent) |
| .accelerator(); |
| EXPECT_EQ(ui::VKEY_UNKNOWN, accelerator.key_code()); |
| |
| // Update to version 2. |
| EXPECT_TRUE(UpdateExtension(kExtensionId, path_v2, 0)); |
| EXPECT_TRUE(registry->enabled_extensions().GetByID(kExtensionId)); |
| |
| // Verify it is still set to nothing. |
| accelerator = |
| command_service |
| ->FindCommandByName(kExtensionId, |
| manifest_values::kBrowserActionCommandEvent) |
| .accelerator(); |
| EXPECT_EQ(ui::VKEY_UNKNOWN, accelerator.key_code()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(CommandServiceTest, |
| RemoveKeybindingPrefsShouldBePlatformSpecific) { |
| base::FilePath extension_dir = |
| test_data_dir_.AppendASCII("keybinding").AppendASCII("basics"); |
| const Extension* extension = InstallExtension(extension_dir, 1); |
| ASSERT_TRUE(extension); |
| |
| ScopedDictPrefUpdate updater(profile()->GetPrefs(), |
| prefs::kExtensionCommands); |
| base::Value::Dict& bindings = updater.Get(); |
| |
| // Simulate command |toggle-feature| has been assigned with a shortcut on |
| // another platform. |
| std::string anotherPlatformKey = GetAnotherCommandPlatform() + ":Alt+G"; |
| const char kNamedCommandName[] = "toggle-feature"; |
| base::Value::Dict keybinding; |
| keybinding.Set("extension", extension->id()); |
| keybinding.Set("command_name", kNamedCommandName); |
| keybinding.Set("global", false); |
| bindings.Set(anotherPlatformKey, std::move(keybinding)); |
| |
| CommandService* command_service = CommandService::Get(profile()); |
| command_service->RemoveKeybindingPrefs(extension->id(), kNamedCommandName); |
| |
| // Removal of keybinding preference should be platform-specific, so the key on |
| // another platform should always remained. |
| EXPECT_TRUE(bindings.Find(anotherPlatformKey)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(CommandServiceTest, |
| GetExtensionActionCommandQueryAll) { |
| base::FilePath extension_dir = |
| test_data_dir_.AppendASCII("keybinding").AppendASCII("basics"); |
| const Extension* extension = InstallExtension(extension_dir, 1); |
| ASSERT_TRUE(extension); |
| |
| CommandService* command_service = CommandService::Get(profile()); |
| |
| { |
| Command command; |
| bool active = false; |
| EXPECT_TRUE(command_service->GetExtensionActionCommand( |
| extension->id(), ActionInfo::Type::kBrowser, CommandService::ALL, |
| &command, &active)); |
| |
| EXPECT_EQ(kBasicBrowserActionKeybinding, |
| Command::AcceleratorToString(command.accelerator())); |
| EXPECT_TRUE(active); |
| } |
| |
| command_service->UpdateKeybindingPrefs( |
| extension->id(), manifest_values::kBrowserActionCommandEvent, |
| kBasicAlternateKeybinding); |
| |
| { |
| Command command; |
| bool active = false; |
| EXPECT_TRUE(command_service->GetExtensionActionCommand( |
| extension->id(), ActionInfo::Type::kBrowser, CommandService::ALL, |
| &command, &active)); |
| |
| EXPECT_EQ(kBasicAlternateKeybinding, |
| Command::AcceleratorToString(command.accelerator())); |
| EXPECT_TRUE(active); |
| } |
| |
| command_service->RemoveKeybindingPrefs( |
| extension->id(), manifest_values::kBrowserActionCommandEvent); |
| |
| { |
| Command command; |
| bool active = true; |
| EXPECT_TRUE(command_service->GetExtensionActionCommand( |
| extension->id(), ActionInfo::Type::kBrowser, CommandService::ALL, |
| &command, &active)); |
| |
| EXPECT_EQ(kBasicBrowserActionKeybinding, |
| Command::AcceleratorToString(command.accelerator())); |
| EXPECT_FALSE(active); |
| } |
| |
| command_service->UpdateKeybindingPrefs( |
| extension->id(), manifest_values::kBrowserActionCommandEvent, |
| /*keystroke=*/""); |
| |
| { |
| Command command; |
| bool active = true; |
| EXPECT_TRUE(command_service->GetExtensionActionCommand( |
| extension->id(), ActionInfo::Type::kBrowser, CommandService::ALL, |
| &command, &active)); |
| |
| EXPECT_EQ(ui::VKEY_UNKNOWN, command.accelerator().key_code()); |
| EXPECT_FALSE(active); |
| } |
| } |
| |
| IN_PROC_BROWSER_TEST_F(CommandServiceTest, |
| GetExtensionActionCommandQueryActive) { |
| base::FilePath extension_dir = |
| test_data_dir_.AppendASCII("keybinding").AppendASCII("basics"); |
| const Extension* extension = InstallExtension(extension_dir, 1); |
| ASSERT_TRUE(extension); |
| |
| CommandService* command_service = CommandService::Get(profile()); |
| |
| { |
| Command command; |
| bool active = false; |
| EXPECT_TRUE(command_service->GetExtensionActionCommand( |
| extension->id(), ActionInfo::Type::kBrowser, CommandService::ACTIVE, |
| &command, &active)); |
| |
| EXPECT_EQ(kBasicBrowserActionKeybinding, |
| Command::AcceleratorToString(command.accelerator())); |
| EXPECT_TRUE(active); |
| } |
| |
| command_service->UpdateKeybindingPrefs( |
| extension->id(), manifest_values::kBrowserActionCommandEvent, |
| kBasicAlternateKeybinding); |
| |
| { |
| Command command; |
| bool active = false; |
| EXPECT_TRUE(command_service->GetExtensionActionCommand( |
| extension->id(), ActionInfo::Type::kBrowser, CommandService::ACTIVE, |
| &command, &active)); |
| |
| EXPECT_EQ(kBasicAlternateKeybinding, |
| Command::AcceleratorToString(command.accelerator())); |
| EXPECT_TRUE(active); |
| } |
| |
| command_service->RemoveKeybindingPrefs( |
| extension->id(), manifest_values::kBrowserActionCommandEvent); |
| |
| { |
| Command command; |
| bool active = false; |
| EXPECT_FALSE(command_service->GetExtensionActionCommand( |
| extension->id(), ActionInfo::Type::kBrowser, CommandService::ACTIVE, |
| &command, &active)); |
| } |
| } |
| |
| IN_PROC_BROWSER_TEST_F(CommandServiceTest, |
| GetNamedCommandsQueryAll) { |
| base::FilePath extension_dir = |
| test_data_dir_.AppendASCII("keybinding").AppendASCII("basics"); |
| const Extension* extension = InstallExtension(extension_dir, 1); |
| ASSERT_TRUE(extension); |
| |
| CommandService* command_service = CommandService::Get(profile()); |
| |
| { |
| ui::CommandMap command_map; |
| EXPECT_TRUE(command_service->GetNamedCommands( |
| extension->id(), CommandService::ALL, CommandService::ANY_SCOPE, |
| &command_map)); |
| |
| ASSERT_EQ(1u, command_map.count(kBasicNamedCommand)); |
| ui::Command command = command_map[kBasicNamedCommand]; |
| EXPECT_EQ(kBasicNamedKeybinding, |
| Command::AcceleratorToString(command.accelerator())); |
| } |
| |
| command_service->UpdateKeybindingPrefs( |
| extension->id(), kBasicNamedCommand, kBasicAlternateKeybinding); |
| |
| { |
| ui::CommandMap command_map; |
| EXPECT_TRUE(command_service->GetNamedCommands( |
| extension->id(), CommandService::ALL, CommandService::ANY_SCOPE, |
| &command_map)); |
| |
| ASSERT_EQ(1u, command_map.count(kBasicNamedCommand)); |
| ui::Command command = command_map[kBasicNamedCommand]; |
| EXPECT_EQ(kBasicAlternateKeybinding, |
| Command::AcceleratorToString(command.accelerator())); |
| } |
| |
| // Tests that removing the keybinding pref restores the default binding. |
| command_service->RemoveKeybindingPrefs(extension->id(), kBasicNamedCommand); |
| |
| { |
| ui::CommandMap command_map; |
| EXPECT_TRUE(command_service->GetNamedCommands( |
| extension->id(), CommandService::ALL, CommandService::ANY_SCOPE, |
| &command_map)); |
| |
| ASSERT_EQ(1u, command_map.count(kBasicNamedCommand)); |
| ui::Command command = command_map[kBasicNamedCommand]; |
| EXPECT_EQ(kBasicNamedKeybinding, |
| Command::AcceleratorToString(command.accelerator())); |
| } |
| |
| // Tests that setting an empty keybinding string unsets the binding. |
| command_service->UpdateKeybindingPrefs(extension->id(), kBasicNamedCommand, |
| /*keystroke=*/""); |
| { |
| ui::CommandMap command_map; |
| EXPECT_TRUE(command_service->GetNamedCommands( |
| extension->id(), CommandService::ALL, CommandService::ANY_SCOPE, |
| &command_map)); |
| |
| ASSERT_EQ(1u, command_map.count(kBasicNamedCommand)); |
| ui::Command command = command_map[kBasicNamedCommand]; |
| EXPECT_EQ(ui::VKEY_UNKNOWN, command.accelerator().key_code()); |
| } |
| } |
| |
| IN_PROC_BROWSER_TEST_F(CommandServiceTest, GetNamedCommandsQueryActive) { |
| base::FilePath extension_dir = |
| test_data_dir_.AppendASCII("keybinding").AppendASCII("basics"); |
| const Extension* extension = InstallExtension(extension_dir, 1); |
| ASSERT_TRUE(extension); |
| |
| CommandService* command_service = CommandService::Get(profile()); |
| |
| { |
| ui::CommandMap command_map; |
| EXPECT_TRUE(command_service->GetNamedCommands( |
| extension->id(), CommandService::ACTIVE, CommandService::ANY_SCOPE, |
| &command_map)); |
| |
| ASSERT_EQ(1u, command_map.count(kBasicNamedCommand)); |
| ui::Command command = command_map[kBasicNamedCommand]; |
| EXPECT_EQ(kBasicNamedKeybinding, |
| Command::AcceleratorToString(command.accelerator())); |
| } |
| |
| command_service->UpdateKeybindingPrefs( |
| extension->id(), kBasicNamedCommand, kBasicAlternateKeybinding); |
| |
| { |
| ui::CommandMap command_map; |
| EXPECT_TRUE(command_service->GetNamedCommands( |
| extension->id(), CommandService::ACTIVE, CommandService::ANY_SCOPE, |
| &command_map)); |
| |
| ASSERT_EQ(1u, command_map.count(kBasicNamedCommand)); |
| ui::Command command = command_map[kBasicNamedCommand]; |
| EXPECT_EQ(kBasicAlternateKeybinding, |
| Command::AcceleratorToString(command.accelerator())); |
| } |
| |
| command_service->RemoveKeybindingPrefs(extension->id(), kBasicNamedCommand); |
| |
| { |
| ui::CommandMap command_map; |
| command_service->GetNamedCommands( |
| extension->id(), CommandService::ACTIVE, CommandService::ANY_SCOPE, |
| &command_map); |
| EXPECT_EQ(0u, command_map.count(kBasicNamedCommand)); |
| } |
| } |
| #endif // BUILDFLAG(ENABLE_EXTENSIONS) |
| |
| // Test both browser and page actions for these tests. |
| INSTANTIATE_TEST_SUITE_P(BrowserAction, |
| CommandServiceMv3UpgradeTest, |
| testing::Values(ManifestCommandTestParameters{ |
| manifest_keys::kBrowserAction, |
| manifest_values::kBrowserActionCommandEvent, |
| "v1_upgrade_browser_action"})); |
| |
| INSTANTIATE_TEST_SUITE_P(PageAction, |
| CommandServiceMv3UpgradeTest, |
| testing::Values(ManifestCommandTestParameters{ |
| manifest_keys::kPageAction, |
| manifest_values::kPageActionCommandEvent, |
| "v1_upgrade_page_action"})); |
| |
| } // namespace extensions |