195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley// Copyright (c) 2012 The Chromium Authors. All rights reserved. 295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley// Use of this source code is governed by a BSD-style license that can be 395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley// found in the LICENSE file. 495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "chrome/browser/ui/webui/extensions/command_handler.h" 695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "base/bind.h" 895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "base/values.h" 995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "chrome/browser/extensions/api/commands/command_service.h" 1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "chrome/browser/extensions/extension_commands_global_registry.h" 1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "chrome/browser/extensions/extension_keybinding_registry.h" 1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "chrome/browser/profiles/profile.h" 1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "chrome/grit/generated_resources.h" 1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "content/public/browser/web_ui.h" 1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "content/public/browser/web_ui_data_source.h" 1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "extensions/browser/extension_registry.h" 1795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "extensions/browser/extension_system.h" 1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "extensions/common/extension_set.h" 1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "ui/base/l10n/l10n_util.h" 2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleynamespace extensions { 2295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 2395c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyCommandHandler::CommandHandler(Profile* profile) 2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley : profile_(profile), 2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley extension_registry_observer_(this) { 2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 2895c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyCommandHandler::~CommandHandler() { 2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid CommandHandler::GetLocalizedValues(content::WebUIDataSource* source) { 3295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley source->AddString("extensionCommandsOverlay", 3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley l10n_util::GetStringUTF16(IDS_EXTENSION_COMMANDS_DIALOG_TITLE)); 3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley source->AddString("extensionCommandsEmpty", 3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley l10n_util::GetStringUTF16(IDS_EXTENSION_COMMANDS_EMPTY)); 3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley source->AddString("extensionCommandsInactive", 3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley l10n_util::GetStringUTF16(IDS_EXTENSION_COMMANDS_INACTIVE)); 3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley source->AddString("extensionCommandsStartTyping", 3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley l10n_util::GetStringUTF16(IDS_EXTENSION_TYPE_SHORTCUT)); 4095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley source->AddString("extensionCommandsDelete", 4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley l10n_util::GetStringUTF16(IDS_EXTENSION_DELETE_SHORTCUT)); 4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley source->AddString("extensionCommandsGlobal", 4395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley l10n_util::GetStringUTF16(IDS_EXTENSION_COMMANDS_GLOBAL)); 4495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley source->AddString("extensionCommandsRegular", 4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley l10n_util::GetStringUTF16(IDS_EXTENSION_COMMANDS_NOT_GLOBAL)); 4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley source->AddString("ok", l10n_util::GetStringUTF16(IDS_OK)); 4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 4995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid CommandHandler::RegisterMessages() { 5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley extension_registry_observer_.Add(ExtensionRegistry::Get(profile_)); 5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley web_ui()->RegisterMessageCallback("extensionCommandsRequestExtensionsData", 5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::Bind(&CommandHandler::HandleRequestExtensionsData, 5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::Unretained(this))); 5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley web_ui()->RegisterMessageCallback("setShortcutHandlingSuspended", 5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::Bind(&CommandHandler::HandleSetShortcutHandlingSuspended, 5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::Unretained(this))); 5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley web_ui()->RegisterMessageCallback("setExtensionCommandShortcut", 5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::Bind(&CommandHandler::HandleSetExtensionCommandShortcut, 6095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::Unretained(this))); 6195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley web_ui()->RegisterMessageCallback("setCommandScope", 6295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::Bind(&CommandHandler::HandleSetCommandScope, 6395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::Unretained(this))); 6495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 6595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid CommandHandler::OnExtensionLoaded(content::BrowserContext* browser_context, 6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const Extension* extension) { 6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley UpdateCommandDataOnPage(); 6995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid CommandHandler::OnExtensionUnloaded( 7295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley content::BrowserContext* browser_context, 7395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const Extension* extension, 7495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley UnloadedExtensionInfo::Reason reason) { 7595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley UpdateCommandDataOnPage(); 7695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 7795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid CommandHandler::UpdateCommandDataOnPage() { 7995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::DictionaryValue results; 8095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley GetAllCommands(&results); 8195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley web_ui()->CallJavascriptFunction( 8295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley "extensions.ExtensionCommandsOverlay.returnExtensionsData", results); 8395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 8495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid CommandHandler::HandleRequestExtensionsData(const base::ListValue* args) { 8695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley UpdateCommandDataOnPage(); 8795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 8895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid CommandHandler::HandleSetExtensionCommandShortcut( 9095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const base::ListValue* args) { 9195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley std::string extension_id; 9295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley std::string command_name; 9395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley std::string keystroke; 9495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!args->GetString(0, &extension_id) || 9595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley !args->GetString(1, &command_name) || 9695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley !args->GetString(2, &keystroke)) { 9795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley NOTREACHED(); 9895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return; 9995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 10095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 10195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley Profile* profile = Profile::FromWebUI(web_ui()); 10295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CommandService* command_service = CommandService::Get(profile); 10395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley command_service->UpdateKeybindingPrefs(extension_id, command_name, keystroke); 10495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 10595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley UpdateCommandDataOnPage(); 10695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 10795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 10895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid CommandHandler::HandleSetCommandScope( 10995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const base::ListValue* args) { 11095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley std::string extension_id; 11195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley std::string command_name; 11295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley bool global; 11395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!args->GetString(0, &extension_id) || 11495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley !args->GetString(1, &command_name) || 11595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley !args->GetBoolean(2, &global)) { 11695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley NOTREACHED(); 11795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return; 11895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 11995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley Profile* profile = Profile::FromWebUI(web_ui()); 12195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CommandService* command_service = CommandService::Get(profile); 12295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (command_service->SetScope(extension_id, command_name, global)) 12395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley UpdateCommandDataOnPage(); 12495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 12595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid CommandHandler::HandleSetShortcutHandlingSuspended( 12795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const base::ListValue* args) { 12895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley bool suspended; 12995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (args->GetBoolean(0, &suspended)) { 13095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley // Suspend/Resume normal shortcut handling. 13195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ExtensionKeybindingRegistry::SetShortcutHandlingSuspended(suspended); 13295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley // Suspend/Resume global shortcut handling. 13495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ExtensionCommandsGlobalRegistry::SetShortcutHandlingSuspended(suspended); 13595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 13695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 13795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid CommandHandler::GetAllCommands(base::DictionaryValue* commands) { 13995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::ListValue* results = new base::ListValue; 14095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 14195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley Profile* profile = Profile::FromWebUI(web_ui()); 14295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CommandService* command_service = CommandService::Get(profile); 14395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 14495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ExtensionSet& extensions = 14595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ExtensionRegistry::Get(profile)->enabled_extensions(); 14695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (ExtensionSet::const_iterator extension = extensions.begin(); 14795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley extension != extensions.end(); 14895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ++extension) { 14995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley scoped_ptr<base::DictionaryValue> extension_dict(new base::DictionaryValue); 15095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley extension_dict->SetString("name", (*extension)->name()); 15195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley extension_dict->SetString("id", (*extension)->id()); 15295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 15395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley // Add the keybindings to a list structure. 15495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley scoped_ptr<base::ListValue> extensions_list(new base::ListValue()); 15595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 15695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley bool active = false; 15795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 15895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley Command browser_action; 15995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (command_service->GetBrowserActionCommand((*extension)->id(), 16095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CommandService::ALL, 16195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley &browser_action, 16295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley &active)) { 16395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley extensions_list->Append( 16495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley browser_action.ToValue((extension->get()), active)); 16595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 16695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 16795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley Command page_action; 16895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (command_service->GetPageActionCommand((*extension)->id(), 16995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CommandService::ALL, 17095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley &page_action, 17195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley &active)) { 17295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley extensions_list->Append(page_action.ToValue((extension->get()), active)); 17395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 17495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 17595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CommandMap named_commands; 17695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (command_service->GetNamedCommands((*extension)->id(), 17795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CommandService::ALL, 17895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CommandService::ANY_SCOPE, 17995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley &named_commands)) { 180d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley for (CommandMap::const_iterator iter = named_commands.begin(); 181d493d5289dd834b65232899c2cd8fe83baddfd44Adam Langley iter != named_commands.end(); 18295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ++iter) { 18395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley Command command = command_service->FindCommandByName( 18495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley (*extension)->id(), iter->second.command_name()); 18595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ui::Accelerator shortcut_assigned = command.accelerator(); 18695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 18795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley active = (shortcut_assigned.key_code() != ui::VKEY_UNKNOWN); 18895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 18995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley extensions_list->Append( 19095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley iter->second.ToValue((extension->get()), active)); 19195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 19295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 19395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 19495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!extensions_list->empty()) { 19595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley extension_dict->Set("commands", extensions_list.release()); 19695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley results->Append(extension_dict.release()); 19795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 19895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 19995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 20095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley commands->Set("commands", results); 20195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 20295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 20395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} // namespace extensions 20495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley