handler_options_handler.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1762bb9d0ad20320b9f97a841dce57ba5e8e48b07Richard Smith// Copyright (c) 2012 The Chromium Authors. All rights reserved.
28e8fb3be5bd78f0564444eca02b404566a5f3b5dAndy Gibbs// Use of this source code is governed by a BSD-style license that can be
3b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor// found in the LICENSE file.
4b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor
5b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor#include "chrome/browser/ui/webui/options/handler_options_handler.h"
6b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor
7b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor#include <vector>
8b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor
9b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor#include "base/bind.h"
10b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor#include "base/bind_helpers.h"
11b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor#include "base/prefs/pref_service.h"
12b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor#include "base/utf_string_conversions.h"
13b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor#include "base/values.h"
14b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor#include "chrome/browser/profiles/profile.h"
15b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor#include "chrome/common/chrome_notification_types.h"
16b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor#include "content/public/browser/web_ui.h"
17b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor#include "grit/generated_resources.h"
18b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor#include "ui/base/l10n/l10n_util.h"
1948a4ce7d484a448490edfe9e1d47b806cee85f30Douglas Gregor
20b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregornamespace options {
21b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor
22b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas GregorHandlerOptionsHandler::HandlerOptionsHandler() {
23b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor}
24b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor
25b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas GregorHandlerOptionsHandler::~HandlerOptionsHandler() {
26b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor}
27b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor
28b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregorvoid HandlerOptionsHandler::GetLocalizedValues(
29b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor    DictionaryValue* localized_strings) {
30b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor  DCHECK(localized_strings);
31b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor
32b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor  static OptionsStringResource resources[] = {
33b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor      { "handlers_tab_label", IDS_HANDLERS_TAB_LABEL },
34b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor      { "handlers_allow", IDS_HANDLERS_ALLOW_RADIO },
35b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor      { "handlers_block", IDS_HANDLERS_DONOTALLOW_RADIO },
36b13ede9f440f52ccfce046f1eba98679e9ffc0e6Douglas Gregor      { "handlers_type_column_header", IDS_HANDLERS_TYPE_COLUMN_HEADER },
3748a4ce7d484a448490edfe9e1d47b806cee85f30Douglas Gregor      { "handlers_site_column_header", IDS_HANDLERS_SITE_COLUMN_HEADER },
3848a4ce7d484a448490edfe9e1d47b806cee85f30Douglas Gregor      { "handlers_remove_link", IDS_HANDLERS_REMOVE_HANDLER_LINK },
3948a4ce7d484a448490edfe9e1d47b806cee85f30Douglas Gregor      { "handlers_none_handler", IDS_HANDLERS_NONE_HANDLER },
4048a4ce7d484a448490edfe9e1d47b806cee85f30Douglas Gregor      { "handlers_active_heading", IDS_HANDLERS_ACTIVE_HEADING },
4148a4ce7d484a448490edfe9e1d47b806cee85f30Douglas Gregor      { "handlers_ignored_heading", IDS_HANDLERS_IGNORED_HEADING },
4248a4ce7d484a448490edfe9e1d47b806cee85f30Douglas Gregor  };
4348a4ce7d484a448490edfe9e1d47b806cee85f30Douglas Gregor#if defined(ENABLE_SETTINGS_APP)
4448a4ce7d484a448490edfe9e1d47b806cee85f30Douglas Gregor  static OptionsStringResource app_resources[] = {
4548a4ce7d484a448490edfe9e1d47b806cee85f30Douglas Gregor    { "handlers_allow", IDS_SETTINGS_APP_HANDLERS_ALLOW_RADIO },
4648a4ce7d484a448490edfe9e1d47b806cee85f30Douglas Gregor    { "handlers_block", IDS_SETTINGS_APP_HANDLERS_DONOTALLOW_RADIO },
4748a4ce7d484a448490edfe9e1d47b806cee85f30Douglas Gregor  };
4848a4ce7d484a448490edfe9e1d47b806cee85f30Douglas Gregor  DictionaryValue* app_values = NULL;
4948a4ce7d484a448490edfe9e1d47b806cee85f30Douglas Gregor  CHECK(localized_strings->GetDictionary(kSettingsAppKey, &app_values));
5048a4ce7d484a448490edfe9e1d47b806cee85f30Douglas Gregor  RegisterStrings(app_values, app_resources, arraysize(app_resources));
5148a4ce7d484a448490edfe9e1d47b806cee85f30Douglas Gregor#endif
5248a4ce7d484a448490edfe9e1d47b806cee85f30Douglas Gregor  RegisterTitle(localized_strings, "handlersPage",
5348a4ce7d484a448490edfe9e1d47b806cee85f30Douglas Gregor                IDS_HANDLER_OPTIONS_WINDOW_TITLE);
54440a48318c53647d6416bcb1ff1af1452aa5d453Douglas Gregor  RegisterStrings(localized_strings, resources, arraysize(resources));
55440a48318c53647d6416bcb1ff1af1452aa5d453Douglas Gregor}
5648a4ce7d484a448490edfe9e1d47b806cee85f30Douglas Gregor
5748a4ce7d484a448490edfe9e1d47b806cee85f30Douglas Gregorvoid HandlerOptionsHandler::InitializeHandler() {
58440a48318c53647d6416bcb1ff1af1452aa5d453Douglas Gregor  notification_registrar_.Add(
5948a4ce7d484a448490edfe9e1d47b806cee85f30Douglas Gregor      this, chrome::NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED,
6048a4ce7d484a448490edfe9e1d47b806cee85f30Douglas Gregor      content::Source<Profile>(Profile::FromWebUI(web_ui())));
61}
62
63void HandlerOptionsHandler::InitializePage() {
64  UpdateHandlerList();
65}
66
67void HandlerOptionsHandler::RegisterMessages() {
68  web_ui()->RegisterMessageCallback("clearDefault",
69      base::Bind(&HandlerOptionsHandler::ClearDefault,
70                 base::Unretained(this)));
71  web_ui()->RegisterMessageCallback("removeHandler",
72      base::Bind(&HandlerOptionsHandler::RemoveHandler,
73                 base::Unretained(this)));
74  web_ui()->RegisterMessageCallback("setHandlersEnabled",
75      base::Bind(&HandlerOptionsHandler::SetHandlersEnabled,
76                 base::Unretained(this)));
77  web_ui()->RegisterMessageCallback("setDefault",
78      base::Bind(&HandlerOptionsHandler::SetDefault,
79                 base::Unretained(this)));
80  web_ui()->RegisterMessageCallback("removeIgnoredHandler",
81      base::Bind(&HandlerOptionsHandler::RemoveIgnoredHandler,
82                 base::Unretained(this)));
83}
84
85ProtocolHandlerRegistry* HandlerOptionsHandler::GetProtocolHandlerRegistry() {
86  return Profile::FromWebUI(web_ui())->GetProtocolHandlerRegistry();
87}
88
89static void GetHandlersAsListValue(
90    const ProtocolHandlerRegistry::ProtocolHandlerList& handlers,
91    ListValue* handler_list) {
92  ProtocolHandlerRegistry::ProtocolHandlerList::const_iterator handler;
93  for (handler = handlers.begin(); handler != handlers.end(); ++handler) {
94    ListValue* handlerValue = new ListValue();
95    handlerValue->Append(new base::StringValue(handler->protocol()));
96    handlerValue->Append(new base::StringValue(handler->url().spec()));
97    handlerValue->Append(new base::StringValue(handler->title()));
98    handler_list->Append(handlerValue);
99  }
100}
101
102void HandlerOptionsHandler::GetHandlersForProtocol(
103    const std::string& protocol,
104    DictionaryValue* handlers_value) {
105  ProtocolHandlerRegistry* registry = GetProtocolHandlerRegistry();
106  handlers_value->SetString("protocol", protocol);
107  handlers_value->SetInteger("default_handler",
108      registry->GetHandlerIndex(protocol));
109
110  ListValue* handlers_list = new ListValue();
111  GetHandlersAsListValue(registry->GetHandlersFor(protocol), handlers_list);
112  handlers_value->Set("handlers", handlers_list);
113}
114
115void HandlerOptionsHandler::GetIgnoredHandlers(ListValue* handlers) {
116  ProtocolHandlerRegistry* registry = GetProtocolHandlerRegistry();
117  ProtocolHandlerRegistry::ProtocolHandlerList ignored_handlers =
118      registry->GetIgnoredHandlers();
119  return GetHandlersAsListValue(ignored_handlers, handlers);
120}
121
122void HandlerOptionsHandler::UpdateHandlerList() {
123  ProtocolHandlerRegistry* registry = GetProtocolHandlerRegistry();
124  std::vector<std::string> protocols;
125  registry->GetRegisteredProtocols(&protocols);
126
127  ListValue handlers;
128  for (std::vector<std::string>::iterator protocol = protocols.begin();
129       protocol != protocols.end(); protocol++) {
130    DictionaryValue* handler_value = new DictionaryValue();
131    GetHandlersForProtocol(*protocol, handler_value);
132    handlers.Append(handler_value);
133  }
134
135  scoped_ptr<ListValue> ignored_handlers(new ListValue());
136  GetIgnoredHandlers(ignored_handlers.get());
137  web_ui()->CallJavascriptFunction("HandlerOptions.setHandlers", handlers);
138  web_ui()->CallJavascriptFunction("HandlerOptions.setIgnoredHandlers",
139                                   *ignored_handlers);
140}
141
142void HandlerOptionsHandler::RemoveHandler(const ListValue* args) {
143  const ListValue* list;
144  if (!args->GetList(0, &list)) {
145    NOTREACHED();
146    return;
147  }
148
149  ProtocolHandler handler(ParseHandlerFromArgs(list));
150  GetProtocolHandlerRegistry()->RemoveHandler(handler);
151
152  // No need to call UpdateHandlerList() - we should receive a notification
153  // that the ProtocolHandlerRegistry has changed and we will update the view
154  // then.
155}
156
157void HandlerOptionsHandler::RemoveIgnoredHandler(const ListValue* args) {
158  const ListValue* list;
159  if (!args->GetList(0, &list)) {
160    NOTREACHED();
161    return;
162  }
163
164  ProtocolHandler handler(ParseHandlerFromArgs(list));
165  GetProtocolHandlerRegistry()->RemoveIgnoredHandler(handler);
166}
167
168void HandlerOptionsHandler::SetHandlersEnabled(const ListValue* args) {
169  bool enabled = true;
170  CHECK(args->GetBoolean(0, &enabled));
171  if (enabled)
172    GetProtocolHandlerRegistry()->Enable();
173  else
174    GetProtocolHandlerRegistry()->Disable();
175}
176
177void HandlerOptionsHandler::ClearDefault(const ListValue* args) {
178  const Value* value;
179  CHECK(args->Get(0, &value));
180  std::string protocol_to_clear;
181  CHECK(value->GetAsString(&protocol_to_clear));
182  GetProtocolHandlerRegistry()->ClearDefault(protocol_to_clear);
183}
184
185void HandlerOptionsHandler::SetDefault(const ListValue* args) {
186  const ListValue* list;
187  CHECK(args->GetList(0, &list));
188  const ProtocolHandler& handler(ParseHandlerFromArgs(list));
189  CHECK(!handler.IsEmpty());
190  GetProtocolHandlerRegistry()->OnAcceptRegisterProtocolHandler(handler);
191}
192
193ProtocolHandler HandlerOptionsHandler::ParseHandlerFromArgs(
194    const ListValue* args) const {
195  string16 protocol;
196  string16 url;
197  string16 title;
198  bool ok = args->GetString(0, &protocol) && args->GetString(1, &url) &&
199    args->GetString(2, &title);
200  if (!ok)
201    return ProtocolHandler::EmptyProtocolHandler();
202  return ProtocolHandler::CreateProtocolHandler(UTF16ToUTF8(protocol),
203                                                GURL(UTF16ToUTF8(url)),
204                                                title);
205}
206
207void HandlerOptionsHandler::Observe(
208    int type,
209    const content::NotificationSource& source,
210    const content::NotificationDetails& details) {
211  if (type == chrome::NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED)
212    UpdateHandlerList();
213  else
214    NOTREACHED();
215}
216
217}  // namespace options
218