// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "build/build_config.h" #include "chrome/browser/extensions/api/commands/command_service.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_service.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/common/manifest_constants.h" namespace { const char kBasicBrowserActionKeybinding[] = "Ctrl+Shift+F"; const char kBasicNamedKeybinding[] = "Ctrl+Shift+Y"; const char kBasicAlternateKeybinding[] = "Ctrl+Shift+G"; const char kBasicNamedCommand[] = "toggle-feature"; // Get another command platform, whcih is used for simulating a command has been // assigned with a shortcut on another platform. std::string GetAnotherCommandPlatform() { #if defined(OS_WIN) return extensions::manifest_values::kKeybindingPlatformMac; #elif defined(OS_MACOSX) return extensions::manifest_values::kKeybindingPlatformChromeOs; #elif defined(OS_CHROMEOS) return extensions::manifest_values::kKeybindingPlatformLinux; #elif defined(OS_LINUX) return extensions::manifest_values::kKeybindingPlatformWin; #else return ""; #endif } } // namespace namespace extensions { typedef ExtensionApiTest CommandServiceTest; IN_PROC_BROWSER_TEST_F(CommandServiceTest, RemoveShortcutSurvivesUpdate) { 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.path().AppendASCII("v1.crx"), pem_path, base::FilePath()); base::FilePath path_v2 = PackExtensionWithOptions( test_data_dir_.AppendASCII("keybinding").AppendASCII("update") .AppendASCII("v2"), scoped_temp_dir.path().AppendASCII("v2.crx"), pem_path, base::FilePath()); ExtensionService* service = ExtensionSystem::Get(browser()->profile())-> extension_service(); CommandService* command_service = CommandService::Get(browser()->profile()); const char kId[] = "pgoakhfeplldmjheffidklpoklkppipp"; // Install v1 of the extension. ASSERT_TRUE(InstallExtension(path_v1, 1)); EXPECT_TRUE(service->GetExtensionById(kId, false) != NULL); // Verify it has a command of Alt+Shift+F. ui::Accelerator accelerator = command_service->FindCommandByName( kId, 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->RemoveKeybindingPrefs( kId, manifest_values::kBrowserActionCommandEvent); // Verify it got removed. accelerator = command_service->FindCommandByName( kId, manifest_values::kBrowserActionCommandEvent).accelerator(); EXPECT_EQ(ui::VKEY_UNKNOWN, accelerator.key_code()); // Update to version 2. EXPECT_TRUE(UpdateExtension(kId, path_v2, 0)); EXPECT_TRUE(service->GetExtensionById(kId, false) != NULL); // Verify it is still set to nothing. accelerator = command_service->FindCommandByName( kId, 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); DictionaryPrefUpdate updater(browser()->profile()->GetPrefs(), prefs::kExtensionCommands); base::DictionaryValue* 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::DictionaryValue* keybinding = new base::DictionaryValue(); keybinding->SetString("extension", extension->id()); keybinding->SetString("command_name", kNamedCommandName); keybinding->SetBoolean("global", false); bindings->Set(anotherPlatformKey, keybinding); CommandService* command_service = CommandService::Get(browser()->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->HasKey(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(browser()->profile()); { Command command; bool active = false; EXPECT_TRUE(command_service->GetBrowserActionCommand( extension->id(), 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->GetBrowserActionCommand( extension->id(), 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->GetBrowserActionCommand( extension->id(), CommandService::ALL, &command, &active)); EXPECT_EQ(kBasicBrowserActionKeybinding, Command::AcceleratorToString(command.accelerator())); 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(browser()->profile()); { Command command; bool active = false; EXPECT_TRUE(command_service->GetBrowserActionCommand( extension->id(), 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->GetBrowserActionCommand( extension->id(), 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->GetBrowserActionCommand( extension->id(), CommandService::ACTIVE, &command, &active)); } } IN_PROC_BROWSER_TEST_F(CommandServiceTest, GetExtensionActionCommandQuerySuggested) { 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(browser()->profile()); { Command command; bool active = false; EXPECT_TRUE(command_service->GetBrowserActionCommand( extension->id(), CommandService::SUGGESTED, &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 = true; EXPECT_TRUE(command_service->GetBrowserActionCommand( extension->id(), CommandService::SUGGESTED, &command, &active)); EXPECT_EQ(kBasicBrowserActionKeybinding, Command::AcceleratorToString(command.accelerator())); EXPECT_FALSE(active); } command_service->RemoveKeybindingPrefs( extension->id(), manifest_values::kBrowserActionCommandEvent); { Command command; bool active = true; EXPECT_TRUE(command_service->GetBrowserActionCommand( extension->id(), CommandService::SUGGESTED, &command, &active)); EXPECT_EQ(kBasicBrowserActionKeybinding, Command::AcceleratorToString(command.accelerator())); EXPECT_FALSE(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(browser()->profile()); { CommandMap command_map; EXPECT_TRUE(command_service->GetNamedCommands( extension->id(), CommandService::ALL, CommandService::ANY_SCOPE, &command_map)); ASSERT_EQ(1u, command_map.count(kBasicNamedCommand)); Command command = command_map[kBasicNamedCommand]; EXPECT_EQ(kBasicNamedKeybinding, Command::AcceleratorToString(command.accelerator())); } command_service->UpdateKeybindingPrefs( extension->id(), kBasicNamedCommand, kBasicAlternateKeybinding); { CommandMap command_map; EXPECT_TRUE(command_service->GetNamedCommands( extension->id(), CommandService::ALL, CommandService::ANY_SCOPE, &command_map)); ASSERT_EQ(1u, command_map.count(kBasicNamedCommand)); Command command = command_map[kBasicNamedCommand]; EXPECT_EQ(kBasicAlternateKeybinding, Command::AcceleratorToString(command.accelerator())); } command_service->RemoveKeybindingPrefs(extension->id(), kBasicNamedCommand); { CommandMap command_map; EXPECT_TRUE(command_service->GetNamedCommands( extension->id(), CommandService::ALL, CommandService::ANY_SCOPE, &command_map)); ASSERT_EQ(1u, command_map.count(kBasicNamedCommand)); Command command = command_map[kBasicNamedCommand]; EXPECT_EQ(kBasicNamedKeybinding, Command::AcceleratorToString(command.accelerator())); } } 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(browser()->profile()); { CommandMap command_map; EXPECT_TRUE(command_service->GetNamedCommands( extension->id(), CommandService::ACTIVE, CommandService::ANY_SCOPE, &command_map)); ASSERT_EQ(1u, command_map.count(kBasicNamedCommand)); Command command = command_map[kBasicNamedCommand]; EXPECT_EQ(kBasicNamedKeybinding, Command::AcceleratorToString(command.accelerator())); } command_service->UpdateKeybindingPrefs( extension->id(), kBasicNamedCommand, kBasicAlternateKeybinding); { CommandMap command_map; EXPECT_TRUE(command_service->GetNamedCommands( extension->id(), CommandService::ACTIVE, CommandService::ANY_SCOPE, &command_map)); ASSERT_EQ(1u, command_map.count(kBasicNamedCommand)); Command command = command_map[kBasicNamedCommand]; EXPECT_EQ(kBasicAlternateKeybinding, Command::AcceleratorToString(command.accelerator())); } command_service->RemoveKeybindingPrefs(extension->id(), kBasicNamedCommand); { CommandMap command_map; command_service->GetNamedCommands( extension->id(), CommandService::ACTIVE, CommandService::ANY_SCOPE, &command_map); EXPECT_EQ(0u, command_map.count(kBasicNamedCommand)); } } IN_PROC_BROWSER_TEST_F(CommandServiceTest, GetNamedCommandsQuerySuggested) { 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(browser()->profile()); { CommandMap command_map; EXPECT_TRUE(command_service->GetNamedCommands( extension->id(), CommandService::SUGGESTED, CommandService::ANY_SCOPE, &command_map)); ASSERT_EQ(1u, command_map.count(kBasicNamedCommand)); Command command = command_map[kBasicNamedCommand]; EXPECT_EQ(kBasicNamedKeybinding, Command::AcceleratorToString(command.accelerator())); } command_service->UpdateKeybindingPrefs( extension->id(), kBasicNamedCommand, kBasicAlternateKeybinding); { CommandMap command_map; EXPECT_TRUE(command_service->GetNamedCommands( extension->id(), CommandService::SUGGESTED, CommandService::ANY_SCOPE, &command_map)); ASSERT_EQ(1u, command_map.count(kBasicNamedCommand)); Command command = command_map[kBasicNamedCommand]; EXPECT_EQ(kBasicNamedKeybinding, Command::AcceleratorToString(command.accelerator())); } command_service->RemoveKeybindingPrefs(extension->id(), kBasicNamedCommand); { CommandMap command_map; EXPECT_TRUE(command_service->GetNamedCommands( extension->id(), CommandService::SUGGESTED, CommandService::ANY_SCOPE, &command_map)); ASSERT_EQ(1u, command_map.count(kBasicNamedCommand)); Command command = command_map[kBasicNamedCommand]; EXPECT_EQ(kBasicNamedKeybinding, Command::AcceleratorToString(command.accelerator())); } } } // namespace extensions