Index: chrome/browser/extensions/api/settings_private/prefs_util.cc |
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc |
index c22a846d42df191640f6f54d4a4e3c1d9435221d..11440853969ed5e251cdfb3a77add1eeebdeddef 100644 |
--- a/chrome/browser/extensions/api/settings_private/prefs_util.cc |
+++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc |
@@ -2,23 +2,40 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+#include "base/json/json_reader.h" |
#include "base/prefs/pref_service.h" |
#include "chrome/browser/browser_process.h" |
#include "chrome/browser/extensions/api/settings_private/prefs_util.h" |
+#include "chrome/browser/extensions/chrome_extension_function.h" |
#include "chrome/browser/profiles/profile.h" |
#include "chrome/common/pref_names.h" |
+#include "components/url_fixer/url_fixer.h" |
+ |
+#if defined(OS_CHROMEOS) |
+#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" |
+#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" |
+#include "chrome/browser/chromeos/settings/cros_settings.h" |
+#endif |
namespace extensions { |
namespace settings_private = api::settings_private; |
-namespace prefs_util { |
+PrefsUtil::PrefsUtil(Profile* profile) : profile_(profile) { |
+} |
-const TypedPrefMap& GetWhitelistedKeys() { |
- static TypedPrefMap* s_whitelist = nullptr; |
+PrefsUtil::~PrefsUtil() { |
+} |
+ |
+#if defined(OS_CHROMEOS) |
+using CrosSettings = chromeos::CrosSettings; |
+#endif |
+ |
+const PrefsUtil::TypedPrefMap& PrefsUtil::GetWhitelistedKeys() { |
+ static PrefsUtil::TypedPrefMap* s_whitelist = nullptr; |
if (s_whitelist) |
return *s_whitelist; |
- s_whitelist = new TypedPrefMap(); |
+ s_whitelist = new PrefsUtil::TypedPrefMap(); |
(*s_whitelist)["browser.show_home_button"] = |
settings_private::PrefType::PREF_TYPE_BOOLEAN; |
(*s_whitelist)["bookmark_bar.show_on_all_tabs"] = |
@@ -30,6 +47,14 @@ const TypedPrefMap& GetWhitelistedKeys() { |
(*s_whitelist)["homepage"] = settings_private::PrefType::PREF_TYPE_URL; |
#if defined(OS_CHROMEOS) |
+ (*s_whitelist)["cros.accounts.allowBWSI"] = |
+ settings_private::PrefType::PREF_TYPE_BOOLEAN; |
+ (*s_whitelist)["cros.accounts.supervisedUsersEnabled"] = |
+ settings_private::PrefType::PREF_TYPE_BOOLEAN; |
+ (*s_whitelist)["cros.accounts.showUserNamesOnSignIn"] = |
+ settings_private::PrefType::PREF_TYPE_BOOLEAN; |
+ (*s_whitelist)["cros.accounts.allowGuest"] = |
+ settings_private::PrefType::PREF_TYPE_BOOLEAN; |
(*s_whitelist)["settings.accessibility"] = |
settings_private::PrefType::PREF_TYPE_BOOLEAN; |
(*s_whitelist)["settings.a11y.autoclick"] = |
@@ -57,38 +82,55 @@ const TypedPrefMap& GetWhitelistedKeys() { |
return *s_whitelist; |
} |
-scoped_ptr<api::settings_private::PrefObject> GetPref(Profile* profile, |
- const std::string& name) { |
- scoped_ptr<api::settings_private::PrefObject> pref_object( |
- new api::settings_private::PrefObject()); |
- |
- PrefService* pref_service = FindServiceForPref(profile, name); |
- const PrefService::Preference* pref = pref_service->FindPreference(name); |
- if (!pref) |
- return pref_object.Pass(); |
- |
- pref_object->key = pref->name(); |
- switch (pref->GetType()) { |
+api::settings_private::PrefType PrefsUtil::GetType(const std::string& name, |
+ base::Value::Type type) { |
+ switch (type) { |
case base::Value::Type::TYPE_BOOLEAN: |
- pref_object->type = api::settings_private::PrefType::PREF_TYPE_BOOLEAN; |
- break; |
+ return api::settings_private::PrefType::PREF_TYPE_BOOLEAN; |
case base::Value::Type::TYPE_INTEGER: |
case base::Value::Type::TYPE_DOUBLE: |
- pref_object->type = api::settings_private::PrefType::PREF_TYPE_NUMBER; |
- break; |
+ return api::settings_private::PrefType::PREF_TYPE_NUMBER; |
case base::Value::Type::TYPE_STRING: |
- pref_object->type = |
- IsPrefTypeURL(name) |
- ? api::settings_private::PrefType::PREF_TYPE_URL |
- : api::settings_private::PrefType::PREF_TYPE_STRING; |
- break; |
+ return IsPrefTypeURL(name) |
+ ? api::settings_private::PrefType::PREF_TYPE_URL |
+ : api::settings_private::PrefType::PREF_TYPE_STRING; |
case base::Value::Type::TYPE_LIST: |
- pref_object->type = api::settings_private::PrefType::PREF_TYPE_LIST; |
- break; |
+ return api::settings_private::PrefType::PREF_TYPE_LIST; |
default: |
- break; |
+ return api::settings_private::PrefType::PREF_TYPE_NONE; |
} |
+} |
+ |
+scoped_ptr<api::settings_private::PrefObject> PrefsUtil::GetCrosSettingsPref( |
+ const std::string& name) { |
+ scoped_ptr<api::settings_private::PrefObject> pref_object( |
+ new api::settings_private::PrefObject()); |
+ |
+#if defined(OS_CHROMEOS) |
+ const base::Value* value = CrosSettings::Get()->GetPref(name); |
+ pref_object->key = name; |
+ pref_object->type = GetType(name, value->GetType()); |
Oren Blasberg
2015/06/06 00:42:55
Somehow, this line segfaults if name is 'cros.acco
stevenjb
2015/06/06 00:48:17
Is value maybe NULL?
Oren Blasberg
2015/06/06 01:02:11
Whoops, you're right, it's null.
However, I don't
|
+ pref_object->value.reset(value->DeepCopy()); |
+#endif |
+ |
+ return pref_object.Pass(); |
+} |
+scoped_ptr<api::settings_private::PrefObject> PrefsUtil::GetPref( |
+ const std::string& name) { |
+ scoped_ptr<api::settings_private::PrefObject> pref_object( |
+ new api::settings_private::PrefObject()); |
+ |
+ if (IsCrosSetting(name)) |
+ return GetCrosSettingsPref(name); |
+ |
+ PrefService* pref_service = FindServiceForPref(name); |
+ const PrefService::Preference* pref = pref_service->FindPreference(name); |
+ if (!pref) |
+ return pref_object.Pass(); |
+ |
+ pref_object->key = pref->name(); |
+ pref_object->type = GetType(name, pref->GetType()); |
pref_object->value.reset(pref->GetValue()->DeepCopy()); |
if (pref->IsManaged()) { |
@@ -104,7 +146,7 @@ scoped_ptr<api::settings_private::PrefObject> GetPref(Profile* profile, |
POLICY_ENFORCEMENT_RECOMMENDED |
: api::settings_private::PolicyEnforcement:: |
POLICY_ENFORCEMENT_ENFORCED; |
- } else if (!IsPrefUserModifiable(profile, name)) { |
+ } else if (!IsPrefUserModifiable(name)) { |
pref_object->policy_source = |
api::settings_private::PolicySource::POLICY_SOURCE_USER; |
pref_object->policy_enforcement = |
@@ -114,7 +156,120 @@ scoped_ptr<api::settings_private::PrefObject> GetPref(Profile* profile, |
return pref_object.Pass(); |
} |
-bool IsPrefTypeURL(const std::string& pref_name) { |
+bool PrefsUtil::SetPref(const std::string& pref_name, |
+ const base::Value* value) { |
+ if (IsCrosSetting(pref_name)) |
+ return SetCrosSettingsPref(pref_name, value); |
+ |
+ PrefService* pref_service = FindServiceForPref(pref_name); |
+ |
+ if (!IsPrefUserModifiable(pref_name)) |
+ return false; |
+ |
+ const PrefService::Preference* pref = |
+ pref_service->FindPreference(pref_name.c_str()); |
+ if (!pref) |
+ return false; |
+ |
+ DCHECK_EQ(pref->GetType(), value->GetType()); |
+ |
+ scoped_ptr<base::Value> temp_value; |
+ |
+ switch (pref->GetType()) { |
+ case base::Value::TYPE_INTEGER: { |
+ // In JS all numbers are doubles. |
+ double double_value; |
+ if (!value->GetAsDouble(&double_value)) |
+ return false; |
+ |
+ int int_value = static_cast<int>(double_value); |
+ temp_value.reset(new base::FundamentalValue(int_value)); |
+ value = temp_value.get(); |
+ break; |
+ } |
+ case base::Value::TYPE_STRING: { |
+ std::string original; |
+ if (!value->GetAsString(&original)) |
+ return false; |
+ |
+ if (IsPrefTypeURL(pref_name)) { |
+ GURL fixed = url_fixer::FixupURL(original, std::string()); |
+ temp_value.reset(new base::StringValue(fixed.spec())); |
+ value = temp_value.get(); |
+ } |
+ break; |
+ } |
+ case base::Value::TYPE_LIST: { |
+ // In case we have a List pref we got a JSON string. |
+ std::string json_string; |
+ if (!value->GetAsString(&json_string)) |
+ return false; |
+ |
+ temp_value.reset(base::JSONReader::DeprecatedRead(json_string)); |
+ value = temp_value.get(); |
+ if (!value->IsType(base::Value::TYPE_LIST)) |
+ return false; |
+ |
+ break; |
+ } |
+ case base::Value::TYPE_BOOLEAN: |
+ case base::Value::TYPE_DOUBLE: |
+ break; |
+ default: |
+ return false; |
+ } |
+ |
+ // TODO(orenb): Process setting metrics here and in the CrOS setting method |
+ // too (like "ProcessUserMetric" in CoreOptionsHandler). |
+ pref_service->Set(pref_name.c_str(), *value); |
+ return true; |
+} |
+ |
+bool PrefsUtil::SetCrosSettingsPref(const std::string& pref_name, |
+ const base::Value* value) { |
+#if defined(OS_CHROMEOS) |
+ chromeos::OwnerSettingsServiceChromeOS* service = |
+ chromeos::OwnerSettingsServiceChromeOSFactory::GetForBrowserContext( |
+ profile_); |
+ |
+ // Returns false if not the owner, for settings requiring owner. |
+ if (service && service->HandlesSetting(pref_name)) |
+ return service->Set(pref_name, *value); |
+ |
+ chromeos::CrosSettings::Get()->Set(pref_name, *value); |
+ return true; |
+#else |
+ return false; |
+#endif |
+} |
+ |
+bool PrefsUtil::AppendToListCrosSetting(const std::string& setting, |
+ const base::Value& value) { |
+#if defined(OS_CHROMEOS) |
+ chromeos::OwnerSettingsServiceChromeOS* service = |
+ chromeos::OwnerSettingsServiceChromeOSFactory::GetForBrowserContext( |
+ profile_); |
+ DCHECK(service); |
+ return service->AppendToList(setting, value); |
+#else |
+ return false; |
+#endif |
+} |
+ |
+bool PrefsUtil::RemoveFromListCrosSetting(const std::string& setting, |
+ const base::Value& value) { |
+#if defined(OS_CHROMEOS) |
+ chromeos::OwnerSettingsServiceChromeOS* service = |
+ chromeos::OwnerSettingsServiceChromeOSFactory::GetForBrowserContext( |
+ profile_); |
+ DCHECK(service); |
+ return service->RemoveFromList(setting, value); |
+#else |
+ return false; |
+#endif |
+} |
+ |
+bool PrefsUtil::IsPrefTypeURL(const std::string& pref_name) { |
settings_private::PrefType pref_type = |
settings_private::PrefType::PREF_TYPE_NONE; |
@@ -126,24 +281,23 @@ bool IsPrefTypeURL(const std::string& pref_name) { |
return pref_type == settings_private::PrefType::PREF_TYPE_URL; |
} |
-bool IsPrefUserModifiable(Profile* profile, const std::string& pref_name) { |
+bool PrefsUtil::IsPrefUserModifiable(const std::string& pref_name) { |
if (pref_name != prefs::kBrowserGuestModeEnabled && |
pref_name != prefs::kBrowserAddPersonEnabled) { |
return true; |
} |
- PrefService* pref_service = profile->GetPrefs(); |
+ PrefService* pref_service = profile_->GetPrefs(); |
const PrefService::Preference* pref = |
pref_service->FindPreference(pref_name.c_str()); |
- if (!pref || !pref->IsUserModifiable() || profile->IsSupervised()) |
+ if (!pref || !pref->IsUserModifiable() || profile_->IsSupervised()) |
return false; |
return true; |
} |
-PrefService* FindServiceForPref(Profile* profile, |
- const std::string& pref_name) { |
- PrefService* user_prefs = profile->GetPrefs(); |
+PrefService* PrefsUtil::FindServiceForPref(const std::string& pref_name) { |
+ PrefService* user_prefs = profile_->GetPrefs(); |
// Proxy is a peculiar case: on ChromeOS, settings exist in both user |
// prefs and local state, but chrome://settings should affect only user prefs. |
@@ -170,6 +324,12 @@ PrefService* FindServiceForPref(Profile* profile, |
return user_prefs; |
} |
-} // namespace prefs_util |
+bool PrefsUtil::IsCrosSetting(const std::string& pref_name) { |
+#if defined(OS_CHROMEOS) |
+ return CrosSettings::Get()->IsCrosSettings(pref_name); |
+#else |
+ return false; |
+#endif |
+} |
} // namespace extensions |