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