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