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