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/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