core_options_handler.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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/core_options_handler.h"
6
7#include "base/bind.h"
8#include "base/bind_helpers.h"
9#include "base/json/json_reader.h"
10#include "base/memory/scoped_ptr.h"
11#include "base/strings/string16.h"
12#include "base/strings/string_number_conversions.h"
13#include "base/strings/utf_string_conversions.h"
14#include "base/values.h"
15#include "chrome/browser/browser_process.h"
16#include "chrome/browser/chrome_notification_types.h"
17#include "chrome/browser/extensions/extension_service.h"
18#include "chrome/browser/profiles/profile.h"
19#include "chrome/browser/ui/options/options_util.h"
20#include "chrome/common/net/url_fixer_upper.h"
21#include "chrome/common/pref_names.h"
22#include "chrome/common/url_constants.h"
23#include "content/public/browser/notification_details.h"
24#include "content/public/browser/notification_types.h"
25#include "content/public/browser/user_metrics.h"
26#include "content/public/browser/web_ui.h"
27#include "extensions/browser/extension_pref_value_map.h"
28#include "extensions/browser/extension_pref_value_map_factory.h"
29#include "extensions/browser/extension_system.h"
30#include "extensions/common/extension.h"
31#include "grit/chromium_strings.h"
32#include "grit/generated_resources.h"
33#include "grit/locale_settings.h"
34#include "grit/theme_resources.h"
35#include "ui/base/l10n/l10n_util.h"
36#include "url/gurl.h"
37
38using base::UserMetricsAction;
39
40namespace options {
41
42namespace {
43
44// Only allow changes to the metrics reporting checkbox if we were succesfully
45// able to change the service.
46bool AllowMetricsReportingChange(const base::Value* to_value) {
47  bool enable;
48  if (!to_value->GetAsBoolean(&enable)) {
49    NOTREACHED();
50    return false;
51  }
52
53  return enable == OptionsUtil::ResolveMetricsReportingEnabled(enable);
54}
55
56}  // namespace
57
58CoreOptionsHandler::CoreOptionsHandler()
59    : handlers_host_(NULL) {
60}
61
62CoreOptionsHandler::~CoreOptionsHandler() {}
63
64void CoreOptionsHandler::InitializeHandler() {
65  Profile* profile = Profile::FromWebUI(web_ui());
66
67  plugin_status_pref_setter_.Init(
68      profile,
69      base::Bind(&CoreOptionsHandler::OnPreferenceChanged,
70                 base::Unretained(this),
71                 profile->GetPrefs()));
72
73  pref_change_filters_[prefs::kMetricsReportingEnabled] =
74      base::Bind(&AllowMetricsReportingChange);
75}
76
77void CoreOptionsHandler::InitializePage() {
78  UpdateClearPluginLSOData();
79  UpdatePepperFlashSettingsEnabled();
80}
81
82void CoreOptionsHandler::GetLocalizedValues(
83    base::DictionaryValue* localized_strings) {
84  GetStaticLocalizedValues(localized_strings);
85}
86
87void CoreOptionsHandler::GetStaticLocalizedValues(
88    base::DictionaryValue* localized_strings) {
89  DCHECK(localized_strings);
90  // Main
91  localized_strings->SetString("optionsPageTitle",
92      l10n_util::GetStringUTF16(IDS_SETTINGS_TITLE));
93
94  // Controlled settings bubble.
95  localized_strings->SetString("controlledSettingPolicy",
96      l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTING_POLICY));
97  localized_strings->SetString("controlledSettingExtension",
98      l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTING_EXTENSION));
99  localized_strings->SetString("controlledSettingExtensionWithName",
100      l10n_util::GetStringUTF16(
101          IDS_OPTIONS_CONTROLLED_SETTING_EXTENSION_WITH_NAME));
102  localized_strings->SetString("controlledSettingManageExtensions",
103      l10n_util::GetStringUTF16(
104          IDS_OPTIONS_CONTROLLED_SETTING_MANAGE_EXTENSIONS));
105  localized_strings->SetString("controlledSettingDisableExtension",
106      l10n_util::GetStringUTF16(IDS_EXTENSIONS_DISABLE));
107  localized_strings->SetString("controlledSettingRecommended",
108      l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTING_RECOMMENDED));
109  localized_strings->SetString("controlledSettingHasRecommendation",
110      l10n_util::GetStringUTF16(
111          IDS_OPTIONS_CONTROLLED_SETTING_HAS_RECOMMENDATION));
112  localized_strings->SetString("controlledSettingFollowRecommendation",
113      l10n_util::GetStringUTF16(
114          IDS_OPTIONS_CONTROLLED_SETTING_FOLLOW_RECOMMENDATION));
115  localized_strings->SetString("controlledSettingsPolicy",
116      l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTINGS_POLICY));
117  localized_strings->SetString("controlledSettingsExtension",
118      l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTINGS_EXTENSION));
119  localized_strings->SetString("controlledSettingsExtensionWithName",
120      l10n_util::GetStringUTF16(
121          IDS_OPTIONS_CONTROLLED_SETTINGS_EXTENSION_WITH_NAME));
122
123  // Search
124  RegisterTitle(localized_strings, "searchPage", IDS_OPTIONS_SEARCH_PAGE_TITLE);
125  localized_strings->SetString("searchPlaceholder",
126      l10n_util::GetStringUTF16(IDS_OPTIONS_SEARCH_PLACEHOLDER));
127  localized_strings->SetString("searchPageNoMatches",
128      l10n_util::GetStringUTF16(IDS_OPTIONS_SEARCH_PAGE_NO_MATCHES));
129  localized_strings->SetString("searchPageHelpLabel",
130      l10n_util::GetStringUTF16(IDS_OPTIONS_SEARCH_PAGE_HELP_LABEL));
131  localized_strings->SetString("searchPageHelpTitle",
132      l10n_util::GetStringFUTF16(IDS_OPTIONS_SEARCH_PAGE_HELP_TITLE,
133          l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
134  localized_strings->SetString("searchPageHelpURL",
135                               chrome::kSettingsSearchHelpURL);
136
137  // Common
138  localized_strings->SetString("ok",
139      l10n_util::GetStringUTF16(IDS_OK));
140  localized_strings->SetString("cancel",
141      l10n_util::GetStringUTF16(IDS_CANCEL));
142  localized_strings->SetString("learnMore",
143      l10n_util::GetStringUTF16(IDS_LEARN_MORE));
144  localized_strings->SetString("close",
145      l10n_util::GetStringUTF16(IDS_CLOSE));
146  localized_strings->SetString("done",
147      l10n_util::GetStringUTF16(IDS_DONE));
148}
149
150void CoreOptionsHandler::Uninitialize() {
151  std::string last_pref;
152  for (PreferenceCallbackMap::const_iterator iter = pref_callback_map_.begin();
153       iter != pref_callback_map_.end();
154       ++iter) {
155    if (last_pref != iter->first) {
156      StopObservingPref(iter->first);
157      last_pref = iter->first;
158    }
159  }
160}
161
162void CoreOptionsHandler::OnPreferenceChanged(PrefService* service,
163                                             const std::string& pref_name) {
164  if (pref_name == prefs::kClearPluginLSODataEnabled) {
165    // This preference is stored in Local State, not in the user preferences.
166    UpdateClearPluginLSOData();
167    return;
168  }
169  if (pref_name == prefs::kPepperFlashSettingsEnabled) {
170    UpdatePepperFlashSettingsEnabled();
171    return;
172  }
173  NotifyPrefChanged(pref_name, std::string());
174}
175
176void CoreOptionsHandler::RegisterMessages() {
177  registrar_.Init(Profile::FromWebUI(web_ui())->GetPrefs());
178  local_state_registrar_.Init(g_browser_process->local_state());
179
180  web_ui()->RegisterMessageCallback("coreOptionsInitialize",
181      base::Bind(&CoreOptionsHandler::HandleInitialize,
182                 base::Unretained(this)));
183  web_ui()->RegisterMessageCallback("fetchPrefs",
184      base::Bind(&CoreOptionsHandler::HandleFetchPrefs,
185                 base::Unretained(this)));
186  web_ui()->RegisterMessageCallback("observePrefs",
187      base::Bind(&CoreOptionsHandler::HandleObservePrefs,
188                 base::Unretained(this)));
189  web_ui()->RegisterMessageCallback("setBooleanPref",
190      base::Bind(&CoreOptionsHandler::HandleSetBooleanPref,
191                 base::Unretained(this)));
192  web_ui()->RegisterMessageCallback("setIntegerPref",
193      base::Bind(&CoreOptionsHandler::HandleSetIntegerPref,
194                 base::Unretained(this)));
195  web_ui()->RegisterMessageCallback("setDoublePref",
196      base::Bind(&CoreOptionsHandler::HandleSetDoublePref,
197                 base::Unretained(this)));
198  web_ui()->RegisterMessageCallback("setStringPref",
199      base::Bind(&CoreOptionsHandler::HandleSetStringPref,
200                 base::Unretained(this)));
201  web_ui()->RegisterMessageCallback("setURLPref",
202      base::Bind(&CoreOptionsHandler::HandleSetURLPref,
203                 base::Unretained(this)));
204  web_ui()->RegisterMessageCallback("setListPref",
205      base::Bind(&CoreOptionsHandler::HandleSetListPref,
206                 base::Unretained(this)));
207  web_ui()->RegisterMessageCallback("clearPref",
208      base::Bind(&CoreOptionsHandler::HandleClearPref,
209                 base::Unretained(this)));
210  web_ui()->RegisterMessageCallback("coreOptionsUserMetricsAction",
211      base::Bind(&CoreOptionsHandler::HandleUserMetricsAction,
212                 base::Unretained(this)));
213  web_ui()->RegisterMessageCallback("disableExtension",
214      base::Bind(&CoreOptionsHandler::HandleDisableExtension,
215                 base::Unretained(this)));
216}
217
218void CoreOptionsHandler::HandleInitialize(const base::ListValue* args) {
219  DCHECK(handlers_host_);
220  handlers_host_->InitializeHandlers();
221}
222
223base::Value* CoreOptionsHandler::FetchPref(const std::string& pref_name) {
224  return CreateValueForPref(pref_name, std::string());
225}
226
227void CoreOptionsHandler::ObservePref(const std::string& pref_name) {
228  if (g_browser_process->local_state()->FindPreference(pref_name.c_str())) {
229    local_state_registrar_.Add(
230        pref_name.c_str(),
231        base::Bind(&CoreOptionsHandler::OnPreferenceChanged,
232                   base::Unretained(this),
233                   local_state_registrar_.prefs()));
234  }
235  // TODO(pneubeck): change this to if/else once kProxy is only used as a user
236  // pref. Currently, it is both a user and a local state pref.
237  if (Profile::FromWebUI(web_ui())->GetPrefs()->FindPreference(
238          pref_name.c_str())) {
239    registrar_.Add(
240        pref_name.c_str(),
241        base::Bind(&CoreOptionsHandler::OnPreferenceChanged,
242                   base::Unretained(this),
243                   registrar_.prefs()));
244  }
245}
246
247void CoreOptionsHandler::StopObservingPref(const std::string& pref_name) {
248  if (g_browser_process->local_state()->FindPreference(pref_name.c_str()))
249    local_state_registrar_.Remove(pref_name.c_str());
250  else
251    registrar_.Remove(pref_name.c_str());
252}
253
254void CoreOptionsHandler::SetPref(const std::string& pref_name,
255                                 const base::Value* value,
256                                 const std::string& metric) {
257  PrefService* pref_service = FindServiceForPref(pref_name);
258  PrefChangeFilterMap::iterator iter = pref_change_filters_.find(pref_name);
259  if (iter != pref_change_filters_.end()) {
260    // Also check if the pref is user modifiable (don't even try to run the
261    // filter function if the user is not allowed to change the pref).
262    const PrefService::Preference* pref =
263        pref_service->FindPreference(pref_name.c_str());
264    if ((pref && !pref->IsUserModifiable()) || !iter->second.Run(value)) {
265      // Reject the change; remind the page of the true value.
266      NotifyPrefChanged(pref_name, std::string());
267      return;
268    }
269  }
270
271  switch (value->GetType()) {
272    case base::Value::TYPE_BOOLEAN:
273    case base::Value::TYPE_INTEGER:
274    case base::Value::TYPE_DOUBLE:
275    case base::Value::TYPE_STRING:
276    case base::Value::TYPE_LIST:
277      pref_service->Set(pref_name.c_str(), *value);
278      break;
279
280    default:
281      NOTREACHED();
282      return;
283  }
284
285  ProcessUserMetric(value, metric);
286}
287
288void CoreOptionsHandler::ClearPref(const std::string& pref_name,
289                                   const std::string& metric) {
290  PrefService* pref_service = FindServiceForPref(pref_name);
291  pref_service->ClearPref(pref_name.c_str());
292
293  if (!metric.empty())
294    content::RecordComputedAction(metric);
295}
296
297void CoreOptionsHandler::ProcessUserMetric(const base::Value* value,
298                                           const std::string& metric) {
299  if (metric.empty())
300    return;
301
302  std::string metric_string = metric;
303  if (value->IsType(base::Value::TYPE_BOOLEAN)) {
304    bool bool_value;
305    CHECK(value->GetAsBoolean(&bool_value));
306    metric_string += bool_value ? "_Enable" : "_Disable";
307  }
308
309  content::RecordComputedAction(metric_string);
310}
311
312void CoreOptionsHandler::NotifyPrefChanged(
313    const std::string& pref_name,
314    const std::string& controlling_pref_name) {
315  scoped_ptr<base::Value> value(
316      CreateValueForPref(pref_name, controlling_pref_name));
317  DispatchPrefChangeNotification(pref_name, value.Pass());
318}
319
320void CoreOptionsHandler::DispatchPrefChangeNotification(
321    const std::string& name,
322    scoped_ptr<base::Value> value) {
323  std::pair<PreferenceCallbackMap::const_iterator,
324            PreferenceCallbackMap::const_iterator> range =
325      pref_callback_map_.equal_range(name);
326  base::ListValue result_value;
327  result_value.Append(new base::StringValue(name.c_str()));
328  result_value.Append(value.release());
329  for (PreferenceCallbackMap::const_iterator iter = range.first;
330       iter != range.second; ++iter) {
331    const std::string& callback_function = iter->second;
332    web_ui()->CallJavascriptFunction(callback_function, result_value);
333  }
334}
335
336base::Value* CoreOptionsHandler::CreateValueForPref(
337    const std::string& pref_name,
338    const std::string& controlling_pref_name) {
339  const PrefService* pref_service = FindServiceForPref(pref_name.c_str());
340  const PrefService::Preference* pref =
341      pref_service->FindPreference(pref_name.c_str());
342  if (!pref) {
343    NOTREACHED();
344    return base::Value::CreateNullValue();
345  }
346  const PrefService::Preference* controlling_pref =
347      pref_service->FindPreference(controlling_pref_name.c_str());
348  if (!controlling_pref)
349    controlling_pref = pref;
350
351  base::DictionaryValue* dict = new base::DictionaryValue;
352  dict->Set("value", pref->GetValue()->DeepCopy());
353  if (controlling_pref->IsManaged()) {
354    dict->SetString("controlledBy", "policy");
355  } else if (controlling_pref->IsExtensionControlled()) {
356    dict->SetString("controlledBy", "extension");
357    Profile* profile = Profile::FromWebUI(web_ui());
358    ExtensionPrefValueMap* extension_pref_value_map =
359        ExtensionPrefValueMapFactory::GetForBrowserContext(profile);
360    std::string extension_id =
361        extension_pref_value_map->GetExtensionControllingPref(
362            controlling_pref->name());
363
364    ExtensionService* extension_service = extensions::ExtensionSystem::Get(
365        profile)->extension_service();
366    scoped_ptr<base::DictionaryValue> dictionary =
367        extension_service->GetExtensionInfo(extension_id);
368    if (!dictionary->empty())
369      dict->Set("extension", dictionary.release());
370  } else if (controlling_pref->IsRecommended()) {
371    dict->SetString("controlledBy", "recommended");
372  }
373
374  const base::Value* recommended_value =
375      controlling_pref->GetRecommendedValue();
376  if (recommended_value)
377    dict->Set("recommendedValue", recommended_value->DeepCopy());
378  dict->SetBoolean("disabled", !controlling_pref->IsUserModifiable());
379  return dict;
380}
381
382PrefService* CoreOptionsHandler::FindServiceForPref(
383    const std::string& pref_name) {
384  // Proxy is a peculiar case: on ChromeOS, settings exist in both user
385  // prefs and local state, but chrome://settings should affect only user prefs.
386  // Elsewhere the proxy settings are stored in local state.
387  // See http://crbug.com/157147
388  PrefService* user_prefs = Profile::FromWebUI(web_ui())->GetPrefs();
389  if (pref_name == prefs::kProxy)
390#if defined(OS_CHROMEOS)
391    return user_prefs;
392#else
393    return g_browser_process->local_state();
394#endif
395
396  // Find which PrefService contains the given pref. Pref names should not
397  // be duplicated across services, however if they are, prefer the user's
398  // prefs.
399  if (user_prefs->FindPreference(pref_name.c_str()))
400    return user_prefs;
401
402  if (g_browser_process->local_state()->FindPreference(pref_name.c_str()))
403    return g_browser_process->local_state();
404
405  return user_prefs;
406}
407
408void CoreOptionsHandler::HandleFetchPrefs(const base::ListValue* args) {
409  // First param is name of callback function, so, there needs to be at least
410  // one more element for the actual preference identifier.
411  DCHECK_GE(static_cast<int>(args->GetSize()), 2);
412
413  // Get callback JS function name.
414  const base::Value* callback;
415  if (!args->Get(0, &callback) || !callback->IsType(base::Value::TYPE_STRING))
416    return;
417
418  base::string16 callback_function;
419  if (!callback->GetAsString(&callback_function))
420    return;
421
422  // Get the list of name for prefs to build the response dictionary.
423  base::DictionaryValue result_value;
424  const base::Value* list_member;
425
426  for (size_t i = 1; i < args->GetSize(); i++) {
427    if (!args->Get(i, &list_member))
428      break;
429
430    if (!list_member->IsType(base::Value::TYPE_STRING))
431      continue;
432
433    std::string pref_name;
434    if (!list_member->GetAsString(&pref_name))
435      continue;
436
437    result_value.Set(pref_name.c_str(), FetchPref(pref_name));
438  }
439  web_ui()->CallJavascriptFunction(UTF16ToASCII(callback_function),
440                                   result_value);
441}
442
443void CoreOptionsHandler::HandleObservePrefs(const base::ListValue* args) {
444  // First param is name is JS callback function name, the rest are pref
445  // identifiers that we are observing.
446  DCHECK_GE(static_cast<int>(args->GetSize()), 2);
447
448  // Get preference change callback function name.
449  std::string callback_func_name;
450  if (!args->GetString(0, &callback_func_name))
451    return;
452
453  // Get all other parameters - pref identifiers.
454  for (size_t i = 1; i < args->GetSize(); i++) {
455    const base::Value* list_member;
456    if (!args->Get(i, &list_member))
457      break;
458
459    // Just ignore bad pref identifiers for now.
460    std::string pref_name;
461    if (!list_member->IsType(base::Value::TYPE_STRING) ||
462        !list_member->GetAsString(&pref_name))
463      continue;
464
465    if (pref_callback_map_.find(pref_name) == pref_callback_map_.end())
466      ObservePref(pref_name);
467
468    pref_callback_map_.insert(
469        PreferenceCallbackMap::value_type(pref_name, callback_func_name));
470  }
471}
472
473void CoreOptionsHandler::HandleSetBooleanPref(const base::ListValue* args) {
474  HandleSetPref(args, TYPE_BOOLEAN);
475}
476
477void CoreOptionsHandler::HandleSetIntegerPref(const base::ListValue* args) {
478  HandleSetPref(args, TYPE_INTEGER);
479}
480
481void CoreOptionsHandler::HandleSetDoublePref(const base::ListValue* args) {
482  HandleSetPref(args, TYPE_DOUBLE);
483}
484
485void CoreOptionsHandler::HandleSetStringPref(const base::ListValue* args) {
486  HandleSetPref(args, TYPE_STRING);
487}
488
489void CoreOptionsHandler::HandleSetURLPref(const base::ListValue* args) {
490  HandleSetPref(args, TYPE_URL);
491}
492
493void CoreOptionsHandler::HandleSetListPref(const base::ListValue* args) {
494  HandleSetPref(args, TYPE_LIST);
495}
496
497void CoreOptionsHandler::HandleSetPref(const base::ListValue* args,
498                                       PrefType type) {
499  DCHECK_GT(static_cast<int>(args->GetSize()), 1);
500
501  std::string pref_name;
502  if (!args->GetString(0, &pref_name))
503    return;
504
505  const base::Value* value;
506  if (!args->Get(1, &value))
507    return;
508
509  scoped_ptr<base::Value> temp_value;
510
511  switch (type) {
512    case TYPE_BOOLEAN:
513      if (!value->IsType(base::Value::TYPE_BOOLEAN)) {
514        NOTREACHED();
515        return;
516      }
517      break;
518    case TYPE_INTEGER: {
519      // In JS all numbers are doubles.
520      double double_value;
521      if (!value->GetAsDouble(&double_value)) {
522        NOTREACHED();
523        return;
524      }
525      int int_value = static_cast<int>(double_value);
526      temp_value.reset(new base::FundamentalValue(int_value));
527      value = temp_value.get();
528      break;
529    }
530    case TYPE_DOUBLE:
531      if (!value->IsType(base::Value::TYPE_DOUBLE)) {
532        NOTREACHED();
533        return;
534      }
535      break;
536    case TYPE_STRING:
537      if (!value->IsType(base::Value::TYPE_STRING)) {
538        NOTREACHED();
539        return;
540      }
541      break;
542    case TYPE_URL: {
543      std::string original;
544      if (!value->GetAsString(&original)) {
545        NOTREACHED();
546        return;
547      }
548      GURL fixed = URLFixerUpper::FixupURL(original, std::string());
549      temp_value.reset(new base::StringValue(fixed.spec()));
550      value = temp_value.get();
551      break;
552    }
553    case TYPE_LIST: {
554      // In case we have a List pref we got a JSON string.
555      std::string json_string;
556      if (!value->GetAsString(&json_string)) {
557        NOTREACHED();
558        return;
559      }
560      temp_value.reset(
561          base::JSONReader::Read(json_string));
562      value = temp_value.get();
563      if (!value->IsType(base::Value::TYPE_LIST)) {
564        NOTREACHED();
565        return;
566      }
567      break;
568    }
569    default:
570      NOTREACHED();
571  }
572
573  std::string metric;
574  if (args->GetSize() > 2 && !args->GetString(2, &metric))
575    LOG(WARNING) << "Invalid metric parameter: " << pref_name;
576  SetPref(pref_name, value, metric);
577}
578
579void CoreOptionsHandler::HandleClearPref(const base::ListValue* args) {
580  DCHECK_GT(static_cast<int>(args->GetSize()), 0);
581
582  std::string pref_name;
583  if (!args->GetString(0, &pref_name))
584    return;
585
586  std::string metric;
587  if (args->GetSize() > 1) {
588    if (!args->GetString(1, &metric))
589      NOTREACHED();
590  }
591
592  ClearPref(pref_name, metric);
593}
594
595void CoreOptionsHandler::HandleUserMetricsAction(const base::ListValue* args) {
596  std::string metric = base::UTF16ToUTF8(ExtractStringValue(args));
597  if (!metric.empty())
598    content::RecordComputedAction(metric);
599}
600
601void CoreOptionsHandler::HandleDisableExtension(const base::ListValue* args) {
602  std::string extension_id;
603  if (args->GetString(0, &extension_id)) {
604    ExtensionService* extension_service = extensions::ExtensionSystem::Get(
605        Profile::FromWebUI(web_ui()))->extension_service();
606    DCHECK(extension_service);
607    extension_service->DisableExtension(
608        extension_id, extensions::Extension::DISABLE_USER_ACTION);
609  } else {
610    NOTREACHED();
611  }
612}
613
614void CoreOptionsHandler::UpdateClearPluginLSOData() {
615  base::FundamentalValue enabled(
616          plugin_status_pref_setter_.IsClearPluginLSODataEnabled());
617  web_ui()->CallJavascriptFunction(
618      "OptionsPage.setClearPluginLSODataEnabled", enabled);
619}
620
621void CoreOptionsHandler::UpdatePepperFlashSettingsEnabled() {
622  base::FundamentalValue enabled(
623          plugin_status_pref_setter_.IsPepperFlashSettingsEnabled());
624  web_ui()->CallJavascriptFunction(
625      "OptionsPage.setPepperFlashSettingsEnabled", enabled);
626}
627
628}  // namespace options
629