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 fd80f7ed5b92e870976f2ec2350b64b8b9f6b4a4..d065292f99ece1d93ec5a05e359d3f8ef16ed7c3 100644 |
--- a/chrome/browser/extensions/api/settings_private/prefs_util.cc |
+++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc |
@@ -2,30 +2,52 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+#include "chrome/browser/extensions/api/settings_private/prefs_util.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/proxy_config/proxy_config_pref_names.h" |
#include "components/url_formatter/url_fixer.h" |
+#include "extensions/browser/extension_pref_value_map.h" |
+#include "extensions/browser/extension_pref_value_map_factory.h" |
+#include "extensions/browser/extension_registry.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/policy/browser_policy_connector_chromeos.h" |
+#include "chrome/browser/chromeos/profiles/profile_helper.h" |
#include "chrome/browser/chromeos/settings/cros_settings.h" |
+#include "chromeos/settings/cros_settings_names.h" |
+#endif |
+ |
+namespace { |
+ |
+#if defined(OS_CHROMEOS) |
+bool IsPrivilegedCrosSetting(const std::string& pref_name) { |
+ if (!chromeos::CrosSettings::IsCrosSettings(pref_name)) |
+ return false; |
+ // kSystemTimezone should be changeable by all users. |
+ if (pref_name == chromeos::kSystemTimezone) |
+ return false; |
+ // All other Cros settings are considered privileged and are either policy |
+ // controlled or owner controlled. |
+ return true; |
+} |
#endif |
+} // namespace |
+ |
namespace extensions { |
namespace settings_private = api::settings_private; |
-PrefsUtil::PrefsUtil(Profile* profile) : profile_(profile) { |
-} |
+PrefsUtil::PrefsUtil(Profile* profile) : profile_(profile) {} |
-PrefsUtil::~PrefsUtil() { |
-} |
+PrefsUtil::~PrefsUtil() {} |
#if defined(OS_CHROMEOS) |
using CrosSettings = chromeos::CrosSettings; |
@@ -110,32 +132,32 @@ const PrefsUtil::TypedPrefMap& PrefsUtil::GetWhitelistedKeys() { |
return *s_whitelist; |
} |
-api::settings_private::PrefType PrefsUtil::GetType(const std::string& name, |
- base::Value::Type type) { |
+settings_private::PrefType PrefsUtil::GetType(const std::string& name, |
+ base::Value::Type type) { |
switch (type) { |
case base::Value::Type::TYPE_BOOLEAN: |
- return api::settings_private::PrefType::PREF_TYPE_BOOLEAN; |
+ return settings_private::PrefType::PREF_TYPE_BOOLEAN; |
case base::Value::Type::TYPE_INTEGER: |
case base::Value::Type::TYPE_DOUBLE: |
- return api::settings_private::PrefType::PREF_TYPE_NUMBER; |
+ return settings_private::PrefType::PREF_TYPE_NUMBER; |
case base::Value::Type::TYPE_STRING: |
- return IsPrefTypeURL(name) |
- ? api::settings_private::PrefType::PREF_TYPE_URL |
- : api::settings_private::PrefType::PREF_TYPE_STRING; |
+ return IsPrefTypeURL(name) ? settings_private::PrefType::PREF_TYPE_URL |
+ : settings_private::PrefType::PREF_TYPE_STRING; |
case base::Value::Type::TYPE_LIST: |
- return api::settings_private::PrefType::PREF_TYPE_LIST; |
+ return settings_private::PrefType::PREF_TYPE_LIST; |
default: |
- return api::settings_private::PrefType::PREF_TYPE_NONE; |
+ return settings_private::PrefType::PREF_TYPE_NONE; |
} |
} |
-scoped_ptr<api::settings_private::PrefObject> PrefsUtil::GetCrosSettingsPref( |
+scoped_ptr<settings_private::PrefObject> PrefsUtil::GetCrosSettingsPref( |
const std::string& name) { |
- scoped_ptr<api::settings_private::PrefObject> pref_object( |
- new api::settings_private::PrefObject()); |
+ scoped_ptr<settings_private::PrefObject> pref_object( |
+ new settings_private::PrefObject()); |
#if defined(OS_CHROMEOS) |
const base::Value* value = CrosSettings::Get()->GetPref(name); |
+ DCHECK(value); |
michaelpg
2015/09/17 02:19:25
value shouldn't be NULL, but it could be, so a DCH
stevenjb
2015/09/17 17:33:31
GetPref() already has a NOTREACHED if it returns n
|
pref_object->key = name; |
pref_object->type = GetType(name, value->GetType()); |
pref_object->value.reset(value->DeepCopy()); |
@@ -144,40 +166,88 @@ scoped_ptr<api::settings_private::PrefObject> PrefsUtil::GetCrosSettingsPref( |
return pref_object.Pass(); |
} |
-scoped_ptr<api::settings_private::PrefObject> PrefsUtil::GetPref( |
+scoped_ptr<settings_private::PrefObject> PrefsUtil::GetPref( |
const std::string& name) { |
- if (IsCrosSetting(name)) |
- return GetCrosSettingsPref(name); |
+ const PrefService::Preference* pref = nullptr; |
+ scoped_ptr<settings_private::PrefObject> pref_object; |
+ if (IsCrosSetting(name)) { |
+ pref_object = GetCrosSettingsPref(name); |
+ } else { |
+ PrefService* pref_service = FindServiceForPref(name); |
+ pref = pref_service->FindPreference(name); |
+ if (!pref) |
+ return nullptr; |
+ pref_object.reset(new settings_private::PrefObject()); |
+ pref_object->key = pref->name(); |
+ pref_object->type = GetType(name, pref->GetType()); |
+ pref_object->value.reset(pref->GetValue()->DeepCopy()); |
+ } |
- PrefService* pref_service = FindServiceForPref(name); |
- const PrefService::Preference* pref = pref_service->FindPreference(name); |
- if (!pref) |
- return nullptr; |
- |
- scoped_ptr<api::settings_private::PrefObject> pref_object( |
- new api::settings_private::PrefObject()); |
- pref_object->key = pref->name(); |
- pref_object->type = GetType(name, pref->GetType()); |
- pref_object->value.reset(pref->GetValue()->DeepCopy()); |
- |
- if (pref->IsManaged()) { |
- if (pref->IsManagedByCustodian()) { |
- pref_object->policy_source = |
- api::settings_private::PolicySource::POLICY_SOURCE_DEVICE; |
- } else { |
- pref_object->policy_source = |
- api::settings_private::PolicySource::POLICY_SOURCE_USER; |
- } |
+#if defined(OS_CHROMEOS) |
+ if (IsPrefPrimaryUserControlled(name)) { |
+ pref_object->policy_source = |
+ settings_private::PolicySource::POLICY_SOURCE_PRIMARY_USER; |
pref_object->policy_enforcement = |
- pref->IsRecommended() ? api::settings_private::PolicyEnforcement:: |
- POLICY_ENFORCEMENT_RECOMMENDED |
- : api::settings_private::PolicyEnforcement:: |
- POLICY_ENFORCEMENT_ENFORCED; |
- } else if (!IsPrefUserModifiable(name)) { |
+ settings_private::PolicyEnforcement::POLICY_ENFORCEMENT_ENFORCED; |
+ return pref_object.Pass(); |
+ } |
+ if (IsPrefEnterpriseManaged(name)) { |
+ // Enterprise managed prefs are treated the same as device policy restricted |
+ // prefs in the UI. |
pref_object->policy_source = |
- api::settings_private::PolicySource::POLICY_SOURCE_USER; |
+ settings_private::PolicySource::POLICY_SOURCE_DEVICE_POLICY; |
pref_object->policy_enforcement = |
- api::settings_private::PolicyEnforcement::POLICY_ENFORCEMENT_ENFORCED; |
+ settings_private::PolicyEnforcement::POLICY_ENFORCEMENT_ENFORCED; |
+ return pref_object.Pass(); |
+ } |
+#endif |
+ |
+ if (pref && pref->IsManaged()) { |
+ pref_object->policy_source = |
+ settings_private::PolicySource::POLICY_SOURCE_USER_POLICY; |
+ pref_object->policy_enforcement = |
+ settings_private::PolicyEnforcement::POLICY_ENFORCEMENT_ENFORCED; |
+ return pref_object.Pass(); |
+ } |
+ if (pref && pref->IsRecommended()) { |
+ pref_object->policy_source = |
+ settings_private::PolicySource::POLICY_SOURCE_USER_POLICY; |
+ pref_object->policy_enforcement = |
+ settings_private::PolicyEnforcement::POLICY_ENFORCEMENT_RECOMMENDED; |
+ pref_object->recommended_value.reset( |
+ pref->GetRecommendedValue()->DeepCopy()); |
+ return pref_object.Pass(); |
+ } |
+ |
+#if defined(OS_CHROMEOS) |
+ if (IsPrefOwnerControlled(name)) { |
+ // Check for owner controlled after managed checks because if there is a |
+ // device policy there is no "owner". (In the unlikely case that both |
+ // situations apply, either badge is potentially relevent, so the order |
michaelpg
2015/09/17 02:19:25
sp: relevant
stevenjb
2015/09/17 17:33:31
Done.
|
+ // is somewhat arbitrary). |
+ pref_object->policy_source = |
+ settings_private::PolicySource::POLICY_SOURCE_OWNER; |
+ pref_object->policy_enforcement = |
+ settings_private::PolicyEnforcement::POLICY_ENFORCEMENT_ENFORCED; |
+ return pref_object.Pass(); |
+ } |
+#endif |
+ |
+ if (pref && pref->IsExtensionControlled()) { |
+ pref_object->policy_source = |
+ settings_private::PolicySource::POLICY_SOURCE_EXTENSION; |
+ pref_object->policy_enforcement = |
+ settings_private::PolicyEnforcement::POLICY_ENFORCEMENT_ENFORCED; |
+ std::string extension_id = |
+ ExtensionPrefValueMapFactory::GetForBrowserContext(profile_) |
+ ->GetExtensionControllingPref(pref->name()); |
+ pref_object->extension_id.reset(new std::string(extension_id)); |
+ return pref_object.Pass(); |
+ } |
+ if (pref && (!pref->IsUserModifiable() || IsPrefSupervisorControlled(name))) { |
+ // TODO(stevenjb): Investigate whether either of these should be badged. |
+ pref_object->read_only.reset(new bool(true)); |
+ return pref_object.Pass(); |
} |
return pref_object.Pass(); |
@@ -193,8 +263,7 @@ PrefsUtil::SetPrefResult PrefsUtil::SetPref(const std::string& pref_name, |
if (!IsPrefUserModifiable(pref_name)) |
return PREF_NOT_MODIFIABLE; |
- const PrefService::Preference* pref = |
- pref_service->FindPreference(pref_name); |
+ const PrefService::Preference* pref = pref_service->FindPreference(pref_name); |
if (!pref) |
return PREF_NOT_FOUND; |
@@ -251,7 +320,7 @@ PrefsUtil::SetPrefResult PrefsUtil::SetCrosSettingsPref( |
return PREF_NOT_MODIFIABLE; |
} |
- chromeos::CrosSettings::Get()->Set(pref_name, *value); |
+ CrosSettings::Get()->Set(pref_name, *value); |
return SUCCESS; |
#else |
return PREF_NOT_FOUND; |
@@ -270,7 +339,7 @@ bool PrefsUtil::AppendToListCrosSetting(const std::string& pref_name, |
return service->AppendToList(pref_name, value); |
} |
- chromeos::CrosSettings::Get()->AppendToList(pref_name, &value); |
+ CrosSettings::Get()->AppendToList(pref_name, &value); |
return true; |
#else |
return false; |
@@ -289,7 +358,7 @@ bool PrefsUtil::RemoveFromListCrosSetting(const std::string& pref_name, |
return service->RemoveFromList(pref_name, value); |
} |
- chromeos::CrosSettings::Get()->RemoveFromList(pref_name, &value); |
+ CrosSettings::Get()->RemoveFromList(pref_name, &value); |
return true; |
#else |
return false; |
@@ -308,19 +377,50 @@ bool PrefsUtil::IsPrefTypeURL(const std::string& pref_name) { |
return pref_type == settings_private::PrefType::PREF_TYPE_URL; |
} |
-bool PrefsUtil::IsPrefUserModifiable(const std::string& pref_name) { |
+#if defined(OS_CHROMEOS) |
+bool PrefsUtil::IsPrefEnterpriseManaged(const std::string& pref_name) { |
+ if (IsPrivilegedCrosSetting(pref_name)) { |
+ policy::BrowserPolicyConnectorChromeOS* connector = |
+ g_browser_process->platform_part()->browser_policy_connector_chromeos(); |
+ if (connector->IsEnterpriseManaged()) |
+ return true; |
+ } |
+ return false; |
+} |
+ |
+bool PrefsUtil::IsPrefOwnerControlled(const std::string& pref_name) { |
+ if (IsPrivilegedCrosSetting(pref_name)) { |
+ if (!chromeos::ProfileHelper::IsOwnerProfile(profile_)) |
+ return true; |
+ } |
+ return false; |
+} |
+ |
+bool PrefsUtil::IsPrefPrimaryUserControlled(const std::string& pref_name) { |
+ if (pref_name == prefs::kWakeOnWifiSsid) { |
+ user_manager::UserManager* user_manager = user_manager::UserManager::Get(); |
+ const user_manager::User* user = |
+ chromeos::ProfileHelper::Get()->GetUserByProfile(profile_); |
+ if (user && user->email() != user_manager->GetPrimaryUser()->email()) |
+ return true; |
+ } |
+ return false; |
+} |
+#endif |
+ |
+bool PrefsUtil::IsPrefSupervisorControlled(const std::string& pref_name) { |
if (pref_name != prefs::kBrowserGuestModeEnabled && |
pref_name != prefs::kBrowserAddPersonEnabled) { |
- return true; |
+ return false; |
} |
+ return profile_->IsSupervised(); |
+} |
+bool PrefsUtil::IsPrefUserModifiable(const std::string& pref_name) { |
PrefService* pref_service = profile_->GetPrefs(); |
const PrefService::Preference* pref = |
pref_service->FindPreference(pref_name.c_str()); |
- if (!pref || !pref->IsUserModifiable() || profile_->IsSupervised()) |
- return false; |
- |
- return true; |
+ return pref && pref->IsUserModifiable(); |
} |
PrefService* PrefsUtil::FindServiceForPref(const std::string& pref_name) { |