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/extensions/api/commands/command_service.h" 9 #include "chrome/browser/extensions/global_shortcut_listener.h" 10 #include "extensions/common/extension.h" 11 12 namespace extensions { 13 14 ExtensionCommandsGlobalRegistry::ExtensionCommandsGlobalRegistry( 15 content::BrowserContext* context) 16 : ExtensionKeybindingRegistry(context, 17 ExtensionKeybindingRegistry::ALL_EXTENSIONS, 18 NULL), 19 browser_context_(context) { 20 Init(); 21 } 22 23 ExtensionCommandsGlobalRegistry::~ExtensionCommandsGlobalRegistry() { 24 if (!IsEventTargetsEmpty()) { 25 GlobalShortcutListener* global_shortcut_listener = 26 GlobalShortcutListener::GetInstance(); 27 28 // Resume GlobalShortcutListener before we clean up if the shortcut handling 29 // is currently suspended. 30 if (global_shortcut_listener->IsShortcutHandlingSuspended()) 31 global_shortcut_listener->SetShortcutHandlingSuspended(false); 32 33 global_shortcut_listener->UnregisterAccelerators(this); 34 } 35 } 36 37 static base::LazyInstance< 38 BrowserContextKeyedAPIFactory<ExtensionCommandsGlobalRegistry> > g_factory = 39 LAZY_INSTANCE_INITIALIZER; 40 41 // static 42 BrowserContextKeyedAPIFactory<ExtensionCommandsGlobalRegistry>* 43 ExtensionCommandsGlobalRegistry::GetFactoryInstance() { 44 return g_factory.Pointer(); 45 } 46 47 // static 48 ExtensionCommandsGlobalRegistry* ExtensionCommandsGlobalRegistry::Get( 49 content::BrowserContext* context) { 50 return BrowserContextKeyedAPIFactory<ExtensionCommandsGlobalRegistry>::Get( 51 context); 52 } 53 54 // static 55 void ExtensionCommandsGlobalRegistry::SetShortcutHandlingSuspended( 56 bool suspended) { 57 GlobalShortcutListener::GetInstance()->SetShortcutHandlingSuspended( 58 suspended); 59 } 60 61 void ExtensionCommandsGlobalRegistry::AddExtensionKeybinding( 62 const extensions::Extension* extension, 63 const std::string& command_name) { 64 // This object only handles named commands, not browser/page actions. 65 if (ShouldIgnoreCommand(command_name)) 66 return; 67 68 extensions::CommandService* command_service = 69 extensions::CommandService::Get(browser_context_); 70 // Add all the active global keybindings, if any. 71 extensions::CommandMap commands; 72 if (!command_service->GetNamedCommands( 73 extension->id(), 74 extensions::CommandService::ACTIVE_ONLY, 75 extensions::CommandService::GLOBAL, 76 &commands)) 77 return; 78 79 extensions::CommandMap::const_iterator iter = commands.begin(); 80 for (; iter != commands.end(); ++iter) { 81 if (!command_name.empty() && (iter->second.command_name() != command_name)) 82 continue; 83 const ui::Accelerator& accelerator = iter->second.accelerator(); 84 85 VLOG(0) << "Adding global keybinding for " << extension->name().c_str() 86 << " " << command_name.c_str() 87 << " key: " << accelerator.GetShortcutText(); 88 89 if (!IsAcceleratorRegistered(accelerator)) { 90 if (!GlobalShortcutListener::GetInstance()->RegisterAccelerator( 91 accelerator, this)) 92 continue; 93 } 94 95 AddEventTarget(accelerator, extension->id(), iter->second.command_name()); 96 } 97 } 98 99 void ExtensionCommandsGlobalRegistry::RemoveExtensionKeybindingImpl( 100 const ui::Accelerator& accelerator, 101 const std::string& command_name) { 102 VLOG(0) << "Removing keybinding for " << command_name.c_str(); 103 104 GlobalShortcutListener::GetInstance()->UnregisterAccelerator( 105 accelerator, this); 106 } 107 108 void ExtensionCommandsGlobalRegistry::OnKeyPressed( 109 const ui::Accelerator& accelerator) { 110 ExtensionKeybindingRegistry::NotifyEventTargets(accelerator); 111 } 112 113 } // namespace extensions 114