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