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/options/handler_options_handler.h" 6 7#include <vector> 8 9#include "base/bind.h" 10#include "base/bind_helpers.h" 11#include "base/prefs/pref_service.h" 12#include "base/strings/utf_string_conversions.h" 13#include "base/values.h" 14#include "chrome/browser/chrome_notification_types.h" 15#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" 16#include "chrome/browser/profiles/profile.h" 17#include "content/public/browser/web_ui.h" 18#include "grit/generated_resources.h" 19#include "ui/base/l10n/l10n_util.h" 20 21namespace options { 22 23HandlerOptionsHandler::HandlerOptionsHandler() { 24} 25 26HandlerOptionsHandler::~HandlerOptionsHandler() { 27} 28 29void HandlerOptionsHandler::GetLocalizedValues( 30 DictionaryValue* localized_strings) { 31 DCHECK(localized_strings); 32 33 static OptionsStringResource resources[] = { 34 { "handlers_tab_label", IDS_HANDLERS_TAB_LABEL }, 35 { "handlers_allow", IDS_HANDLERS_ALLOW_RADIO }, 36 { "handlers_block", IDS_HANDLERS_DONOTALLOW_RADIO }, 37 { "handlers_type_column_header", IDS_HANDLERS_TYPE_COLUMN_HEADER }, 38 { "handlers_site_column_header", IDS_HANDLERS_SITE_COLUMN_HEADER }, 39 { "handlers_remove_link", IDS_HANDLERS_REMOVE_HANDLER_LINK }, 40 { "handlers_none_handler", IDS_HANDLERS_NONE_HANDLER }, 41 { "handlers_active_heading", IDS_HANDLERS_ACTIVE_HEADING }, 42 { "handlers_ignored_heading", IDS_HANDLERS_IGNORED_HEADING }, 43 }; 44 RegisterTitle(localized_strings, "handlersPage", 45 IDS_HANDLER_OPTIONS_WINDOW_TITLE); 46 RegisterStrings(localized_strings, resources, arraysize(resources)); 47} 48 49void HandlerOptionsHandler::InitializeHandler() { 50 notification_registrar_.Add( 51 this, chrome::NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED, 52 content::Source<Profile>(Profile::FromWebUI(web_ui()))); 53} 54 55void HandlerOptionsHandler::InitializePage() { 56 UpdateHandlerList(); 57} 58 59void HandlerOptionsHandler::RegisterMessages() { 60 web_ui()->RegisterMessageCallback("clearDefault", 61 base::Bind(&HandlerOptionsHandler::ClearDefault, 62 base::Unretained(this))); 63 web_ui()->RegisterMessageCallback("removeHandler", 64 base::Bind(&HandlerOptionsHandler::RemoveHandler, 65 base::Unretained(this))); 66 web_ui()->RegisterMessageCallback("setHandlersEnabled", 67 base::Bind(&HandlerOptionsHandler::SetHandlersEnabled, 68 base::Unretained(this))); 69 web_ui()->RegisterMessageCallback("setDefault", 70 base::Bind(&HandlerOptionsHandler::SetDefault, 71 base::Unretained(this))); 72 web_ui()->RegisterMessageCallback("removeIgnoredHandler", 73 base::Bind(&HandlerOptionsHandler::RemoveIgnoredHandler, 74 base::Unretained(this))); 75} 76 77ProtocolHandlerRegistry* HandlerOptionsHandler::GetProtocolHandlerRegistry() { 78 return ProtocolHandlerRegistryFactory::GetForProfile( 79 Profile::FromWebUI(web_ui())); 80} 81 82static void GetHandlersAsListValue( 83 const ProtocolHandlerRegistry::ProtocolHandlerList& handlers, 84 ListValue* handler_list) { 85 ProtocolHandlerRegistry::ProtocolHandlerList::const_iterator handler; 86 for (handler = handlers.begin(); handler != handlers.end(); ++handler) { 87 ListValue* handlerValue = new ListValue(); 88 handlerValue->Append(new base::StringValue(handler->protocol())); 89 handlerValue->Append(new base::StringValue(handler->url().spec())); 90 handlerValue->Append(new base::StringValue(handler->title())); 91 handler_list->Append(handlerValue); 92 } 93} 94 95void HandlerOptionsHandler::GetHandlersForProtocol( 96 const std::string& protocol, 97 DictionaryValue* handlers_value) { 98 ProtocolHandlerRegistry* registry = GetProtocolHandlerRegistry(); 99 handlers_value->SetString("protocol", protocol); 100 handlers_value->SetInteger("default_handler", 101 registry->GetHandlerIndex(protocol)); 102 103 ListValue* handlers_list = new ListValue(); 104 GetHandlersAsListValue(registry->GetHandlersFor(protocol), handlers_list); 105 handlers_value->Set("handlers", handlers_list); 106} 107 108void HandlerOptionsHandler::GetIgnoredHandlers(ListValue* handlers) { 109 ProtocolHandlerRegistry* registry = GetProtocolHandlerRegistry(); 110 ProtocolHandlerRegistry::ProtocolHandlerList ignored_handlers = 111 registry->GetIgnoredHandlers(); 112 return GetHandlersAsListValue(ignored_handlers, handlers); 113} 114 115void HandlerOptionsHandler::UpdateHandlerList() { 116 ProtocolHandlerRegistry* registry = GetProtocolHandlerRegistry(); 117 std::vector<std::string> protocols; 118 registry->GetRegisteredProtocols(&protocols); 119 120 ListValue handlers; 121 for (std::vector<std::string>::iterator protocol = protocols.begin(); 122 protocol != protocols.end(); protocol++) { 123 DictionaryValue* handler_value = new DictionaryValue(); 124 GetHandlersForProtocol(*protocol, handler_value); 125 handlers.Append(handler_value); 126 } 127 128 scoped_ptr<ListValue> ignored_handlers(new ListValue()); 129 GetIgnoredHandlers(ignored_handlers.get()); 130 web_ui()->CallJavascriptFunction("HandlerOptions.setHandlers", handlers); 131 web_ui()->CallJavascriptFunction("HandlerOptions.setIgnoredHandlers", 132 *ignored_handlers); 133} 134 135void HandlerOptionsHandler::RemoveHandler(const ListValue* args) { 136 const ListValue* list; 137 if (!args->GetList(0, &list)) { 138 NOTREACHED(); 139 return; 140 } 141 142 ProtocolHandler handler(ParseHandlerFromArgs(list)); 143 GetProtocolHandlerRegistry()->RemoveHandler(handler); 144 145 // No need to call UpdateHandlerList() - we should receive a notification 146 // that the ProtocolHandlerRegistry has changed and we will update the view 147 // then. 148} 149 150void HandlerOptionsHandler::RemoveIgnoredHandler(const ListValue* args) { 151 const ListValue* list; 152 if (!args->GetList(0, &list)) { 153 NOTREACHED(); 154 return; 155 } 156 157 ProtocolHandler handler(ParseHandlerFromArgs(list)); 158 GetProtocolHandlerRegistry()->RemoveIgnoredHandler(handler); 159} 160 161void HandlerOptionsHandler::SetHandlersEnabled(const ListValue* args) { 162 bool enabled = true; 163 CHECK(args->GetBoolean(0, &enabled)); 164 if (enabled) 165 GetProtocolHandlerRegistry()->Enable(); 166 else 167 GetProtocolHandlerRegistry()->Disable(); 168} 169 170void HandlerOptionsHandler::ClearDefault(const ListValue* args) { 171 const Value* value; 172 CHECK(args->Get(0, &value)); 173 std::string protocol_to_clear; 174 CHECK(value->GetAsString(&protocol_to_clear)); 175 GetProtocolHandlerRegistry()->ClearDefault(protocol_to_clear); 176} 177 178void HandlerOptionsHandler::SetDefault(const ListValue* args) { 179 const ListValue* list; 180 CHECK(args->GetList(0, &list)); 181 const ProtocolHandler& handler(ParseHandlerFromArgs(list)); 182 CHECK(!handler.IsEmpty()); 183 GetProtocolHandlerRegistry()->OnAcceptRegisterProtocolHandler(handler); 184} 185 186ProtocolHandler HandlerOptionsHandler::ParseHandlerFromArgs( 187 const ListValue* args) const { 188 base::string16 protocol; 189 base::string16 url; 190 base::string16 title; 191 bool ok = args->GetString(0, &protocol) && args->GetString(1, &url) && 192 args->GetString(2, &title); 193 if (!ok) 194 return ProtocolHandler::EmptyProtocolHandler(); 195 return ProtocolHandler::CreateProtocolHandler(UTF16ToUTF8(protocol), 196 GURL(UTF16ToUTF8(url)), 197 title); 198} 199 200void HandlerOptionsHandler::Observe( 201 int type, 202 const content::NotificationSource& source, 203 const content::NotificationDetails& details) { 204 if (type == chrome::NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED) 205 UpdateHandlerList(); 206 else 207 NOTREACHED(); 208} 209 210} // namespace options 211