• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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/core_options_handler.h"
6 
7 #include "base/json/json_reader.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/string16.h"
10 #include "base/string_number_conversions.h"
11 #include "base/utf_string_conversions.h"
12 #include "base/values.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/google/google_util.h"
15 #include "chrome/browser/metrics/user_metrics.h"
16 #include "chrome/browser/prefs/pref_service.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/common/pref_names.h"
19 #include "chrome/common/url_constants.h"
20 #include "content/common/notification_details.h"
21 #include "content/common/notification_type.h"
22 #include "googleurl/src/gurl.h"
23 #include "grit/chromium_strings.h"
24 #include "grit/generated_resources.h"
25 #include "grit/locale_settings.h"
26 #include "grit/theme_resources.h"
27 #include "ui/base/l10n/l10n_util.h"
28 
CoreOptionsHandler()29 CoreOptionsHandler::CoreOptionsHandler()
30     : handlers_host_(NULL) {
31 }
32 
~CoreOptionsHandler()33 CoreOptionsHandler::~CoreOptionsHandler() {}
34 
Initialize()35 void CoreOptionsHandler::Initialize() {
36   clear_plugin_lso_data_enabled_.Init(prefs::kClearPluginLSODataEnabled,
37                                       g_browser_process->local_state(),
38                                       this);
39   UpdateClearPluginLSOData();
40 }
41 
GetLocalizedValues(DictionaryValue * localized_strings)42 void CoreOptionsHandler::GetLocalizedValues(
43     DictionaryValue* localized_strings) {
44   DCHECK(localized_strings);
45   // Main
46   localized_strings->SetString("title",
47       l10n_util::GetStringUTF16(IDS_SETTINGS_TITLE));
48 
49   // Managed prefs
50   localized_strings->SetString("managedPrefsBannerText",
51       l10n_util::GetStringUTF16(IDS_OPTIONS_MANAGED_PREFS));
52 
53   // Search
54   RegisterTitle(localized_strings, "searchPage", IDS_OPTIONS_SEARCH_PAGE_TITLE);
55   localized_strings->SetString("searchPlaceholder",
56       l10n_util::GetStringUTF16(IDS_OPTIONS_SEARCH_PLACEHOLDER));
57   localized_strings->SetString("searchPageNoMatches",
58       l10n_util::GetStringUTF16(IDS_OPTIONS_SEARCH_PAGE_NO_MATCHES));
59   localized_strings->SetString("searchPageHelpLabel",
60       l10n_util::GetStringUTF16(IDS_OPTIONS_SEARCH_PAGE_HELP_LABEL));
61   localized_strings->SetString("searchPageHelpTitle",
62       l10n_util::GetStringFUTF16(IDS_OPTIONS_SEARCH_PAGE_HELP_TITLE,
63           l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
64   localized_strings->SetString("searchPageHelpURL",
65       google_util::AppendGoogleLocaleParam(
66           GURL(chrome::kChromeHelpURL)).spec());
67 
68   // Common
69   localized_strings->SetString("ok",
70       l10n_util::GetStringUTF16(IDS_OK));
71   localized_strings->SetString("cancel",
72       l10n_util::GetStringUTF16(IDS_CANCEL));
73   localized_strings->SetString("learnMore",
74       l10n_util::GetStringUTF16(IDS_LEARN_MORE));
75   localized_strings->SetString("close",
76       l10n_util::GetStringUTF16(IDS_CLOSE));
77 }
78 
Uninitialize()79 void CoreOptionsHandler::Uninitialize() {
80   std::string last_pref;
81   for (PreferenceCallbackMap::const_iterator iter = pref_callback_map_.begin();
82        iter != pref_callback_map_.end();
83        ++iter) {
84     if (last_pref != iter->first) {
85       StopObservingPref(iter->first);
86       last_pref = iter->first;
87     }
88   }
89 }
90 
Attach(WebUI * web_ui)91 WebUIMessageHandler* CoreOptionsHandler::Attach(WebUI* web_ui) {
92   WebUIMessageHandler* result = WebUIMessageHandler::Attach(web_ui);
93   DCHECK(web_ui_);
94   registrar_.Init(web_ui_->GetProfile()->GetPrefs());
95   return result;
96 }
97 
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)98 void CoreOptionsHandler::Observe(NotificationType type,
99                                  const NotificationSource& source,
100                                  const NotificationDetails& details) {
101   if (type == NotificationType::PREF_CHANGED)
102     NotifyPrefChanged(Details<std::string>(details).ptr());
103 }
104 
RegisterMessages()105 void CoreOptionsHandler::RegisterMessages() {
106   web_ui_->RegisterMessageCallback("coreOptionsInitialize",
107       NewCallback(this, &CoreOptionsHandler::HandleInitialize));
108   web_ui_->RegisterMessageCallback("fetchPrefs",
109       NewCallback(this, &CoreOptionsHandler::HandleFetchPrefs));
110   web_ui_->RegisterMessageCallback("observePrefs",
111       NewCallback(this, &CoreOptionsHandler::HandleObservePrefs));
112   web_ui_->RegisterMessageCallback("setBooleanPref",
113       NewCallback(this, &CoreOptionsHandler::HandleSetBooleanPref));
114   web_ui_->RegisterMessageCallback("setIntegerPref",
115       NewCallback(this, &CoreOptionsHandler::HandleSetIntegerPref));
116   web_ui_->RegisterMessageCallback("setDoublePref",
117       NewCallback(this, &CoreOptionsHandler::HandleSetDoublePref));
118   web_ui_->RegisterMessageCallback("setStringPref",
119       NewCallback(this, &CoreOptionsHandler::HandleSetStringPref));
120   web_ui_->RegisterMessageCallback("setListPref",
121       NewCallback(this, &CoreOptionsHandler::HandleSetListPref));
122   web_ui_->RegisterMessageCallback("clearPref",
123       NewCallback(this, &CoreOptionsHandler::HandleClearPref));
124   web_ui_->RegisterMessageCallback("coreOptionsUserMetricsAction",
125       NewCallback(this, &CoreOptionsHandler::HandleUserMetricsAction));
126 }
127 
HandleInitialize(const ListValue * args)128 void CoreOptionsHandler::HandleInitialize(const ListValue* args) {
129   DCHECK(handlers_host_);
130   handlers_host_->InitializeHandlers();
131 }
132 
FetchPref(const std::string & pref_name)133 Value* CoreOptionsHandler::FetchPref(const std::string& pref_name) {
134   PrefService* pref_service = web_ui_->GetProfile()->GetPrefs();
135 
136   const PrefService::Preference* pref =
137       pref_service->FindPreference(pref_name.c_str());
138 
139   Value* return_value;
140   if (pref) {
141     DictionaryValue* dict = new DictionaryValue;
142     dict->Set("value", pref->GetValue()->DeepCopy());
143     dict->SetBoolean("managed", pref->IsManaged());
144     return_value = dict;
145   } else {
146     return_value = Value::CreateNullValue();
147   }
148   return return_value;
149 }
150 
ObservePref(const std::string & pref_name)151 void CoreOptionsHandler::ObservePref(const std::string& pref_name) {
152   registrar_.Add(pref_name.c_str(), this);
153 }
154 
SetPref(const std::string & pref_name,const Value * value,const std::string & metric)155 void CoreOptionsHandler::SetPref(const std::string& pref_name,
156                                  const Value* value,
157                                  const std::string& metric) {
158   PrefService* pref_service = web_ui_->GetProfile()->GetPrefs();
159 
160   switch (value->GetType()) {
161     case Value::TYPE_BOOLEAN:
162     case Value::TYPE_INTEGER:
163     case Value::TYPE_DOUBLE:
164     case Value::TYPE_STRING:
165       pref_service->Set(pref_name.c_str(), *value);
166       break;
167 
168     default:
169       NOTREACHED();
170       return;
171   }
172 
173   pref_service->ScheduleSavePersistentPrefs();
174   ProcessUserMetric(value, metric);
175 }
176 
ClearPref(const std::string & pref_name,const std::string & metric)177 void CoreOptionsHandler::ClearPref(const std::string& pref_name,
178                                    const std::string& metric) {
179   PrefService* pref_service = web_ui_->GetProfile()->GetPrefs();
180   pref_service->ClearPref(pref_name.c_str());
181   pref_service->ScheduleSavePersistentPrefs();
182 
183   if (!metric.empty())
184     UserMetricsRecordAction(UserMetricsAction(metric.c_str()));
185 }
186 
ProcessUserMetric(const Value * value,const std::string & metric)187 void CoreOptionsHandler::ProcessUserMetric(const Value* value,
188                                            const std::string& metric) {
189   if (metric.empty())
190     return;
191 
192   std::string metric_string = metric;
193   if (value->IsType(Value::TYPE_BOOLEAN)) {
194     bool bool_value;
195     CHECK(value->GetAsBoolean(&bool_value));
196     metric_string += bool_value ? "_Enable" : "_Disable";
197   }
198 
199   UserMetricsRecordAction(UserMetricsAction(metric_string.c_str()));
200 }
201 
StopObservingPref(const std::string & path)202 void CoreOptionsHandler::StopObservingPref(const std::string& path) {
203   registrar_.Remove(path.c_str(), this);
204 }
205 
HandleFetchPrefs(const ListValue * args)206 void CoreOptionsHandler::HandleFetchPrefs(const ListValue* args) {
207   // First param is name of callback function, so, there needs to be at least
208   // one more element for the actual preference identifier.
209   DCHECK_GE(static_cast<int>(args->GetSize()), 2);
210 
211   // Get callback JS function name.
212   Value* callback;
213   if (!args->Get(0, &callback) || !callback->IsType(Value::TYPE_STRING))
214     return;
215 
216   string16 callback_function;
217   if (!callback->GetAsString(&callback_function))
218     return;
219 
220   // Get the list of name for prefs to build the response dictionary.
221   DictionaryValue result_value;
222   Value* list_member;
223 
224   for (size_t i = 1; i < args->GetSize(); i++) {
225     if (!args->Get(i, &list_member))
226       break;
227 
228     if (!list_member->IsType(Value::TYPE_STRING))
229       continue;
230 
231     std::string pref_name;
232     if (!list_member->GetAsString(&pref_name))
233       continue;
234 
235     result_value.Set(pref_name.c_str(), FetchPref(pref_name));
236   }
237   web_ui_->CallJavascriptFunction(UTF16ToASCII(callback_function),
238                                   result_value);
239 }
240 
HandleObservePrefs(const ListValue * args)241 void CoreOptionsHandler::HandleObservePrefs(const ListValue* args) {
242   // First param is name is JS callback function name, the rest are pref
243   // identifiers that we are observing.
244   DCHECK_GE(static_cast<int>(args->GetSize()), 2);
245 
246   // Get preference change callback function name.
247   string16 callback_func_name;
248   if (!args->GetString(0, &callback_func_name))
249     return;
250 
251   // Get all other parameters - pref identifiers.
252   for (size_t i = 1; i < args->GetSize(); i++) {
253     Value* list_member;
254     if (!args->Get(i, &list_member))
255       break;
256 
257     // Just ignore bad pref identifiers for now.
258     std::string pref_name;
259     if (!list_member->IsType(Value::TYPE_STRING) ||
260         !list_member->GetAsString(&pref_name))
261       continue;
262 
263     if (pref_callback_map_.find(pref_name) == pref_callback_map_.end())
264       ObservePref(pref_name);
265 
266     pref_callback_map_.insert(
267         PreferenceCallbackMap::value_type(pref_name,
268                                           UTF16ToWideHack(callback_func_name)));
269   }
270 }
271 
HandleSetBooleanPref(const ListValue * args)272 void CoreOptionsHandler::HandleSetBooleanPref(const ListValue* args) {
273   HandleSetPref(args, Value::TYPE_BOOLEAN);
274 }
275 
HandleSetIntegerPref(const ListValue * args)276 void CoreOptionsHandler::HandleSetIntegerPref(const ListValue* args) {
277   HandleSetPref(args, Value::TYPE_INTEGER);
278 }
279 
HandleSetDoublePref(const ListValue * args)280 void CoreOptionsHandler::HandleSetDoublePref(const ListValue* args) {
281   HandleSetPref(args, Value::TYPE_DOUBLE);
282 }
283 
HandleSetStringPref(const ListValue * args)284 void CoreOptionsHandler::HandleSetStringPref(const ListValue* args) {
285   HandleSetPref(args, Value::TYPE_STRING);
286 }
287 
HandleSetListPref(const ListValue * args)288 void CoreOptionsHandler::HandleSetListPref(const ListValue* args) {
289   HandleSetPref(args, Value::TYPE_LIST);
290 }
291 
HandleSetPref(const ListValue * args,Value::ValueType type)292 void CoreOptionsHandler::HandleSetPref(const ListValue* args,
293                                        Value::ValueType type) {
294   DCHECK_GT(static_cast<int>(args->GetSize()), 1);
295 
296   std::string pref_name;
297   if (!args->GetString(0, &pref_name))
298     return;
299 
300   Value* value;
301   if (!args->Get(1, &value))
302     return;
303 
304   scoped_ptr<Value> temp_value;
305 
306   // In JS all numbers are doubles.
307   if (type == Value::TYPE_INTEGER) {
308     double double_value;
309     CHECK(value->GetAsDouble(&double_value));
310     temp_value.reset(Value::CreateIntegerValue(static_cast<int>(double_value)));
311     value = temp_value.get();
312 
313   // In case we have a List pref we got a JSON string.
314   } else if (type == Value::TYPE_LIST) {
315     std::string json_string;
316     CHECK(value->GetAsString(&json_string));
317     temp_value.reset(
318         base::JSONReader().JsonToValue(json_string,
319                                        false,  // no check_root
320                                        false));  // no trailing comma
321     value = temp_value.get();
322   }
323 
324   CHECK_EQ(type, value->GetType());
325 
326   std::string metric;
327   if (args->GetSize() > 2)
328     args->GetString(2, &metric);
329 
330   SetPref(pref_name, value, metric);
331 }
332 
HandleClearPref(const ListValue * args)333 void CoreOptionsHandler::HandleClearPref(const ListValue* args) {
334   DCHECK_GT(static_cast<int>(args->GetSize()), 0);
335 
336   std::string pref_name;
337   if (!args->GetString(0, &pref_name))
338     return;
339 
340   std::string metric;
341   if (args->GetSize() > 1)
342     args->GetString(1, &metric);
343 
344   ClearPref(pref_name, metric);
345 }
346 
HandleUserMetricsAction(const ListValue * args)347 void CoreOptionsHandler::HandleUserMetricsAction(const ListValue* args) {
348   std::string metric = UTF16ToUTF8(ExtractStringValue(args));
349   if (!metric.empty())
350     UserMetricsRecordAction(UserMetricsAction(metric.c_str()));
351 }
352 
UpdateClearPluginLSOData()353 void CoreOptionsHandler::UpdateClearPluginLSOData() {
354   scoped_ptr<Value> enabled(
355       Value::CreateBooleanValue(clear_plugin_lso_data_enabled_.GetValue()));
356   web_ui_->CallJavascriptFunction(
357       "OptionsPage.setClearPluginLSODataEnabled", *enabled);
358 }
359 
NotifyPrefChanged(const std::string * pref_name)360 void CoreOptionsHandler::NotifyPrefChanged(const std::string* pref_name) {
361   if (*pref_name == prefs::kClearPluginLSODataEnabled) {
362     // This preference is stored in Local State, not in the user preferences.
363     UpdateClearPluginLSOData();
364     return;
365   }
366 
367   PrefService* pref_service = web_ui_->GetProfile()->GetPrefs();
368   const PrefService::Preference* pref =
369       pref_service->FindPreference(pref_name->c_str());
370   if (pref) {
371     for (PreferenceCallbackMap::const_iterator iter =
372         pref_callback_map_.find(*pref_name);
373         iter != pref_callback_map_.end(); ++iter) {
374       const std::wstring& callback_function = iter->second;
375       ListValue result_value;
376       result_value.Append(Value::CreateStringValue(pref_name->c_str()));
377 
378       DictionaryValue* dict = new DictionaryValue;
379       dict->Set("value", pref->GetValue()->DeepCopy());
380       dict->SetBoolean("managed", pref->IsManaged());
381       result_value.Append(dict);
382 
383       web_ui_->CallJavascriptFunction(WideToASCII(callback_function),
384                                       result_value);
385     }
386   }
387 }
388