| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/ui/webui/options/core_options_handler.h" |
| |
| #include <stddef.h> |
| |
| #include <memory> |
| #include <utility> |
| |
| #include "base/bind.h" |
| #include "base/bind_helpers.h" |
| #include "base/json/json_reader.h" |
| #include "base/metrics/user_metrics.h" |
| #include "base/strings/string16.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/values.h" |
| #include "build/build_config.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/chrome_notification_types.h" |
| #include "chrome/browser/extensions/extension_service.h" |
| #include "chrome/browser/extensions/extension_util.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/common/url_constants.h" |
| #include "chrome/grit/chromium_strings.h" |
| #include "chrome/grit/generated_resources.h" |
| #include "chrome/grit/locale_settings.h" |
| #include "components/proxy_config/proxy_config_pref_names.h" |
| #include "components/strings/grit/components_strings.h" |
| #include "components/url_formatter/url_fixer.h" |
| #include "content/public/browser/notification_details.h" |
| #include "content/public/browser/notification_types.h" |
| #include "content/public/browser/web_ui.h" |
| #include "extensions/browser/extension_pref_value_map.h" |
| #include "extensions/browser/extension_pref_value_map_factory.h" |
| #include "extensions/browser/extension_registry.h" |
| #include "extensions/browser/extension_system.h" |
| #include "extensions/common/extension.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "url/gurl.h" |
| |
| using base::UserMetricsAction; |
| |
| namespace options { |
| |
| namespace { |
| |
| // Whether "controlledBy" property of pref value sent to options web UI needs to |
| // be set to "extension" when the preference is controlled by an extension. |
| bool CanSetExtensionControlledPrefValue( |
| const PrefService::Preference* preference) { |
| #if defined(OS_WIN) |
| // These have more obvious UI than the standard one for extension controlled |
| // values (an extension puzzle piece) on the settings page. To avoiding |
| // showing the extension puzzle piece for these settings, their "controlledBy" |
| // value should never be set to "extension". |
| return preference->name() != prefs::kURLsToRestoreOnStartup && |
| preference->name() != prefs::kRestoreOnStartup && |
| preference->name() != prefs::kHomePage && |
| preference->name() != prefs::kHomePageIsNewTabPage; |
| #else |
| return true; |
| #endif |
| } |
| |
| } // namespace |
| |
| CoreOptionsHandler::CoreOptionsHandler() |
| : handlers_host_(NULL) { |
| } |
| |
| CoreOptionsHandler::~CoreOptionsHandler() {} |
| |
| void CoreOptionsHandler::InitializeHandler() { |
| Profile* profile = Profile::FromWebUI(web_ui()); |
| |
| plugin_status_pref_setter_.Init( |
| profile, |
| base::Bind(&CoreOptionsHandler::OnPreferenceChanged, |
| base::Unretained(this), |
| profile->GetPrefs())); |
| |
| pref_change_filters_[prefs::kBrowserGuestModeEnabled] = |
| base::Bind(&CoreOptionsHandler::IsUserUnsupervised, |
| base::Unretained(this)); |
| pref_change_filters_[prefs::kBrowserAddPersonEnabled] = |
| base::Bind(&CoreOptionsHandler::IsUserUnsupervised, |
| base::Unretained(this)); |
| } |
| |
| void CoreOptionsHandler::InitializePage() { |
| UpdateClearPluginLSOData(); |
| UpdatePepperFlashSettingsEnabled(); |
| } |
| |
| void CoreOptionsHandler::GetLocalizedValues( |
| base::DictionaryValue* localized_strings) { |
| GetStaticLocalizedValues(localized_strings); |
| } |
| |
| void CoreOptionsHandler::GetStaticLocalizedValues( |
| base::DictionaryValue* localized_strings) { |
| DCHECK(localized_strings); |
| // Main |
| localized_strings->SetString("optionsPageTitle", |
| l10n_util::GetStringUTF16(IDS_SETTINGS_TITLE)); |
| |
| // Controlled settings bubble. |
| localized_strings->SetString("controlledSettingPolicy", |
| l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTING_POLICY)); |
| localized_strings->SetString("controlledSettingExtension", |
| l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTING_EXTENSION)); |
| localized_strings->SetString("controlledSettingExtensionWithName", |
| l10n_util::GetStringUTF16( |
| IDS_OPTIONS_CONTROLLED_SETTING_EXTENSION_WITH_NAME)); |
| localized_strings->SetString("controlledSettingManageExtension", |
| l10n_util::GetStringUTF16( |
| IDS_OPTIONS_CONTROLLED_SETTING_MANAGE_EXTENSION)); |
| localized_strings->SetString("controlledSettingDisableExtension", |
| l10n_util::GetStringUTF16(IDS_EXTENSIONS_DISABLE)); |
| localized_strings->SetString("controlledSettingRecommended", |
| l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTING_RECOMMENDED)); |
| localized_strings->SetString("controlledSettingHasRecommendation", |
| l10n_util::GetStringUTF16( |
| IDS_OPTIONS_CONTROLLED_SETTING_HAS_RECOMMENDATION)); |
| localized_strings->SetString("controlledSettingFollowRecommendation", |
| l10n_util::GetStringUTF16( |
| IDS_OPTIONS_CONTROLLED_SETTING_FOLLOW_RECOMMENDATION)); |
| localized_strings->SetString("controlledSettingsPolicy", |
| l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTINGS_POLICY)); |
| localized_strings->SetString("controlledSettingsExtension", |
| l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTINGS_EXTENSION)); |
| localized_strings->SetString("controlledSettingsExtensionWithName", |
| l10n_util::GetStringUTF16( |
| IDS_OPTIONS_CONTROLLED_SETTINGS_EXTENSION_WITH_NAME)); |
| |
| // Search |
| RegisterTitle(localized_strings, "searchPage", IDS_OPTIONS_SEARCH_PAGE_TITLE); |
| localized_strings->SetString("searchPlaceholder", |
| l10n_util::GetStringUTF16(IDS_OPTIONS_SEARCH_PLACEHOLDER)); |
| localized_strings->SetString("searchPageNoMatches", |
| l10n_util::GetStringUTF16(IDS_OPTIONS_SEARCH_PAGE_NO_MATCHES)); |
| localized_strings->SetString("searchPageHelpLabel", |
| l10n_util::GetStringUTF16(IDS_OPTIONS_SEARCH_PAGE_HELP_LABEL)); |
| localized_strings->SetString("searchPageHelpTitle", |
| l10n_util::GetStringFUTF16(IDS_OPTIONS_SEARCH_PAGE_HELP_TITLE, |
| l10n_util::GetStringUTF16(IDS_PRODUCT_NAME))); |
| localized_strings->SetString("searchPageHelpURL", |
| chrome::kSettingsSearchHelpURL); |
| |
| // About |
| localized_strings->SetString("aboutButton", |
| l10n_util::GetStringUTF16(IDS_ABOUT_BUTTON)); |
| |
| // Common |
| localized_strings->SetString("ok", |
| l10n_util::GetStringUTF16(IDS_OK)); |
| localized_strings->SetString("cancel", |
| l10n_util::GetStringUTF16(IDS_CANCEL)); |
| localized_strings->SetString("learnMore", |
| l10n_util::GetStringUTF16(IDS_LEARN_MORE)); |
| localized_strings->SetString("close", |
| l10n_util::GetStringUTF16(IDS_CLOSE)); |
| localized_strings->SetString("done", |
| l10n_util::GetStringUTF16(IDS_DONE)); |
| localized_strings->SetString("deletableItemDeleteButtonTitle", |
| l10n_util::GetStringUTF16(IDS_OPTIONS_DELETABLE_ITEM_DELETE_BUTTON)); |
| } |
| |
| void CoreOptionsHandler::Uninitialize() { |
| std::string last_pref; |
| for (PreferenceCallbackMap::const_iterator iter = pref_callback_map_.begin(); |
| iter != pref_callback_map_.end(); |
| ++iter) { |
| if (last_pref != iter->first) { |
| StopObservingPref(iter->first); |
| last_pref = iter->first; |
| } |
| } |
| } |
| |
| void CoreOptionsHandler::OnPreferenceChanged(PrefService* service, |
| const std::string& pref_name) { |
| if (pref_name == prefs::kClearPluginLSODataEnabled) { |
| // This preference is stored in Local State, not in the user preferences. |
| UpdateClearPluginLSOData(); |
| return; |
| } |
| if (pref_name == prefs::kPepperFlashSettingsEnabled) { |
| UpdatePepperFlashSettingsEnabled(); |
| return; |
| } |
| NotifyPrefChanged(pref_name, std::string()); |
| } |
| |
| void CoreOptionsHandler::RegisterMessages() { |
| registrar_.Init(Profile::FromWebUI(web_ui())->GetPrefs()); |
| local_state_registrar_.Init(g_browser_process->local_state()); |
| |
| web_ui()->RegisterMessageCallback("coreOptionsInitialize", |
| base::Bind(&CoreOptionsHandler::HandleInitialize, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback("onFinishedLoadingOptions", |
| base::Bind(&CoreOptionsHandler::OnFinishedLoading, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback("fetchPrefs", |
| base::Bind(&CoreOptionsHandler::HandleFetchPrefs, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback("observePrefs", |
| base::Bind(&CoreOptionsHandler::HandleObservePrefs, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback("setBooleanPref", |
| base::Bind(&CoreOptionsHandler::HandleSetBooleanPref, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback("setIntegerPref", |
| base::Bind(&CoreOptionsHandler::HandleSetIntegerPref, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback("setDoublePref", |
| base::Bind(&CoreOptionsHandler::HandleSetDoublePref, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback("setStringPref", |
| base::Bind(&CoreOptionsHandler::HandleSetStringPref, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback("setURLPref", |
| base::Bind(&CoreOptionsHandler::HandleSetURLPref, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback("setListPref", |
| base::Bind(&CoreOptionsHandler::HandleSetListPref, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback("clearPref", |
| base::Bind(&CoreOptionsHandler::HandleClearPref, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback("coreOptionsUserMetricsAction", |
| base::Bind(&CoreOptionsHandler::HandleUserMetricsAction, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback("disableExtension", |
| base::Bind(&CoreOptionsHandler::HandleDisableExtension, |
| base::Unretained(this))); |
| } |
| |
| void CoreOptionsHandler::HandleInitialize(const base::ListValue* args) { |
| DCHECK(handlers_host_); |
| handlers_host_->InitializeHandlers(); |
| } |
| |
| void CoreOptionsHandler::OnFinishedLoading(const base::ListValue* args) { |
| DCHECK(handlers_host_); |
| handlers_host_->OnFinishedLoading(); |
| } |
| |
| base::Value* CoreOptionsHandler::FetchPref(const std::string& pref_name) { |
| return CreateValueForPref(pref_name, std::string()); |
| } |
| |
| void CoreOptionsHandler::ObservePref(const std::string& pref_name) { |
| if (g_browser_process->local_state()->FindPreference(pref_name)) { |
| local_state_registrar_.Add( |
| pref_name, |
| base::Bind(&CoreOptionsHandler::OnPreferenceChanged, |
| base::Unretained(this), |
| local_state_registrar_.prefs())); |
| } |
| // TODO(pneubeck): change this to if/else once kProxy is only used as a user |
| // pref. Currently, it is both a user and a local state pref. |
| if (Profile::FromWebUI(web_ui())->GetPrefs()->FindPreference(pref_name)) { |
| registrar_.Add( |
| pref_name, |
| base::Bind(&CoreOptionsHandler::OnPreferenceChanged, |
| base::Unretained(this), |
| registrar_.prefs())); |
| } |
| } |
| |
| void CoreOptionsHandler::StopObservingPref(const std::string& pref_name) { |
| if (g_browser_process->local_state()->FindPreference(pref_name)) |
| local_state_registrar_.Remove(pref_name); |
| else |
| registrar_.Remove(pref_name); |
| } |
| |
| void CoreOptionsHandler::SetPref(const std::string& pref_name, |
| const base::Value* value, |
| const std::string& metric) { |
| PrefService* pref_service = FindServiceForPref(pref_name); |
| PrefChangeFilterMap::iterator iter = pref_change_filters_.find(pref_name); |
| if (iter != pref_change_filters_.end()) { |
| // Also check if the pref is user modifiable (don't even try to run the |
| // filter function if the user is not allowed to change the pref). |
| const PrefService::Preference* pref = |
| pref_service->FindPreference(pref_name); |
| if ((pref && !pref->IsUserModifiable()) || !iter->second.Run(value)) { |
| // Reject the change; remind the page of the true value. |
| NotifyPrefChanged(pref_name, std::string()); |
| return; |
| } |
| } |
| |
| switch (value->GetType()) { |
| case base::Value::Type::BOOLEAN: |
| case base::Value::Type::INTEGER: |
| case base::Value::Type::DOUBLE: |
| case base::Value::Type::STRING: |
| case base::Value::Type::LIST: |
| pref_service->Set(pref_name, *value); |
| break; |
| |
| default: |
| NOTREACHED(); |
| return; |
| } |
| |
| ProcessUserMetric(value, metric); |
| } |
| |
| void CoreOptionsHandler::ClearPref(const std::string& pref_name, |
| const std::string& metric) { |
| PrefService* pref_service = FindServiceForPref(pref_name); |
| pref_service->ClearPref(pref_name); |
| |
| if (!metric.empty()) |
| base::RecordComputedAction(metric); |
| } |
| |
| void CoreOptionsHandler::ProcessUserMetric(const base::Value* value, |
| const std::string& metric) { |
| if (metric.empty()) |
| return; |
| |
| std::string metric_string = metric; |
| if (value->IsType(base::Value::Type::BOOLEAN)) { |
| bool bool_value; |
| CHECK(value->GetAsBoolean(&bool_value)); |
| metric_string += bool_value ? "_Enable" : "_Disable"; |
| } |
| |
| base::RecordComputedAction(metric_string); |
| } |
| |
| void CoreOptionsHandler::NotifyPrefChanged( |
| const std::string& pref_name, |
| const std::string& controlling_pref_name) { |
| std::unique_ptr<base::Value> value( |
| CreateValueForPref(pref_name, controlling_pref_name)); |
| DispatchPrefChangeNotification(pref_name, std::move(value)); |
| } |
| |
| void CoreOptionsHandler::DispatchPrefChangeNotification( |
| const std::string& name, |
| std::unique_ptr<base::Value> value) { |
| std::pair<PreferenceCallbackMap::const_iterator, |
| PreferenceCallbackMap::const_iterator> range = |
| pref_callback_map_.equal_range(name); |
| base::ListValue result_value; |
| result_value.AppendString(name); |
| result_value.Append(std::move(value)); |
| for (PreferenceCallbackMap::const_iterator iter = range.first; |
| iter != range.second; ++iter) { |
| const std::string& callback_function = iter->second; |
| web_ui()->CallJavascriptFunctionUnsafe(callback_function, result_value); |
| } |
| } |
| |
| base::Value* CoreOptionsHandler::CreateValueForPref( |
| const std::string& pref_name, |
| const std::string& controlling_pref_name) { |
| const PrefService* pref_service = FindServiceForPref(pref_name); |
| const PrefService::Preference* pref = |
| pref_service->FindPreference(pref_name); |
| if (!pref) { |
| NOTREACHED(); |
| return new base::Value(); |
| } |
| const PrefService::Preference* controlling_pref = |
| pref_service->FindPreference(controlling_pref_name); |
| if (!controlling_pref) |
| controlling_pref = pref; |
| |
| base::DictionaryValue* dict = new base::DictionaryValue; |
| dict->Set("value", pref->GetValue()->DeepCopy()); |
| if (controlling_pref->IsManaged()) { |
| dict->SetString("controlledBy", "policy"); |
| } else if (controlling_pref->IsExtensionControlled() && |
| CanSetExtensionControlledPrefValue(controlling_pref)) { |
| Profile* profile = Profile::FromWebUI(web_ui()); |
| ExtensionPrefValueMap* extension_pref_value_map = |
| ExtensionPrefValueMapFactory::GetForBrowserContext(profile); |
| std::string extension_id = |
| extension_pref_value_map->GetExtensionControllingPref( |
| controlling_pref->name()); |
| |
| const extensions::Extension* extension = |
| extensions::ExtensionRegistry::Get(profile)->GetExtensionById( |
| extension_id, extensions::ExtensionRegistry::EVERYTHING); |
| if (extension) { |
| dict->SetString("controlledBy", "extension"); |
| dict->Set("extension", |
| extensions::util::GetExtensionInfo(extension).release()); |
| } |
| } else if (controlling_pref->IsRecommended()) { |
| dict->SetString("controlledBy", "recommended"); |
| } |
| |
| const base::Value* recommended_value = |
| controlling_pref->GetRecommendedValue(); |
| if (recommended_value) |
| dict->Set("recommendedValue", recommended_value->DeepCopy()); |
| dict->SetBoolean("disabled", !controlling_pref->IsUserModifiable()); |
| return dict; |
| } |
| |
| PrefService* CoreOptionsHandler::FindServiceForPref( |
| const std::string& pref_name) { |
| // Proxy is a peculiar case: on ChromeOS, settings exist in both user |
| // prefs and local state, but chrome://settings should affect only user prefs. |
| // Elsewhere the proxy settings are stored in local state. |
| // See http://crbug.com/157147 |
| PrefService* user_prefs = Profile::FromWebUI(web_ui())->GetPrefs(); |
| if (pref_name == proxy_config::prefs::kProxy) |
| #if defined(OS_CHROMEOS) |
| return user_prefs; |
| #else |
| return g_browser_process->local_state(); |
| #endif |
| |
| // Find which PrefService contains the given pref. Pref names should not |
| // be duplicated across services, however if they are, prefer the user's |
| // prefs. |
| if (user_prefs->FindPreference(pref_name)) |
| return user_prefs; |
| |
| if (g_browser_process->local_state()->FindPreference(pref_name)) |
| return g_browser_process->local_state(); |
| |
| return user_prefs; |
| } |
| |
| void CoreOptionsHandler::HandleFetchPrefs(const base::ListValue* args) { |
| // First param is name of callback function, so, there needs to be at least |
| // one more element for the actual preference identifier. |
| DCHECK_GE(static_cast<int>(args->GetSize()), 2); |
| |
| // Get callback JS function name. |
| const base::Value* callback; |
| if (!args->Get(0, &callback) || !callback->IsType(base::Value::Type::STRING)) |
| return; |
| |
| base::string16 callback_function; |
| if (!callback->GetAsString(&callback_function)) |
| return; |
| |
| // Get the list of name for prefs to build the response dictionary. |
| base::DictionaryValue result_value; |
| const base::Value* list_member; |
| |
| for (size_t i = 1; i < args->GetSize(); i++) { |
| if (!args->Get(i, &list_member)) |
| break; |
| |
| if (!list_member->IsType(base::Value::Type::STRING)) |
| continue; |
| |
| std::string pref_name; |
| if (!list_member->GetAsString(&pref_name)) |
| continue; |
| |
| result_value.Set(pref_name, FetchPref(pref_name)); |
| } |
| web_ui()->CallJavascriptFunctionUnsafe(base::UTF16ToASCII(callback_function), |
| result_value); |
| } |
| |
| void CoreOptionsHandler::HandleObservePrefs(const base::ListValue* args) { |
| // First param is name is JS callback function name, the rest are pref |
| // identifiers that we are observing. |
| DCHECK_GE(static_cast<int>(args->GetSize()), 2); |
| |
| // Get preference change callback function name. |
| std::string callback_func_name; |
| if (!args->GetString(0, &callback_func_name)) |
| return; |
| |
| // Get all other parameters - pref identifiers. |
| for (size_t i = 1; i < args->GetSize(); i++) { |
| const base::Value* list_member; |
| if (!args->Get(i, &list_member)) |
| break; |
| |
| // Just ignore bad pref identifiers for now. |
| std::string pref_name; |
| if (!list_member->IsType(base::Value::Type::STRING) || |
| !list_member->GetAsString(&pref_name)) |
| continue; |
| |
| if (pref_callback_map_.find(pref_name) == pref_callback_map_.end()) |
| ObservePref(pref_name); |
| |
| pref_callback_map_.insert( |
| PreferenceCallbackMap::value_type(pref_name, callback_func_name)); |
| } |
| } |
| |
| void CoreOptionsHandler::HandleSetBooleanPref(const base::ListValue* args) { |
| HandleSetPref(args, TYPE_BOOLEAN); |
| } |
| |
| void CoreOptionsHandler::HandleSetIntegerPref(const base::ListValue* args) { |
| HandleSetPref(args, TYPE_INTEGER); |
| } |
| |
| void CoreOptionsHandler::HandleSetDoublePref(const base::ListValue* args) { |
| HandleSetPref(args, TYPE_DOUBLE); |
| } |
| |
| void CoreOptionsHandler::HandleSetStringPref(const base::ListValue* args) { |
| HandleSetPref(args, TYPE_STRING); |
| } |
| |
| void CoreOptionsHandler::HandleSetURLPref(const base::ListValue* args) { |
| HandleSetPref(args, TYPE_URL); |
| } |
| |
| void CoreOptionsHandler::HandleSetListPref(const base::ListValue* args) { |
| HandleSetPref(args, TYPE_LIST); |
| } |
| |
| void CoreOptionsHandler::HandleSetPref(const base::ListValue* args, |
| PrefType type) { |
| DCHECK_GT(static_cast<int>(args->GetSize()), 1); |
| |
| std::string pref_name; |
| if (!args->GetString(0, &pref_name)) |
| return; |
| |
| const base::Value* value; |
| if (!args->Get(1, &value)) |
| return; |
| |
| std::unique_ptr<base::Value> temp_value; |
| |
| switch (type) { |
| case TYPE_BOOLEAN: |
| if (!value->IsType(base::Value::Type::BOOLEAN)) { |
| NOTREACHED(); |
| return; |
| } |
| break; |
| case TYPE_INTEGER: { |
| // In JS all numbers are doubles. |
| double double_value; |
| if (!value->GetAsDouble(&double_value)) { |
| NOTREACHED(); |
| return; |
| } |
| int int_value = static_cast<int>(double_value); |
| temp_value.reset(new base::Value(int_value)); |
| value = temp_value.get(); |
| break; |
| } |
| case TYPE_DOUBLE: |
| if (!value->IsType(base::Value::Type::DOUBLE)) { |
| NOTREACHED(); |
| return; |
| } |
| break; |
| case TYPE_STRING: |
| if (!value->IsType(base::Value::Type::STRING)) { |
| NOTREACHED(); |
| return; |
| } |
| break; |
| case TYPE_URL: { |
| std::string original; |
| if (!value->GetAsString(&original)) { |
| NOTREACHED(); |
| return; |
| } |
| GURL fixed = url_formatter::FixupURL(original, std::string()); |
| temp_value.reset(new base::Value(fixed.spec())); |
| value = temp_value.get(); |
| break; |
| } |
| case TYPE_LIST: { |
| // In case we have a List pref we got a JSON string. |
| std::string json_string; |
| if (!value->GetAsString(&json_string)) { |
| NOTREACHED(); |
| return; |
| } |
| temp_value = base::JSONReader::Read(json_string); |
| value = temp_value.get(); |
| if (!value || !value->IsType(base::Value::Type::LIST)) { |
| NOTREACHED(); |
| return; |
| } |
| break; |
| } |
| default: |
| NOTREACHED(); |
| } |
| |
| std::string metric; |
| if (args->GetSize() > 2 && !args->GetString(2, &metric)) |
| LOG(WARNING) << "Invalid metric parameter: " << pref_name; |
| SetPref(pref_name, value, metric); |
| } |
| |
| void CoreOptionsHandler::HandleClearPref(const base::ListValue* args) { |
| DCHECK_GT(static_cast<int>(args->GetSize()), 0); |
| |
| std::string pref_name; |
| if (!args->GetString(0, &pref_name)) |
| return; |
| |
| std::string metric; |
| if (args->GetSize() > 1) { |
| if (!args->GetString(1, &metric)) |
| NOTREACHED(); |
| } |
| |
| ClearPref(pref_name, metric); |
| } |
| |
| void CoreOptionsHandler::HandleUserMetricsAction(const base::ListValue* args) { |
| std::string metric = base::UTF16ToUTF8(ExtractStringValue(args)); |
| if (!metric.empty()) |
| base::RecordComputedAction(metric); |
| } |
| |
| void CoreOptionsHandler::HandleDisableExtension(const base::ListValue* args) { |
| std::string extension_id; |
| if (args->GetString(0, &extension_id)) { |
| ExtensionService* extension_service = extensions::ExtensionSystem::Get( |
| Profile::FromWebUI(web_ui()))->extension_service(); |
| DCHECK(extension_service); |
| extension_service->DisableExtension( |
| extension_id, extensions::Extension::DISABLE_USER_ACTION); |
| } else { |
| NOTREACHED(); |
| } |
| } |
| |
| void CoreOptionsHandler::UpdateClearPluginLSOData() { |
| base::Value enabled(plugin_status_pref_setter_.IsClearPluginLSODataEnabled()); |
| web_ui()->CallJavascriptFunctionUnsafe( |
| "options.OptionsPage.setClearPluginLSODataEnabled", enabled); |
| } |
| |
| void CoreOptionsHandler::UpdatePepperFlashSettingsEnabled() { |
| base::Value enabled( |
| plugin_status_pref_setter_.IsPepperFlashSettingsEnabled()); |
| web_ui()->CallJavascriptFunctionUnsafe( |
| "options.OptionsPage.setPepperFlashSettingsEnabled", enabled); |
| } |
| |
| bool CoreOptionsHandler::IsUserUnsupervised(const base::Value* to_value) { |
| return !Profile::FromWebUI(web_ui())->IsSupervised(); |
| } |
| |
| } // namespace options |