core_options_handler.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
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} 147 148void CoreOptionsHandler::Uninitialize() { 149 std::string last_pref; 150 for (PreferenceCallbackMap::const_iterator iter = pref_callback_map_.begin(); 151 iter != pref_callback_map_.end(); 152 ++iter) { 153 if (last_pref != iter->first) { 154 StopObservingPref(iter->first); 155 last_pref = iter->first; 156 } 157 } 158} 159 160void CoreOptionsHandler::OnPreferenceChanged(PrefService* service, 161 const std::string& pref_name) { 162 if (pref_name == prefs::kClearPluginLSODataEnabled) { 163 // This preference is stored in Local State, not in the user preferences. 164 UpdateClearPluginLSOData(); 165 return; 166 } 167 if (pref_name == prefs::kPepperFlashSettingsEnabled) { 168 UpdatePepperFlashSettingsEnabled(); 169 return; 170 } 171 NotifyPrefChanged(pref_name, std::string()); 172} 173 174void CoreOptionsHandler::RegisterMessages() { 175 registrar_.Init(Profile::FromWebUI(web_ui())->GetPrefs()); 176 local_state_registrar_.Init(g_browser_process->local_state()); 177 178 web_ui()->RegisterMessageCallback("coreOptionsInitialize", 179 base::Bind(&CoreOptionsHandler::HandleInitialize, 180 base::Unretained(this))); 181 web_ui()->RegisterMessageCallback("onFinishedLoadingOptions", 182 base::Bind(&CoreOptionsHandler::OnFinishedLoading, 183 base::Unretained(this))); 184 web_ui()->RegisterMessageCallback("fetchPrefs", 185 base::Bind(&CoreOptionsHandler::HandleFetchPrefs, 186 base::Unretained(this))); 187 web_ui()->RegisterMessageCallback("observePrefs", 188 base::Bind(&CoreOptionsHandler::HandleObservePrefs, 189 base::Unretained(this))); 190 web_ui()->RegisterMessageCallback("setBooleanPref", 191 base::Bind(&CoreOptionsHandler::HandleSetBooleanPref, 192 base::Unretained(this))); 193 web_ui()->RegisterMessageCallback("setIntegerPref", 194 base::Bind(&CoreOptionsHandler::HandleSetIntegerPref, 195 base::Unretained(this))); 196 web_ui()->RegisterMessageCallback("setDoublePref", 197 base::Bind(&CoreOptionsHandler::HandleSetDoublePref, 198 base::Unretained(this))); 199 web_ui()->RegisterMessageCallback("setStringPref", 200 base::Bind(&CoreOptionsHandler::HandleSetStringPref, 201 base::Unretained(this))); 202 web_ui()->RegisterMessageCallback("setURLPref", 203 base::Bind(&CoreOptionsHandler::HandleSetURLPref, 204 base::Unretained(this))); 205 web_ui()->RegisterMessageCallback("setListPref", 206 base::Bind(&CoreOptionsHandler::HandleSetListPref, 207 base::Unretained(this))); 208 web_ui()->RegisterMessageCallback("clearPref", 209 base::Bind(&CoreOptionsHandler::HandleClearPref, 210 base::Unretained(this))); 211 web_ui()->RegisterMessageCallback("coreOptionsUserMetricsAction", 212 base::Bind(&CoreOptionsHandler::HandleUserMetricsAction, 213 base::Unretained(this))); 214 web_ui()->RegisterMessageCallback("disableExtension", 215 base::Bind(&CoreOptionsHandler::HandleDisableExtension, 216 base::Unretained(this))); 217} 218 219void CoreOptionsHandler::HandleInitialize(const base::ListValue* args) { 220 DCHECK(handlers_host_); 221 handlers_host_->InitializeHandlers(); 222} 223 224void CoreOptionsHandler::OnFinishedLoading(const base::ListValue* args) { 225 DCHECK(handlers_host_); 226 handlers_host_->OnFinishedLoading(); 227} 228 229base::Value* CoreOptionsHandler::FetchPref(const std::string& pref_name) { 230 return CreateValueForPref(pref_name, std::string()); 231} 232 233void CoreOptionsHandler::ObservePref(const std::string& pref_name) { 234 if (g_browser_process->local_state()->FindPreference(pref_name.c_str())) { 235 local_state_registrar_.Add( 236 pref_name.c_str(), 237 base::Bind(&CoreOptionsHandler::OnPreferenceChanged, 238 base::Unretained(this), 239 local_state_registrar_.prefs())); 240 } 241 // TODO(pneubeck): change this to if/else once kProxy is only used as a user 242 // pref. Currently, it is both a user and a local state pref. 243 if (Profile::FromWebUI(web_ui())->GetPrefs()->FindPreference( 244 pref_name.c_str())) { 245 registrar_.Add( 246 pref_name.c_str(), 247 base::Bind(&CoreOptionsHandler::OnPreferenceChanged, 248 base::Unretained(this), 249 registrar_.prefs())); 250 } 251} 252 253void CoreOptionsHandler::StopObservingPref(const std::string& pref_name) { 254 if (g_browser_process->local_state()->FindPreference(pref_name.c_str())) 255 local_state_registrar_.Remove(pref_name.c_str()); 256 else 257 registrar_.Remove(pref_name.c_str()); 258} 259 260void CoreOptionsHandler::SetPref(const std::string& pref_name, 261 const base::Value* value, 262 const std::string& metric) { 263 PrefService* pref_service = FindServiceForPref(pref_name); 264 PrefChangeFilterMap::iterator iter = pref_change_filters_.find(pref_name); 265 if (iter != pref_change_filters_.end()) { 266 // Also check if the pref is user modifiable (don't even try to run the 267 // filter function if the user is not allowed to change the pref). 268 const PrefService::Preference* pref = 269 pref_service->FindPreference(pref_name.c_str()); 270 if ((pref && !pref->IsUserModifiable()) || !iter->second.Run(value)) { 271 // Reject the change; remind the page of the true value. 272 NotifyPrefChanged(pref_name, std::string()); 273 return; 274 } 275 } 276 277 switch (value->GetType()) { 278 case base::Value::TYPE_BOOLEAN: 279 case base::Value::TYPE_INTEGER: 280 case base::Value::TYPE_DOUBLE: 281 case base::Value::TYPE_STRING: 282 case base::Value::TYPE_LIST: 283 pref_service->Set(pref_name.c_str(), *value); 284 break; 285 286 default: 287 NOTREACHED(); 288 return; 289 } 290 291 ProcessUserMetric(value, metric); 292} 293 294void CoreOptionsHandler::ClearPref(const std::string& pref_name, 295 const std::string& metric) { 296 PrefService* pref_service = FindServiceForPref(pref_name); 297 pref_service->ClearPref(pref_name.c_str()); 298 299 if (!metric.empty()) 300 content::RecordComputedAction(metric); 301} 302 303void CoreOptionsHandler::ProcessUserMetric(const base::Value* value, 304 const std::string& metric) { 305 if (metric.empty()) 306 return; 307 308 std::string metric_string = metric; 309 if (value->IsType(base::Value::TYPE_BOOLEAN)) { 310 bool bool_value; 311 CHECK(value->GetAsBoolean(&bool_value)); 312 metric_string += bool_value ? "_Enable" : "_Disable"; 313 } 314 315 content::RecordComputedAction(metric_string); 316} 317 318void CoreOptionsHandler::NotifyPrefChanged( 319 const std::string& pref_name, 320 const std::string& controlling_pref_name) { 321 scoped_ptr<base::Value> value( 322 CreateValueForPref(pref_name, controlling_pref_name)); 323 DispatchPrefChangeNotification(pref_name, value.Pass()); 324} 325 326void CoreOptionsHandler::DispatchPrefChangeNotification( 327 const std::string& name, 328 scoped_ptr<base::Value> value) { 329 std::pair<PreferenceCallbackMap::const_iterator, 330 PreferenceCallbackMap::const_iterator> range = 331 pref_callback_map_.equal_range(name); 332 base::ListValue result_value; 333 result_value.Append(new base::StringValue(name.c_str())); 334 result_value.Append(value.release()); 335 for (PreferenceCallbackMap::const_iterator iter = range.first; 336 iter != range.second; ++iter) { 337 const std::string& callback_function = iter->second; 338 web_ui()->CallJavascriptFunction(callback_function, result_value); 339 } 340} 341 342base::Value* CoreOptionsHandler::CreateValueForPref( 343 const std::string& pref_name, 344 const std::string& controlling_pref_name) { 345 const PrefService* pref_service = FindServiceForPref(pref_name.c_str()); 346 const PrefService::Preference* pref = 347 pref_service->FindPreference(pref_name.c_str()); 348 if (!pref) { 349 NOTREACHED(); 350 return base::Value::CreateNullValue(); 351 } 352 const PrefService::Preference* controlling_pref = 353 pref_service->FindPreference(controlling_pref_name.c_str()); 354 if (!controlling_pref) 355 controlling_pref = pref; 356 357 // We don't show a UI here for extension controlled values because we opted to 358 // show a more obvious UI than an extension puzzle piece on the settings page. 359 base::DictionaryValue* dict = new base::DictionaryValue; 360 dict->Set("value", pref->GetValue()->DeepCopy()); 361 if (controlling_pref->IsManaged()) 362 dict->SetString("controlledBy", "policy"); 363 else if (controlling_pref->IsRecommended()) 364 dict->SetString("controlledBy", "recommended"); 365 366 const base::Value* recommended_value = 367 controlling_pref->GetRecommendedValue(); 368 if (recommended_value) 369 dict->Set("recommendedValue", recommended_value->DeepCopy()); 370 dict->SetBoolean("disabled", !controlling_pref->IsUserModifiable()); 371 return dict; 372} 373 374PrefService* CoreOptionsHandler::FindServiceForPref( 375 const std::string& pref_name) { 376 // Proxy is a peculiar case: on ChromeOS, settings exist in both user 377 // prefs and local state, but chrome://settings should affect only user prefs. 378 // Elsewhere the proxy settings are stored in local state. 379 // See http://crbug.com/157147 380 PrefService* user_prefs = Profile::FromWebUI(web_ui())->GetPrefs(); 381 if (pref_name == prefs::kProxy) 382#if defined(OS_CHROMEOS) 383 return user_prefs; 384#else 385 return g_browser_process->local_state(); 386#endif 387 388 // Find which PrefService contains the given pref. Pref names should not 389 // be duplicated across services, however if they are, prefer the user's 390 // prefs. 391 if (user_prefs->FindPreference(pref_name.c_str())) 392 return user_prefs; 393 394 if (g_browser_process->local_state()->FindPreference(pref_name.c_str())) 395 return g_browser_process->local_state(); 396 397 return user_prefs; 398} 399 400void CoreOptionsHandler::HandleFetchPrefs(const base::ListValue* args) { 401 // First param is name of callback function, so, there needs to be at least 402 // one more element for the actual preference identifier. 403 DCHECK_GE(static_cast<int>(args->GetSize()), 2); 404 405 // Get callback JS function name. 406 const base::Value* callback; 407 if (!args->Get(0, &callback) || !callback->IsType(base::Value::TYPE_STRING)) 408 return; 409 410 base::string16 callback_function; 411 if (!callback->GetAsString(&callback_function)) 412 return; 413 414 // Get the list of name for prefs to build the response dictionary. 415 base::DictionaryValue result_value; 416 const base::Value* list_member; 417 418 for (size_t i = 1; i < args->GetSize(); i++) { 419 if (!args->Get(i, &list_member)) 420 break; 421 422 if (!list_member->IsType(base::Value::TYPE_STRING)) 423 continue; 424 425 std::string pref_name; 426 if (!list_member->GetAsString(&pref_name)) 427 continue; 428 429 result_value.Set(pref_name.c_str(), FetchPref(pref_name)); 430 } 431 web_ui()->CallJavascriptFunction(base::UTF16ToASCII(callback_function), 432 result_value); 433} 434 435void CoreOptionsHandler::HandleObservePrefs(const base::ListValue* args) { 436 // First param is name is JS callback function name, the rest are pref 437 // identifiers that we are observing. 438 DCHECK_GE(static_cast<int>(args->GetSize()), 2); 439 440 // Get preference change callback function name. 441 std::string callback_func_name; 442 if (!args->GetString(0, &callback_func_name)) 443 return; 444 445 // Get all other parameters - pref identifiers. 446 for (size_t i = 1; i < args->GetSize(); i++) { 447 const base::Value* list_member; 448 if (!args->Get(i, &list_member)) 449 break; 450 451 // Just ignore bad pref identifiers for now. 452 std::string pref_name; 453 if (!list_member->IsType(base::Value::TYPE_STRING) || 454 !list_member->GetAsString(&pref_name)) 455 continue; 456 457 if (pref_callback_map_.find(pref_name) == pref_callback_map_.end()) 458 ObservePref(pref_name); 459 460 pref_callback_map_.insert( 461 PreferenceCallbackMap::value_type(pref_name, callback_func_name)); 462 } 463} 464 465void CoreOptionsHandler::HandleSetBooleanPref(const base::ListValue* args) { 466 HandleSetPref(args, TYPE_BOOLEAN); 467} 468 469void CoreOptionsHandler::HandleSetIntegerPref(const base::ListValue* args) { 470 HandleSetPref(args, TYPE_INTEGER); 471} 472 473void CoreOptionsHandler::HandleSetDoublePref(const base::ListValue* args) { 474 HandleSetPref(args, TYPE_DOUBLE); 475} 476 477void CoreOptionsHandler::HandleSetStringPref(const base::ListValue* args) { 478 HandleSetPref(args, TYPE_STRING); 479} 480 481void CoreOptionsHandler::HandleSetURLPref(const base::ListValue* args) { 482 HandleSetPref(args, TYPE_URL); 483} 484 485void CoreOptionsHandler::HandleSetListPref(const base::ListValue* args) { 486 HandleSetPref(args, TYPE_LIST); 487} 488 489void CoreOptionsHandler::HandleSetPref(const base::ListValue* args, 490 PrefType type) { 491 DCHECK_GT(static_cast<int>(args->GetSize()), 1); 492 493 std::string pref_name; 494 if (!args->GetString(0, &pref_name)) 495 return; 496 497 const base::Value* value; 498 if (!args->Get(1, &value)) 499 return; 500 501 scoped_ptr<base::Value> temp_value; 502 503 switch (type) { 504 case TYPE_BOOLEAN: 505 if (!value->IsType(base::Value::TYPE_BOOLEAN)) { 506 NOTREACHED(); 507 return; 508 } 509 break; 510 case TYPE_INTEGER: { 511 // In JS all numbers are doubles. 512 double double_value; 513 if (!value->GetAsDouble(&double_value)) { 514 NOTREACHED(); 515 return; 516 } 517 int int_value = static_cast<int>(double_value); 518 temp_value.reset(new base::FundamentalValue(int_value)); 519 value = temp_value.get(); 520 break; 521 } 522 case TYPE_DOUBLE: 523 if (!value->IsType(base::Value::TYPE_DOUBLE)) { 524 NOTREACHED(); 525 return; 526 } 527 break; 528 case TYPE_STRING: 529 if (!value->IsType(base::Value::TYPE_STRING)) { 530 NOTREACHED(); 531 return; 532 } 533 break; 534 case TYPE_URL: { 535 std::string original; 536 if (!value->GetAsString(&original)) { 537 NOTREACHED(); 538 return; 539 } 540 GURL fixed = URLFixerUpper::FixupURL(original, std::string()); 541 temp_value.reset(new base::StringValue(fixed.spec())); 542 value = temp_value.get(); 543 break; 544 } 545 case TYPE_LIST: { 546 // In case we have a List pref we got a JSON string. 547 std::string json_string; 548 if (!value->GetAsString(&json_string)) { 549 NOTREACHED(); 550 return; 551 } 552 temp_value.reset( 553 base::JSONReader::Read(json_string)); 554 value = temp_value.get(); 555 if (!value->IsType(base::Value::TYPE_LIST)) { 556 NOTREACHED(); 557 return; 558 } 559 break; 560 } 561 default: 562 NOTREACHED(); 563 } 564 565 std::string metric; 566 if (args->GetSize() > 2 && !args->GetString(2, &metric)) 567 LOG(WARNING) << "Invalid metric parameter: " << pref_name; 568 SetPref(pref_name, value, metric); 569} 570 571void CoreOptionsHandler::HandleClearPref(const base::ListValue* args) { 572 DCHECK_GT(static_cast<int>(args->GetSize()), 0); 573 574 std::string pref_name; 575 if (!args->GetString(0, &pref_name)) 576 return; 577 578 std::string metric; 579 if (args->GetSize() > 1) { 580 if (!args->GetString(1, &metric)) 581 NOTREACHED(); 582 } 583 584 ClearPref(pref_name, metric); 585} 586 587void CoreOptionsHandler::HandleUserMetricsAction(const base::ListValue* args) { 588 std::string metric = base::UTF16ToUTF8(ExtractStringValue(args)); 589 if (!metric.empty()) 590 content::RecordComputedAction(metric); 591} 592 593void CoreOptionsHandler::HandleDisableExtension(const base::ListValue* args) { 594 std::string extension_id; 595 if (args->GetString(0, &extension_id)) { 596 ExtensionService* extension_service = extensions::ExtensionSystem::Get( 597 Profile::FromWebUI(web_ui()))->extension_service(); 598 DCHECK(extension_service); 599 extension_service->DisableExtension( 600 extension_id, extensions::Extension::DISABLE_USER_ACTION); 601 } else { 602 NOTREACHED(); 603 } 604} 605 606void CoreOptionsHandler::UpdateClearPluginLSOData() { 607 base::FundamentalValue enabled( 608 plugin_status_pref_setter_.IsClearPluginLSODataEnabled()); 609 web_ui()->CallJavascriptFunction( 610 "OptionsPage.setClearPluginLSODataEnabled", enabled); 611} 612 613void CoreOptionsHandler::UpdatePepperFlashSettingsEnabled() { 614 base::FundamentalValue enabled( 615 plugin_status_pref_setter_.IsPepperFlashSettingsEnabled()); 616 web_ui()->CallJavascriptFunction( 617 "OptionsPage.setPepperFlashSettingsEnabled", enabled); 618} 619 620} // namespace options 621