1 // Copyright (c) 2013 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 "chrome/browser/extensions/extension_commands_global_registry.h" 6 7 #include "base/lazy_instance.h" 8 #include "chrome/browser/chrome_notification_types.h" 9 #include "chrome/browser/extensions/api/commands/command_service.h" 10 #include "chrome/browser/extensions/extension_keybinding_registry.h" 11 #include "chrome/browser/extensions/extension_service.h" 12 #include "chrome/browser/extensions/global_shortcut_listener.h" 13 #include "chrome/browser/profiles/profile.h" 14 #include "extensions/common/extension.h" 15 16 namespace extensions { 17 18 ExtensionCommandsGlobalRegistry::ExtensionCommandsGlobalRegistry( 19 Profile* profile) 20 : ExtensionKeybindingRegistry( 21 profile, ExtensionKeybindingRegistry::ALL_EXTENSIONS, NULL), 22 profile_(profile) { 23 Init(); 24 } 25 26 ExtensionCommandsGlobalRegistry::~ExtensionCommandsGlobalRegistry() { 27 for (EventTargets::const_iterator iter = event_targets_.begin(); 28 iter != event_targets_.end(); ++iter) { 29 GlobalShortcutListener::GetInstance()->UnregisterAccelerator( 30 iter->first, this); 31 } 32 } 33 34 static base::LazyInstance< 35 ProfileKeyedAPIFactory<ExtensionCommandsGlobalRegistry> > 36 g_factory = LAZY_INSTANCE_INITIALIZER; 37 38 // static 39 ProfileKeyedAPIFactory<ExtensionCommandsGlobalRegistry>* 40 ExtensionCommandsGlobalRegistry::GetFactoryInstance() { 41 return &g_factory.Get(); 42 } 43 44 // static 45 ExtensionCommandsGlobalRegistry* 46 ExtensionCommandsGlobalRegistry::Get(Profile* profile) { 47 return ProfileKeyedAPIFactory< 48 ExtensionCommandsGlobalRegistry>::GetForProfile(profile); 49 } 50 51 52 void ExtensionCommandsGlobalRegistry::AddExtensionKeybinding( 53 const extensions::Extension* extension, 54 const std::string& command_name) { 55 // This object only handles named commands, not browser/page actions. 56 if (ShouldIgnoreCommand(command_name)) 57 return; 58 59 extensions::CommandService* command_service = 60 extensions::CommandService::Get(profile_); 61 // Add all the active global keybindings, if any. 62 extensions::CommandMap commands; 63 if (!command_service->GetNamedCommands( 64 extension->id(), 65 extensions::CommandService::ACTIVE_ONLY, 66 extensions::CommandService::GLOBAL, 67 &commands)) 68 return; 69 70 extensions::CommandMap::const_iterator iter = commands.begin(); 71 for (; iter != commands.end(); ++iter) { 72 if (!command_name.empty() && (iter->second.command_name() != command_name)) 73 continue; 74 75 VLOG(0) << "Adding global keybinding for " << extension->name().c_str() 76 << " " << command_name.c_str() 77 << " key: " << iter->second.accelerator().GetShortcutText(); 78 79 event_targets_[iter->second.accelerator()].push_back( 80 std::make_pair(extension->id(), iter->second.command_name())); 81 // Shortcuts except media keys have only one target in the list. See comment 82 // about |event_targets_|. 83 if (!extensions::CommandService::IsMediaKey(iter->second.accelerator())) 84 DCHECK(event_targets_[iter->second.accelerator()].size() == 1); 85 86 GlobalShortcutListener::GetInstance()->RegisterAccelerator( 87 iter->second.accelerator(), this); 88 } 89 } 90 91 void ExtensionCommandsGlobalRegistry::RemoveExtensionKeybindingImpl( 92 const ui::Accelerator& accelerator, 93 const std::string& command_name) { 94 VLOG(0) << "Removing keybinding for " << command_name.c_str(); 95 96 GlobalShortcutListener::GetInstance()->UnregisterAccelerator( 97 accelerator, this); 98 } 99 100 void ExtensionCommandsGlobalRegistry::OnKeyPressed( 101 const ui::Accelerator& accelerator) { 102 ExtensionKeybindingRegistry::NotifyEventTargets(accelerator); 103 } 104 105 } // namespace extensions 106