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