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