Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5532)

Unified Diff: chrome/browser/chromeos/user_cros_settings_provider.cc

Issue 8727037: Signed settings refactoring: Proper caching and more tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments. Fixed small bugs. Rebased to ToT. Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/chromeos/user_cros_settings_provider.h ('k') | chrome/browser/policy/device_policy_cache.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/chromeos/user_cros_settings_provider.cc
diff --git a/chrome/browser/chromeos/user_cros_settings_provider.cc b/chrome/browser/chromeos/user_cros_settings_provider.cc
deleted file mode 100644
index 7d855dff978796bbf9dfff1e3cf8fc51420e3046..0000000000000000000000000000000000000000
--- a/chrome/browser/chromeos/user_cros_settings_provider.cc
+++ /dev/null
@@ -1,536 +0,0 @@
-// Copyright (c) 2011 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/chromeos/user_cros_settings_provider.h"
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/callback.h"
-#include "base/hash_tables.h"
-#include "base/logging.h"
-#include "base/memory/singleton.h"
-#include "base/string_util.h"
-#include "base/values.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/chromeos/cros/cros_library.h"
-#include "chrome/browser/chromeos/cros/network_library.h"
-#include "chrome/browser/chromeos/cros_settings.h"
-#include "chrome/browser/chromeos/cros_settings_names.h"
-#include "chrome/browser/chromeos/login/ownership_service.h"
-#include "chrome/browser/chromeos/login/ownership_status_checker.h"
-#include "chrome/browser/chromeos/login/user_manager.h"
-#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/prefs/pref_value_map.h"
-#include "chrome/browser/prefs/scoped_user_pref_update.h"
-#include "chrome/browser/ui/options/options_util.h"
-#include "chrome/common/chrome_notification_types.h"
-#include "chrome/installer/util/google_update_settings.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/notification_service.h"
-
-using content::BrowserThread;
-
-namespace chromeos {
-
-namespace {
-
-const char kTrueIncantation[] = "true";
-const char kFalseIncantation[] = "false";
-const char kTrustedSuffix[] = "/trusted";
-
-// For all our boolean settings following is applicable:
-// true is default permissive value and false is safe prohibitic value.
-// Exception: kSignedDataRoamingEnabled which has default value of false.
-const char* kBooleanSettings[] = {
- kAccountsPrefAllowNewUser,
- kAccountsPrefAllowGuest,
- kAccountsPrefShowUserNamesOnSignIn,
- kSignedDataRoamingEnabled,
- kStatsReportingPref
-};
-
-const char* kStringSettings[] = {
- kDeviceOwner,
- kReleaseChannel
-};
-
-const char* kListSettings[] = {
- kAccountsPrefUsers
-};
-
-// This class provides the means to migrate settings to the signed settings
-// store. It does one of three things - store the settings in the policy blob
-// immediately if the current user is the owner. Uses the
-// SignedSettingsTempStorage if there is no owner yet, or waits for an
-// OWNERSHIP_CHECKED notification to delay the storing until the owner has
-// logged in.
-class MigrationHelper : public content::NotificationObserver {
- public:
- explicit MigrationHelper() : callback_(NULL) {
- registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_CHECKED,
- content::NotificationService::AllSources());
- }
-
- void set_callback(SignedSettingsHelper::Callback* callback) {
- callback_ = callback;
- }
-
- void AddMigrationValue(const std::string& path, base::Value* value) {
- migration_values_.SetValue(path, value);
- }
-
- void MigrateValues(void) {
- ownership_checker_.reset(new OwnershipStatusChecker(
- base::Bind(&MigrationHelper::DoMigrateValues, base::Unretained(this))));
- }
-
- // NotificationObserver overrides:
- virtual void Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) OVERRIDE {
- if (type == chrome::NOTIFICATION_OWNERSHIP_CHECKED)
- MigrateValues();
- }
-
- private:
- void DoMigrateValues(OwnershipService::Status status,
- bool current_user_is_owner) {
- ownership_checker_.reset(NULL);
-
- // We can call StartStorePropertyOp in two cases - either if the owner is
- // currently logged in and the policy can be updated immediately or if there
- // is no owner yet in which case the value will be temporarily stored in the
- // SignedSettingsTempStorage until the device is owned. If none of these
- // cases is met then we will wait for user change notification and retry.
- if (current_user_is_owner || status != OwnershipService::OWNERSHIP_TAKEN) {
- PrefValueMap::const_iterator i;
- for (i = migration_values_.begin(); i != migration_values_.end(); ++i) {
- // Queue all values for storing.
- SignedSettingsHelper::Get()->StartStorePropertyOp(i->first, *i->second,
- callback_);
- }
- migration_values_.Clear();
- }
- }
-
- content::NotificationRegistrar registrar_;
- scoped_ptr<OwnershipStatusChecker> ownership_checker_;
- SignedSettingsHelper::Callback* callback_;
- PrefValueMap migration_values_;
-
- DISALLOW_COPY_AND_ASSIGN(MigrationHelper);
-};
-
-bool IsControlledBooleanSetting(const std::string& pref_path) {
- // TODO(nkostylev): Using std::find for 4 value array generates this warning
- // in chroot stl_algo.h:231: error: array subscript is above array bounds.
- // GCC 4.4.3
- return (pref_path == kAccountsPrefAllowNewUser) ||
- (pref_path == kAccountsPrefAllowGuest) ||
- (pref_path == kAccountsPrefShowUserNamesOnSignIn) ||
- (pref_path == kSignedDataRoamingEnabled) ||
- (pref_path == kStatsReportingPref);
-}
-
-bool IsControlledStringSetting(const std::string& pref_path) {
- return std::find(kStringSettings,
- kStringSettings + arraysize(kStringSettings),
- pref_path) !=
- kStringSettings + arraysize(kStringSettings);
-}
-
-bool IsControlledListSetting(const std::string& pref_path) {
- return std::find(kListSettings,
- kListSettings + arraysize(kListSettings),
- pref_path) !=
- kListSettings + arraysize(kListSettings);
-}
-
-bool IsControlledSetting(const std::string& pref_path) {
- return (IsControlledBooleanSetting(pref_path) ||
- IsControlledStringSetting(pref_path) ||
- IsControlledListSetting(pref_path));
-}
-
-void RegisterSetting(PrefService* local_state, const std::string& pref_path) {
- local_state->RegisterBooleanPref((pref_path + kTrustedSuffix).c_str(),
- false,
- PrefService::UNSYNCABLE_PREF);
- if (IsControlledBooleanSetting(pref_path)) {
- if (pref_path == kSignedDataRoamingEnabled ||
- pref_path == kStatsReportingPref)
- local_state->RegisterBooleanPref(pref_path.c_str(),
- false,
- PrefService::UNSYNCABLE_PREF);
- else
- local_state->RegisterBooleanPref(pref_path.c_str(),
- true,
- PrefService::UNSYNCABLE_PREF);
- } else if (IsControlledStringSetting(pref_path)) {
- local_state->RegisterStringPref(pref_path.c_str(),
- "",
- PrefService::UNSYNCABLE_PREF);
- } else {
- DCHECK(IsControlledListSetting(pref_path));
- local_state->RegisterListPref(pref_path.c_str(),
- PrefService::UNSYNCABLE_PREF);
- }
-}
-
-enum UseValue {
- USE_VALUE_SUPPLIED,
- USE_VALUE_DEFAULT
-};
-
-void UpdateCache(const std::string& name,
- const base::Value* value,
- UseValue use_value) {
- PrefService* prefs = g_browser_process->local_state();
- if (use_value == USE_VALUE_DEFAULT)
- prefs->ClearPref(name.c_str());
- else
- prefs->Set(name.c_str(), *value);
- prefs->ScheduleSavePersistentPrefs();
-}
-
-class UserCrosSettingsTrust : public SignedSettingsHelper::Callback {
- public:
- static UserCrosSettingsTrust* GetInstance() {
- return Singleton<UserCrosSettingsTrust>::get();
- }
-
- // Working horse for UserCrosSettingsProvider::RequestTrusted* family.
- bool RequestTrustedEntity(const std::string& name) {
- OwnershipService::Status ownership_status =
- ownership_service_->GetStatus(false);
- if (ownership_status == OwnershipService::OWNERSHIP_NONE)
- return true;
- PrefService* prefs = g_browser_process->local_state();
- if (prefs->IsManagedPreference(name.c_str()))
- return true;
- if (ownership_status == OwnershipService::OWNERSHIP_TAKEN) {
- DCHECK(g_browser_process);
- PrefService* prefs = g_browser_process->local_state();
- DCHECK(prefs);
- if (prefs->GetBoolean((name + kTrustedSuffix).c_str()))
- return true;
- }
- return false;
- }
-
- bool RequestTrustedEntity(const std::string& name,
- const base::Closure& callback) {
- if (RequestTrustedEntity(name)) {
- return true;
- } else {
- if (!callback.is_null())
- callbacks_[name].push_back(callback);
- return false;
- }
- }
-
- void Reload() {
- for (size_t i = 0; i < arraysize(kBooleanSettings); ++i)
- StartFetchingSetting(kBooleanSettings[i]);
- for (size_t i = 0; i < arraysize(kStringSettings); ++i)
- StartFetchingSetting(kStringSettings[i]);
- for (size_t i = 0; i < arraysize(kListSettings); ++i)
- StartFetchingSetting(kListSettings[i]);
- }
-
- void Set(const std::string& path, const base::Value& in_value) {
- PrefService* prefs = g_browser_process->local_state();
- DCHECK(!prefs->IsManagedPreference(path.c_str()));
-
- if (!UserManager::Get()->current_user_is_owner()) {
- LOG(WARNING) << "Changing settings from non-owner, setting=" << path;
-
- // Revert UI change.
- CrosSettings::Get()->FireObservers(path.c_str());
- return;
- }
- if (IsControlledSetting(path)) {
- if (IsControlledBooleanSetting(path)) {
- bool bool_value = false;
- if (in_value.GetAsBoolean(&bool_value)) {
- OnBooleanPropertyChange(path, bool_value);
- }
- }
- SignedSettingsHelper::Get()->StartStorePropertyOp(
- path, in_value, this);
- UpdateCache(path, &in_value, USE_VALUE_SUPPLIED);
-
- LOG(ERROR) << "Set cros setting " << path;
- } else {
- LOG(WARNING) << "Try to set unhandled cros setting " << path;
- }
- }
-
- private:
- // upper bound for number of retries to fetch a signed setting.
- static const int kNumRetriesLimit = 9;
-
- UserCrosSettingsTrust()
- : ownership_service_(OwnershipService::GetSharedInstance()),
- retries_left_(kNumRetriesLimit) {
- migration_helper_.set_callback(this);
- // Start prefetching Boolean and String preferences.
- Reload();
- }
-
- virtual ~UserCrosSettingsTrust() {
- if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- // Cancels all pending callbacks from us.
- SignedSettingsHelper::Get()->CancelCallback(this);
- }
- }
-
- // Called right before boolean property is changed.
- void OnBooleanPropertyChange(const std::string& path, bool new_value) {
- if (path == kSignedDataRoamingEnabled) {
- NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
- if (cros->IsCellularAlwaysInRoaming()) {
- // If operator requires roaming always enabled, ignore supplied value
- // and set data roaming allowed in true always.
- new_value = true;
- }
- cros->SetCellularDataRoamingAllowed(new_value);
- } else if (path == kStatsReportingPref) {
- // TODO(pastarmovj): Remove this once we don't need to regenerate the
- // consent file for the GUID anymore.
- OptionsUtil::ResolveMetricsReportingEnabled(new_value);
- }
- }
-
- // Called right after signed value was checked.
- void OnPropertyRetrieve(const std::string& path,
- const base::Value* value,
- UseValue use_value) {
- if (path == kSignedDataRoamingEnabled) {
- NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
- const NetworkDevice* cellular = cros->FindCellularDevice();
- if (cellular) {
- bool device_value = cellular->data_roaming_allowed();
- if (!device_value && cros->IsCellularAlwaysInRoaming()) {
- // If operator requires roaming always enabled, ignore supplied value
- // and set data roaming allowed in true always.
- cros->SetCellularDataRoamingAllowed(true);
- } else {
- bool new_value = false;
- if (use_value == USE_VALUE_SUPPLIED)
- value->GetAsBoolean(&new_value);
- if (device_value != new_value)
- cros->SetCellularDataRoamingAllowed(new_value);
- }
- }
- } else if (path == kStatsReportingPref) {
- bool stats_consent = false;
- if (use_value == USE_VALUE_SUPPLIED)
- value->GetAsBoolean(&stats_consent);
- // TODO(pastarmovj): Remove this once migration is not needed anymore.
- // If the value is not set we should try to migrate legacy consent file.
- if (use_value == USE_VALUE_DEFAULT) {
- // Loading consent file state causes us to do blocking IO on UI thread.
- // Temporarily allow it until we fix http://crbug.com/62626
- base::ThreadRestrictions::ScopedAllowIO allow_io;
- stats_consent = GoogleUpdateSettings::GetCollectStatsConsent();
- // Make sure the values will get eventually written to the policy file.
- migration_helper_.AddMigrationValue(
- path, base::Value::CreateBooleanValue(stats_consent));
- migration_helper_.MigrateValues();
- base::FundamentalValue base_value(stats_consent);
- UpdateCache(path, &base_value, USE_VALUE_SUPPLIED);
- LOG(WARNING) << "No metrics policy set will revert to checking "
- << "consent file which is "
- << (stats_consent ? "on." : "off.");
- }
- // TODO(pastarmovj): Remove this once we don't need to regenerate the
- // consent file for the GUID anymore.
- VLOG(1) << "Metrics policy is being set to : " << stats_consent
- << "(reason : " << use_value << ")";
- OptionsUtil::ResolveMetricsReportingEnabled(stats_consent);
- }
- }
-
- void StartFetchingSetting(const std::string& name) {
- DCHECK(g_browser_process);
- PrefService* prefs = g_browser_process->local_state();
- if (!prefs)
- return;
- // Do not trust before fetching complete.
- prefs->ClearPref((name + kTrustedSuffix).c_str());
- prefs->ScheduleSavePersistentPrefs();
- SignedSettingsHelper::Get()->StartRetrieveProperty(name, this);
- }
-
- // Implementation of SignedSettingsHelper::Callback.
- virtual void OnRetrievePropertyCompleted(SignedSettings::ReturnCode code,
- const std::string& name,
- const base::Value* value) {
- if (!IsControlledSetting(name)) {
- NOTREACHED();
- return;
- }
-
- bool is_owned = ownership_service_->GetStatus(true) ==
- OwnershipService::OWNERSHIP_TAKEN;
- PrefService* prefs = g_browser_process->local_state();
- switch (code) {
- case SignedSettings::SUCCESS:
- case SignedSettings::NOT_FOUND:
- case SignedSettings::KEY_UNAVAILABLE: {
- bool fallback_to_default = !is_owned
- || (code == SignedSettings::NOT_FOUND);
- DCHECK(fallback_to_default || code == SignedSettings::SUCCESS);
- if (fallback_to_default)
- VLOG(1) << "Going default for cros setting " << name;
- else
- VLOG(1) << "Retrieved cros setting " << name;
- UpdateCache(
- name, value,
- fallback_to_default ? USE_VALUE_DEFAULT : USE_VALUE_SUPPLIED);
- OnPropertyRetrieve(
- name, value,
- fallback_to_default ? USE_VALUE_DEFAULT : USE_VALUE_SUPPLIED);
- break;
- }
- case SignedSettings::OPERATION_FAILED:
- default: {
- DCHECK(code == SignedSettings::OPERATION_FAILED);
- DCHECK(is_owned);
- LOG(ERROR) << "On owned device: failed to retrieve cros "
- "setting, name=" << name;
- if (retries_left_ > 0) {
- retries_left_ -= 1;
- StartFetchingSetting(name);
- return;
- }
- LOG(ERROR) << "No retries left";
- if (IsControlledBooleanSetting(name)) {
- // For boolean settings we can just set safe (false) values
- // and continue as trusted.
- scoped_ptr<base::Value> false_value(
- base::Value::CreateBooleanValue(false));
- OnPropertyRetrieve(name, false_value.get(), USE_VALUE_SUPPLIED);
- UpdateCache(name, false_value.get(), USE_VALUE_SUPPLIED);
- } else {
- prefs->ClearPref((name + kTrustedSuffix).c_str());
- return;
- }
- break;
- }
- }
- prefs->SetBoolean((name + kTrustedSuffix).c_str(), true);
- {
- std::vector<base::Closure>& callbacks_vector = callbacks_[name];
- for (size_t i = 0; i < callbacks_vector.size(); ++i)
- MessageLoop::current()->PostTask(FROM_HERE, callbacks_vector[i]);
- callbacks_vector.clear();
- }
- if (code == SignedSettings::SUCCESS)
- CrosSettings::Get()->FireObservers(name.c_str());
- }
-
- // Implementation of SignedSettingsHelper::Callback.
- virtual void OnStorePropertyCompleted(SignedSettings::ReturnCode code,
- const std::string& name,
- const base::Value& value) {
- VLOG(1) << "Store cros setting " << name << ", code=" << code;
-
- // Reload the setting if store op fails.
- if (code != SignedSettings::SUCCESS)
- SignedSettingsHelper::Get()->StartRetrieveProperty(name, this);
- }
-
- // Implementation of SignedSettingsHelper::Callback.
- virtual void OnWhitelistCompleted(SignedSettings::ReturnCode code,
- const std::string& email) {
- VLOG(1) << "Add " << email << " to whitelist, code=" << code;
-
- // Reload the whitelist on settings op failure.
- if (code != SignedSettings::SUCCESS)
- CrosSettings::Get()->FireObservers(kAccountsPrefUsers);
- }
-
- // Implementation of SignedSettingsHelper::Callback.
- virtual void OnUnwhitelistCompleted(SignedSettings::ReturnCode code,
- const std::string& email) {
- VLOG(1) << "Remove " << email << " from whitelist, code=" << code;
-
- // Reload the whitelist on settings op failure.
- if (code != SignedSettings::SUCCESS)
- CrosSettings::Get()->FireObservers(kAccountsPrefUsers);
- }
-
- // Pending callbacks that need to be invoked after settings verification.
- base::hash_map<std::string, std::vector<base::Closure> > callbacks_;
-
- OwnershipService* ownership_service_;
- MigrationHelper migration_helper_;
-
- // In order to guard against occasional failure to fetch a property
- // we allow for some number of retries.
- int retries_left_;
-
- friend class SignedSettingsHelper;
- friend struct DefaultSingletonTraits<UserCrosSettingsTrust>;
-
- DISALLOW_COPY_AND_ASSIGN(UserCrosSettingsTrust);
-};
-
-} // namespace
-
-} // namespace chromeos
-
-namespace chromeos {
-
-UserCrosSettingsProvider::UserCrosSettingsProvider() {
- // Trigger prefetching of settings.
- UserCrosSettingsTrust::GetInstance();
-}
-
-// static
-void UserCrosSettingsProvider::RegisterPrefs(PrefService* local_state) {
- for (size_t i = 0; i < arraysize(kBooleanSettings); ++i)
- RegisterSetting(local_state, kBooleanSettings[i]);
- for (size_t i = 0; i < arraysize(kStringSettings); ++i)
- RegisterSetting(local_state, kStringSettings[i]);
- for (size_t i = 0; i < arraysize(kListSettings); ++i)
- RegisterSetting(local_state, kListSettings[i]);
-}
-
-void UserCrosSettingsProvider::Reload() {
- UserCrosSettingsTrust::GetInstance()->Reload();
-}
-
-void UserCrosSettingsProvider::DoSet(const std::string& path,
- const base::Value& in_value) {
- UserCrosSettingsTrust::GetInstance()->Set(path, in_value);
-}
-
-const base::Value* UserCrosSettingsProvider::Get(
- const std::string& path) const {
- if (HandlesSetting(path)) {
- const PrefService* prefs = g_browser_process->local_state();
- const PrefService::Preference* pref = prefs->FindPreference(path.c_str());
- return pref->GetValue();
- }
- return NULL;
-}
-
-bool UserCrosSettingsProvider::GetTrusted(const std::string& path,
- const base::Closure& callback) const {
- return UserCrosSettingsTrust::GetInstance()->RequestTrustedEntity(
- path, callback);
-}
-
-bool UserCrosSettingsProvider::HandlesSetting(const std::string& path) const {
- return ::StartsWithASCII(path, "cros.accounts.", true) ||
- ::StartsWithASCII(path, "cros.signed.", true) ||
- ::StartsWithASCII(path, "cros.metrics.", true) ||
- path == kDeviceOwner ||
- path == kReleaseChannel;
-}
-
-} // namespace chromeos
« no previous file with comments | « chrome/browser/chromeos/user_cros_settings_provider.h ('k') | chrome/browser/policy/device_policy_cache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698