Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2012 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/ui/webui/extensions/command_handler.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/values.h"
      9 #include "chrome/browser/extensions/api/commands/command_service.h"
     10 #include "chrome/browser/extensions/extension_commands_global_registry.h"
     11 #include "chrome/browser/extensions/extension_keybinding_registry.h"
     12 #include "chrome/browser/profiles/profile.h"
     13 #include "chrome/grit/generated_resources.h"
     14 #include "content/public/browser/web_ui.h"
     15 #include "content/public/browser/web_ui_data_source.h"
     16 #include "extensions/browser/extension_registry.h"
     17 #include "extensions/browser/extension_system.h"
     18 #include "extensions/common/extension_set.h"
     19 #include "ui/base/l10n/l10n_util.h"
     20 
     21 namespace extensions {
     22 
     23 CommandHandler::CommandHandler(Profile* profile)
     24     : profile_(profile),
     25       extension_registry_observer_(this) {
     26 }
     27 
     28 CommandHandler::~CommandHandler() {
     29 }
     30 
     31 void CommandHandler::GetLocalizedValues(content::WebUIDataSource* source) {
     32   source->AddString("extensionCommandsOverlay",
     33       l10n_util::GetStringUTF16(IDS_EXTENSION_COMMANDS_DIALOG_TITLE));
     34   source->AddString("extensionCommandsEmpty",
     35       l10n_util::GetStringUTF16(IDS_EXTENSION_COMMANDS_EMPTY));
     36   source->AddString("extensionCommandsInactive",
     37       l10n_util::GetStringUTF16(IDS_EXTENSION_COMMANDS_INACTIVE));
     38   source->AddString("extensionCommandsStartTyping",
     39       l10n_util::GetStringUTF16(IDS_EXTENSION_TYPE_SHORTCUT));
     40   source->AddString("extensionCommandsDelete",
     41       l10n_util::GetStringUTF16(IDS_EXTENSION_DELETE_SHORTCUT));
     42   source->AddString("extensionCommandsGlobal",
     43       l10n_util::GetStringUTF16(IDS_EXTENSION_COMMANDS_GLOBAL));
     44   source->AddString("extensionCommandsRegular",
     45       l10n_util::GetStringUTF16(IDS_EXTENSION_COMMANDS_NOT_GLOBAL));
     46   source->AddString("ok", l10n_util::GetStringUTF16(IDS_OK));
     47 }
     48 
     49 void CommandHandler::RegisterMessages() {
     50   extension_registry_observer_.Add(ExtensionRegistry::Get(profile_));
     51 
     52   web_ui()->RegisterMessageCallback("extensionCommandsRequestExtensionsData",
     53       base::Bind(&CommandHandler::HandleRequestExtensionsData,
     54       base::Unretained(this)));
     55   web_ui()->RegisterMessageCallback("setShortcutHandlingSuspended",
     56       base::Bind(&CommandHandler::HandleSetShortcutHandlingSuspended,
     57       base::Unretained(this)));
     58   web_ui()->RegisterMessageCallback("setExtensionCommandShortcut",
     59       base::Bind(&CommandHandler::HandleSetExtensionCommandShortcut,
     60       base::Unretained(this)));
     61   web_ui()->RegisterMessageCallback("setCommandScope",
     62       base::Bind(&CommandHandler::HandleSetCommandScope,
     63       base::Unretained(this)));
     64 }
     65 
     66 void CommandHandler::OnExtensionLoaded(content::BrowserContext* browser_context,
     67                                        const Extension* extension) {
     68   UpdateCommandDataOnPage();
     69 }
     70 
     71 void CommandHandler::OnExtensionUnloaded(
     72     content::BrowserContext* browser_context,
     73     const Extension* extension,
     74     UnloadedExtensionInfo::Reason reason) {
     75   UpdateCommandDataOnPage();
     76 }
     77 
     78 void CommandHandler::UpdateCommandDataOnPage() {
     79   base::DictionaryValue results;
     80   GetAllCommands(&results);
     81   web_ui()->CallJavascriptFunction(
     82       "extensions.ExtensionCommandsOverlay.returnExtensionsData", results);
     83 }
     84 
     85 void CommandHandler::HandleRequestExtensionsData(const base::ListValue* args) {
     86   UpdateCommandDataOnPage();
     87 }
     88 
     89 void CommandHandler::HandleSetExtensionCommandShortcut(
     90     const base::ListValue* args) {
     91   std::string extension_id;
     92   std::string command_name;
     93   std::string keystroke;
     94   if (!args->GetString(0, &extension_id) ||
     95       !args->GetString(1, &command_name) ||
     96       !args->GetString(2, &keystroke)) {
     97     NOTREACHED();
     98     return;
     99   }
    100 
    101   Profile* profile = Profile::FromWebUI(web_ui());
    102   CommandService* command_service = CommandService::Get(profile);
    103   command_service->UpdateKeybindingPrefs(extension_id, command_name, keystroke);
    104 
    105   UpdateCommandDataOnPage();
    106 }
    107 
    108 void CommandHandler::HandleSetCommandScope(
    109     const base::ListValue* args) {
    110   std::string extension_id;
    111   std::string command_name;
    112   bool global;
    113   if (!args->GetString(0, &extension_id) ||
    114       !args->GetString(1, &command_name) ||
    115       !args->GetBoolean(2, &global)) {
    116     NOTREACHED();
    117     return;
    118   }
    119 
    120   Profile* profile = Profile::FromWebUI(web_ui());
    121   CommandService* command_service = CommandService::Get(profile);
    122   if (command_service->SetScope(extension_id, command_name, global))
    123     UpdateCommandDataOnPage();
    124 }
    125 
    126 void CommandHandler::HandleSetShortcutHandlingSuspended(
    127     const base::ListValue* args) {
    128   bool suspended;
    129   if (args->GetBoolean(0, &suspended)) {
    130     // Suspend/Resume normal shortcut handling.
    131     ExtensionKeybindingRegistry::SetShortcutHandlingSuspended(suspended);
    132 
    133     // Suspend/Resume global shortcut handling.
    134     ExtensionCommandsGlobalRegistry::SetShortcutHandlingSuspended(suspended);
    135   }
    136 }
    137 
    138 void CommandHandler::GetAllCommands(base::DictionaryValue* commands) {
    139   base::ListValue* results = new base::ListValue;
    140 
    141   Profile* profile = Profile::FromWebUI(web_ui());
    142   CommandService* command_service = CommandService::Get(profile);
    143 
    144   const ExtensionSet& extensions =
    145       ExtensionRegistry::Get(profile)->enabled_extensions();
    146   for (ExtensionSet::const_iterator extension = extensions.begin();
    147        extension != extensions.end();
    148        ++extension) {
    149     scoped_ptr<base::DictionaryValue> extension_dict(new base::DictionaryValue);
    150     extension_dict->SetString("name", (*extension)->name());
    151     extension_dict->SetString("id", (*extension)->id());
    152 
    153     // Add the keybindings to a list structure.
    154     scoped_ptr<base::ListValue> extensions_list(new base::ListValue());
    155 
    156     bool active = false;
    157 
    158     Command browser_action;
    159     if (command_service->GetBrowserActionCommand((*extension)->id(),
    160                                                  CommandService::ALL,
    161                                                  &browser_action,
    162                                                  &active)) {
    163       extensions_list->Append(
    164           browser_action.ToValue((extension->get()), active));
    165     }
    166 
    167     Command page_action;
    168     if (command_service->GetPageActionCommand((*extension)->id(),
    169                                               CommandService::ALL,
    170                                               &page_action,
    171                                               &active)) {
    172       extensions_list->Append(page_action.ToValue((extension->get()), active));
    173     }
    174 
    175     CommandMap named_commands;
    176     if (command_service->GetNamedCommands((*extension)->id(),
    177                                           CommandService::ALL,
    178                                           CommandService::ANY_SCOPE,
    179                                           &named_commands)) {
    180       for (CommandMap::const_iterator iter = named_commands.begin();
    181            iter != named_commands.end();
    182            ++iter) {
    183         Command command = command_service->FindCommandByName(
    184             (*extension)->id(), iter->second.command_name());
    185         ui::Accelerator shortcut_assigned = command.accelerator();
    186 
    187         active = (shortcut_assigned.key_code() != ui::VKEY_UNKNOWN);
    188 
    189         extensions_list->Append(
    190             iter->second.ToValue((extension->get()), active));
    191       }
    192     }
    193 
    194     if (!extensions_list->empty()) {
    195       extension_dict->Set("commands", extensions_list.release());
    196       results->Append(extension_dict.release());
    197     }
    198   }
    199 
    200   commands->Set("commands", results);
    201 }
    202 
    203 }  // namespace extensions
    204