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