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