diff options
author | pastarmovj@chromium.org <pastarmovj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-02 16:15:49 +0000 |
---|---|---|
committer | pastarmovj@chromium.org <pastarmovj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-02 16:15:49 +0000 |
commit | 233bb3ecc6051de687249841b10705a546385999 (patch) | |
tree | 5c6064480add3d2f95510c879daa0f398b98aba6 /chrome | |
parent | 8a42080741944d129bc3c5af69d8b480c9a77dab (diff) | |
download | chromium_src-233bb3ecc6051de687249841b10705a546385999.zip chromium_src-233bb3ecc6051de687249841b10705a546385999.tar.gz chromium_src-233bb3ecc6051de687249841b10705a546385999.tar.bz2 |
PART 5 Of the signed settings refactoring. List of all changes follow beneath:
Read from the bottom to the top:
* Add new unit tests to cover what was removed before.
* Rename SignedSettingsTempStorage to SignedSettingsCache.
* Revitalize existing tests for SignedSettings[Helper].
* Add the needed infrastucture to support enrollment as well.
* Remove the second cache in OwnershipService it is obsolete.
* Remove the prop ops completely.
* Remove direct prop op from the proxy stuff.
* Serialize policy changes correctly and map side effects of policies.
Mainly make sure we never serialize dirty policy.
Don't reload if policy is serialized fine.
Clear local state registration.
* Clean up redundand SS ops and make proper callbacks for the helper
Move the temp storage finalization to where it belongs.
* Make the temp storage be the cache and use policy ops.
* Make DeviceSettingsProvider work with the protobuf blob directly.
* Merged DeviceSettingsProvider and UserCrosSettingsTrust.
* Rename UserCrosSettingsProvider to DeviceSettingsProvider.
* Extract the SignedSettingsMigrationHelper in its own file.
BUG=chromium-os:14054
TEST=unit_tests:SignedSettings*,*CrosSettings*,suite_Smoke:login_OwnershipApi
Review URL: http://codereview.chromium.org/8727037
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112713 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
51 files changed, 1536 insertions, 1924 deletions
diff --git a/chrome/browser/chromeos/cros_settings.cc b/chrome/browser/chromeos/cros_settings.cc index bde3c31..8d54cbd 100644 --- a/chrome/browser/chromeos/cros_settings.cc +++ b/chrome/browser/chromeos/cros_settings.cc @@ -8,7 +8,7 @@ #include "base/stl_util.h" #include "base/string_util.h" #include "base/values.h" -#include "chrome/browser/chromeos/user_cros_settings_provider.h" +#include "chrome/browser/chromeos/device_settings_provider.h" #include "chrome/browser/ui/webui/options/chromeos/system_settings_provider.h" #include "chrome/common/chrome_notification_types.h" #include "content/public/browser/notification_details.h" @@ -50,9 +50,8 @@ void CrosSettings::Set(const std::string& path, const base::Value& in_value) { DCHECK(CalledOnValidThread()); CrosSettingsProvider* provider; provider = GetProvider(path); - if (provider) { + if (provider) provider->Set(path, in_value); - } } void CrosSettings::SetBoolean(const std::string& path, bool in_value) { @@ -104,8 +103,8 @@ bool CrosSettings::FindEmailInList(const std::string& path, const std::string& email) const { DCHECK(CalledOnValidThread()); base::StringValue email_value(email); - const base::ListValue* value = - static_cast<const base::ListValue*>(GetPref(path)); + const base::ListValue* value( + static_cast<const base::ListValue*>(GetPref(path))); if (value) { if (value->Find(email_value) != value->end()) return true; @@ -144,7 +143,7 @@ void CrosSettings::AddSettingsObserver(const char* path, if (!GetProvider(std::string(path))) { NOTREACHED() << "Trying to add an observer for an unregistered setting: " - << path; + << path; return; } @@ -178,9 +177,8 @@ void CrosSettings::RemoveSettingsObserver(const char* path, SettingsObserverMap::iterator observer_iterator = settings_observers_.find(path); - if (observer_iterator == settings_observers_.end()) { + if (observer_iterator == settings_observers_.end()) return; - } NotificationObserverList* observer_list = observer_iterator->second; observer_list->RemoveObserver(obs); @@ -195,6 +193,11 @@ CrosSettingsProvider* CrosSettings::GetProvider( return NULL; } +void CrosSettings::ReloadProviders() { + for (size_t i = 0; i < providers_.size(); ++i) + providers_[i]->Reload(); +} + const base::Value* CrosSettings::GetPref(const std::string& path) const { DCHECK(CalledOnValidThread()); CrosSettingsProvider* provider = GetProvider(path); @@ -261,7 +264,7 @@ bool CrosSettings::GetList(const std::string& path, CrosSettings::CrosSettings() { AddSettingsProvider(new SystemSettingsProvider()); - AddSettingsProvider(new UserCrosSettingsProvider()); + AddSettingsProvider(new DeviceSettingsProvider()); } CrosSettings::~CrosSettings() { diff --git a/chrome/browser/chromeos/cros_settings.h b/chrome/browser/chromeos/cros_settings.h index c7f66d2..49cf526 100644 --- a/chrome/browser/chromeos/cros_settings.h +++ b/chrome/browser/chromeos/cros_settings.h @@ -92,6 +92,10 @@ class CrosSettings : public base::NonThreadSafe { // Returns the provider that handles settings with the path or prefix. CrosSettingsProvider* GetProvider(const std::string& path) const; + // Forces all providers to reload their caches from the respective backing + // stores if they have any. + void ReloadProviders(); + private: // List of ChromeOS system settings providers. std::vector<CrosSettingsProvider*> providers_; diff --git a/chrome/browser/chromeos/cros_settings_provider.h b/chrome/browser/chromeos/cros_settings_provider.h index c050092..ba65253 100644 --- a/chrome/browser/chromeos/cros_settings_provider.h +++ b/chrome/browser/chromeos/cros_settings_provider.h @@ -30,11 +30,14 @@ class CrosSettingsProvider { // was needed in which case the return value is false. Else it will return // true and won't call the |callback|. virtual bool GetTrusted(const std::string& path, - const base::Closure& callback) const = 0; + const base::Closure& callback) = 0; - // Gets the namespace prefix provided by this provider + // Gets the namespace prefix provided by this provider. virtual bool HandlesSetting(const std::string& path) const = 0; + // Reloads the caches if the provider has any. + virtual void Reload() = 0; + private: // Does the real job for Set(). virtual void DoSet(const std::string& path, diff --git a/chrome/browser/chromeos/cros_settings_unittest.cc b/chrome/browser/chromeos/cros_settings_unittest.cc new file mode 100644 index 0000000..783d372 --- /dev/null +++ b/chrome/browser/chromeos/cros_settings_unittest.cc @@ -0,0 +1,228 @@ +// 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/login/signed_settings.h" + +#include <map> +#include <string> + +#include "base/bind.h" +#include "base/memory/weak_ptr.h" +#include "base/message_loop.h" +#include "base/stl_util.h" +#include "base/values.h" +#include "chrome/browser/chromeos/cros_settings.h" +#include "chrome/browser/chromeos/cros_settings_names.h" +#include "chrome/browser/chromeos/cros/cros_library.h" +#include "chrome/browser/chromeos/login/signed_settings_cache.h" +#include "chrome/browser/policy/proto/chrome_device_policy.pb.h" +#include "chrome/browser/policy/proto/device_management_backend.pb.h" +#include "chrome/test/base/testing_browser_process.h" +#include "chrome/test/base/testing_pref_service.h" +#include "content/test/test_browser_thread.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace em = enterprise_management; +namespace chromeos { + +class CrosSettingsTest : public testing::Test { + protected: + CrosSettingsTest() + : message_loop_(MessageLoop::TYPE_UI), + ui_thread_(content::BrowserThread::UI, &message_loop_), + file_thread_(content::BrowserThread::FILE, &message_loop_), + pointer_factory_(this), + local_state_(static_cast<TestingBrowserProcess*>(g_browser_process)) { + } + + virtual ~CrosSettingsTest() { + } + + virtual void SetUp() { + // Reset the cache between tests. + ApplyEmptyPolicy(); + } + + virtual void TearDown() { + message_loop_.RunAllPending(); + ASSERT_TRUE(expected_props_.empty()); + // Reset the cache between tests. + ApplyEmptyPolicy(); + STLDeleteValues(&expected_props_); + } + + void FetchPref(const std::string& pref) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + if (expected_props_.find(pref) == expected_props_.end()) + return; + + if (CrosSettings::Get()->GetTrusted(pref, + base::Bind(&CrosSettingsTest::FetchPref, + pointer_factory_.GetWeakPtr(), pref))) { + scoped_ptr<base::Value> expected_value( + expected_props_.find(pref)->second); + const base::Value* pref_value = CrosSettings::Get()->GetPref(pref); + if (expected_value.get()) { + ASSERT_TRUE(pref_value); + ASSERT_TRUE(expected_value->Equals(pref_value)); + } else { + ASSERT_FALSE(pref_value); + } + expected_props_.erase(pref); + } + } + + void SetPref(const std::string& pref_name, const base::Value* value) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + CrosSettings::Get()->Set(pref_name, *value); + } + + void AddExpectation(const std::string& pref_name, base::Value* value) { + base::Value*& entry = expected_props_[pref_name]; + delete entry; + entry = value; + } + + void PrepareEmptyPolicy(em::PolicyData* policy) { + // Prepare some policy blob. + em::PolicyFetchResponse response; + em::ChromeDeviceSettingsProto pol; + policy->set_policy_type(chromeos::kDevicePolicyType); + policy->set_username("me@owner"); + policy->set_policy_value(pol.SerializeAsString()); + // Wipe the signed settings store. + response.set_policy_data(policy->SerializeAsString()); + response.set_policy_data_signature("false"); + } + + void ApplyEmptyPolicy() { + em::PolicyData fake_pol; + PrepareEmptyPolicy(&fake_pol); + signed_settings_cache::Store(fake_pol, local_state_.Get()); + CrosSettings::Get()->ReloadProviders(); + } + + std::map<std::string, base::Value*> expected_props_; + + MessageLoop message_loop_; + content::TestBrowserThread ui_thread_; + content::TestBrowserThread file_thread_; + + base::WeakPtrFactory<CrosSettingsTest> pointer_factory_; + + ScopedTestingLocalState local_state_; + + ScopedStubCrosEnabler stub_cros_enabler_; +}; + +TEST_F(CrosSettingsTest, SetPref) { + // Change to something that is not the default. + AddExpectation(kAccountsPrefAllowGuest, + base::Value::CreateBooleanValue(false)); + SetPref(kAccountsPrefAllowGuest, expected_props_[kAccountsPrefAllowGuest]); + FetchPref(kAccountsPrefAllowGuest); + message_loop_.RunAllPending(); + ASSERT_TRUE(expected_props_.empty()); +} + +TEST_F(CrosSettingsTest, GetPref) { + // We didn't change the default so look for it. + AddExpectation(kAccountsPrefAllowGuest, + base::Value::CreateBooleanValue(true)); + FetchPref(kAccountsPrefAllowGuest); +} + +TEST_F(CrosSettingsTest, SetWhitelist) { + // Setting the whitelist should also switch the value of + // kAccountsPrefAllowNewUser to false. + base::ListValue whitelist; + whitelist.Append(base::Value::CreateStringValue("me@owner")); + AddExpectation(kAccountsPrefAllowNewUser, + base::Value::CreateBooleanValue(false)); + AddExpectation(kAccountsPrefUsers, whitelist.DeepCopy()); + SetPref(kAccountsPrefUsers, &whitelist); + FetchPref(kAccountsPrefAllowNewUser); + FetchPref(kAccountsPrefUsers); +} + +TEST_F(CrosSettingsTest, SetWhitelistWithListOps) { + base::ListValue* whitelist = new base::ListValue(); + base::StringValue hacky_user("h@xxor"); + whitelist->Append(hacky_user.DeepCopy()); + AddExpectation(kAccountsPrefAllowNewUser, + base::Value::CreateBooleanValue(false)); + AddExpectation(kAccountsPrefUsers, whitelist); + // Add some user to the whitelist. + CrosSettings::Get()->AppendToList(kAccountsPrefUsers, &hacky_user); + FetchPref(kAccountsPrefAllowNewUser); + FetchPref(kAccountsPrefUsers); +} + +TEST_F(CrosSettingsTest, SetWhitelistWithListOps2) { + base::ListValue whitelist; + base::StringValue hacky_user("h@xxor"); + base::StringValue lamy_user("l@mer"); + whitelist.Append(hacky_user.DeepCopy()); + base::ListValue* expected_list = whitelist.DeepCopy(); + whitelist.Append(lamy_user.DeepCopy()); + AddExpectation(kAccountsPrefAllowNewUser, + base::Value::CreateBooleanValue(false)); + AddExpectation(kAccountsPrefUsers, whitelist.DeepCopy()); + SetPref(kAccountsPrefUsers, &whitelist); + FetchPref(kAccountsPrefAllowNewUser); + FetchPref(kAccountsPrefUsers); + message_loop_.RunAllPending(); + ASSERT_TRUE(expected_props_.empty()); + // Now try to remove one element from that list. + AddExpectation(kAccountsPrefUsers, expected_list); + CrosSettings::Get()->RemoveFromList(kAccountsPrefUsers, &lamy_user); + FetchPref(kAccountsPrefAllowNewUser); + FetchPref(kAccountsPrefUsers); +} + +TEST_F(CrosSettingsTest, SetEmptyWhitelist) { + // Setting the whitelist empty should switch the value of + // kAccountsPrefAllowNewUser to true. + base::ListValue whitelist; + base::FundamentalValue disallow_new(false); + AddExpectation(kAccountsPrefAllowNewUser, + base::Value::CreateBooleanValue(true)); + SetPref(kAccountsPrefUsers, &whitelist); + SetPref(kAccountsPrefAllowNewUser, &disallow_new); + FetchPref(kAccountsPrefAllowNewUser); + FetchPref(kAccountsPrefUsers); +} + +TEST_F(CrosSettingsTest, SetWhitelistAndNoNewUsers) { + // Setting the whitelist should allow us to set kAccountsPrefAllowNewUser to + // false (which is the implicit value too). + base::ListValue whitelist; + whitelist.Append(base::Value::CreateStringValue("me@owner")); + AddExpectation(kAccountsPrefUsers, whitelist.DeepCopy()); + AddExpectation(kAccountsPrefAllowNewUser, + base::Value::CreateBooleanValue(false)); + SetPref(kAccountsPrefUsers, &whitelist); + SetPref(kAccountsPrefAllowNewUser, + expected_props_[kAccountsPrefAllowNewUser]); + FetchPref(kAccountsPrefAllowNewUser); + FetchPref(kAccountsPrefUsers); +} + +TEST_F(CrosSettingsTest, SetAllowNewUsers) { + // Setting kAccountsPrefAllowNewUser to true with no whitelist should be ok. + AddExpectation(kAccountsPrefAllowNewUser, + base::Value::CreateBooleanValue(true)); + SetPref(kAccountsPrefAllowNewUser, + expected_props_[kAccountsPrefAllowNewUser]); + FetchPref(kAccountsPrefAllowNewUser); +} + +TEST_F(CrosSettingsTest, SetOwner) { + base::StringValue hacky_owner("h@xxor"); + AddExpectation(kDeviceOwner, base::Value::CreateStringValue("h@xxor")); + SetPref(kDeviceOwner, &hacky_owner); + FetchPref(kDeviceOwner); +} + +} // namespace chromeos diff --git a/chrome/browser/chromeos/device_settings_provider.cc b/chrome/browser/chromeos/device_settings_provider.cc new file mode 100644 index 0000000..d04c4fb --- /dev/null +++ b/chrome/browser/chromeos/device_settings_provider.cc @@ -0,0 +1,523 @@ +// 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/device_settings_provider.h" + +#include "base/base64.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/signed_settings_cache.h" +#include "chrome/browser/chromeos/login/user_manager.h" +#include "chrome/browser/policy/proto/chrome_device_policy.pb.h" +#include "chrome/browser/policy/proto/device_management_backend.pb.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; +using google::protobuf::RepeatedPtrField; + +namespace chromeos { + +namespace { + +const char* kBooleanSettings[] = { + kAccountsPrefAllowNewUser, + kAccountsPrefAllowGuest, + kAccountsPrefShowUserNamesOnSignIn, + kSignedDataRoamingEnabled, + kStatsReportingPref +}; + +const char* kStringSettings[] = { + kDeviceOwner, + kReleaseChannel, + kSettingProxyEverywhere +}; + +const char* kListSettings[] = { + kAccountsPrefUsers +}; + +// Upper bound for number of retries to fetch a signed setting. +static const int kNumRetriesLimit = 9; + +bool IsControlledBooleanSetting(const std::string& pref_path) { + const char** end = kBooleanSettings + arraysize(kBooleanSettings); + return std::find(kBooleanSettings, end, pref_path) != end; +} + +bool IsControlledStringSetting(const std::string& pref_path) { + const char** end = kStringSettings + arraysize(kStringSettings); + return std::find(kStringSettings, end, pref_path) != end; +} + +bool IsControlledListSetting(const std::string& pref_path) { + const char** end = kListSettings + arraysize(kListSettings); + return std::find(kListSettings, end, pref_path) != end; +} + +bool IsControlledSetting(const std::string& pref_path) { + return (IsControlledBooleanSetting(pref_path) || + IsControlledStringSetting(pref_path) || + IsControlledListSetting(pref_path)); +} + +bool HasOldMetricsFile() { + // TODO(pastarmovj): Remove this once migration is not needed anymore. + // If the value is not set we should try to migrate legacy consent file. + // 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; + return GoogleUpdateSettings::GetCollectStatsConsent(); +} + +} // namespace + +DeviceSettingsProvider::DeviceSettingsProvider() + : ownership_status_(OwnershipService::GetSharedInstance()->GetStatus(true)), + migration_helper_(new SignedSettingsMigrationHelper()), + retries_left_(kNumRetriesLimit), + trusted_(false) { + // Register for notification when ownership is taken so that we can update + // the |ownership_status_| and reload if needed. + registrar_.Add(this, chrome::NOTIFICATION_OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED, + content::NotificationService::AllSources()); + // Make sure we have at least the cache data immediately. + RetrieveCachedData(); + // Start prefetching preferences. + Reload(); +} + +DeviceSettingsProvider::~DeviceSettingsProvider() { +} + +void DeviceSettingsProvider::Reload() { + // While fetching we can't trust the cache anymore. + trusted_ = false; + if (ownership_status_ == OwnershipService::OWNERSHIP_NONE) { + RetrieveCachedData(); + } else { + // Retrieve the real data. + SignedSettingsHelper::Get()->StartRetrievePolicyOp( + base::Bind(&DeviceSettingsProvider::OnRetrievePolicyCompleted, + base::Unretained(this))); + } +} + +void DeviceSettingsProvider::DoSet(const std::string& path, + const base::Value& in_value) { + if (!UserManager::Get()->current_user_is_owner() && + ownership_status_ != OwnershipService::OWNERSHIP_NONE) { + LOG(WARNING) << "Changing settings from non-owner, setting=" << path; + + // Revert UI change. + CrosSettings::Get()->FireObservers(path.c_str()); + return; + } + + if (IsControlledSetting(path)) + SetInPolicy(path, in_value); + else + NOTREACHED() << "Try to set unhandled cros setting " << path; +} + +void DeviceSettingsProvider::Observe( + int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { + if (type == chrome::NOTIFICATION_OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED && + UserManager::Get()->current_user_is_owner()) { + // Reload the initial policy blob, apply settings from temp storage, + // and write back the blob. + ownership_status_ = OwnershipService::OWNERSHIP_TAKEN; + Reload(); + } +} + +const em::PolicyData DeviceSettingsProvider::policy() const { + return policy_; +} + +void DeviceSettingsProvider::RetrieveCachedData() { + // If there is no owner yet, this function will pull the policy cache from the + // temp storage and use that instead. + em::PolicyData policy; + if (!signed_settings_cache::Retrieve(&policy, + g_browser_process->local_state())) { + VLOG(1) << "Can't retrieve temp store possibly not created yet."; + // Prepare empty data for the case we don't have temp cache yet. + policy.set_policy_type(kDevicePolicyType); + em::ChromeDeviceSettingsProto pol; + policy.set_policy_value(pol.SerializeAsString()); + } + + policy_ = policy; + UpdateValuesCache(); +} + +void DeviceSettingsProvider::SetInPolicy(const std::string& prop, + const base::Value& value) { + if (prop == kDeviceOwner) { + // Just store it in the memory cache without trusted checks or persisting. + std::string owner; + if (value.GetAsString(&owner)) { + policy_.set_username(owner); + values_cache_.SetValue(prop, value.DeepCopy()); + CrosSettings::Get()->FireObservers(prop.c_str()); + // We can't trust this value anymore until we reload the real username. + trusted_ = false; + } else { + NOTREACHED(); + } + return; + } + + if (!RequestTrustedEntity()) { + // Otherwise we should first reload and apply on top of that. + SignedSettingsHelper::Get()->StartRetrievePolicyOp( + base::Bind(&DeviceSettingsProvider::FinishSetInPolicy, + base::Unretained(this), + prop, base::Owned(value.DeepCopy()))); + return; + } + + trusted_ = false; + em::PolicyData data = policy(); + em::ChromeDeviceSettingsProto pol; + pol.ParseFromString(data.policy_value()); + if (prop == kAccountsPrefAllowNewUser) { + em::AllowNewUsersProto* allow = pol.mutable_allow_new_users(); + bool allow_value; + if (value.GetAsBoolean(&allow_value)) + allow->set_allow_new_users(allow_value); + else + NOTREACHED(); + } else if (prop == kAccountsPrefAllowGuest) { + em::GuestModeEnabledProto* guest = pol.mutable_guest_mode_enabled(); + bool guest_value; + if (value.GetAsBoolean(&guest_value)) + guest->set_guest_mode_enabled(guest_value); + else + NOTREACHED(); + } else if (prop == kAccountsPrefShowUserNamesOnSignIn) { + em::ShowUserNamesOnSigninProto* show = pol.mutable_show_user_names(); + bool show_value; + if (value.GetAsBoolean(&show_value)) + show->set_show_user_names(show_value); + else + NOTREACHED(); + } else if (prop == kSignedDataRoamingEnabled) { + em::DataRoamingEnabledProto* roam = pol.mutable_data_roaming_enabled(); + bool roaming_value = false; + if (value.GetAsBoolean(&roaming_value)) + roam->set_data_roaming_enabled(roaming_value); + else + NOTREACHED(); + ApplyRoamingSetting(roaming_value); + } else if (prop == kSettingProxyEverywhere) { + // TODO(cmasone): NOTIMPLEMENTED() once http://crosbug.com/13052 is fixed. + std::string proxy_value; + if (value.GetAsString(&proxy_value)) { + bool success = + pol.mutable_device_proxy_settings()->ParseFromString(proxy_value); + DCHECK(success); + } else { + NOTREACHED(); + } + } else if (prop == kReleaseChannel) { + em::ReleaseChannelProto* release_channel = pol.mutable_release_channel(); + std::string channel_value; + if (value.GetAsString(&channel_value)) + release_channel->set_release_channel(channel_value); + else + NOTREACHED(); + } else if (prop == kStatsReportingPref) { + em::MetricsEnabledProto* metrics = pol.mutable_metrics_enabled(); + bool metrics_value = false; + if (value.GetAsBoolean(&metrics_value)) + metrics->set_metrics_enabled(metrics_value); + else + NOTREACHED(); + ApplyMetricsSetting(false, metrics_value); + } else if (prop == kAccountsPrefUsers) { + em::UserWhitelistProto* whitelist_proto = pol.mutable_user_whitelist(); + whitelist_proto->clear_user_whitelist(); + const base::ListValue& users = static_cast<const base::ListValue&>(value); + for (base::ListValue::const_iterator i = users.begin(); + i != users.end(); ++i) { + std::string email; + if ((*i)->GetAsString(&email)) + whitelist_proto->add_user_whitelist(email.c_str()); + } + } else { + NOTREACHED(); + } + data.set_policy_value(pol.SerializeAsString()); + // Set the cache to the updated value. + policy_ = data; + UpdateValuesCache(); + CrosSettings::Get()->FireObservers(prop.c_str()); + + if (!signed_settings_cache::Store(data, g_browser_process->local_state())) + LOG(ERROR) << "Couldn't store to the temp storage."; + + if (ownership_status_ == OwnershipService::OWNERSHIP_TAKEN) { + em::PolicyFetchResponse policy_envelope; + policy_envelope.set_policy_data(policy_.SerializeAsString()); + SignedSettingsHelper::Get()->StartStorePolicyOp( + policy_envelope, + base::Bind(&DeviceSettingsProvider::OnStorePolicyCompleted, + base::Unretained(this))); + } +} + +void DeviceSettingsProvider::FinishSetInPolicy( + const std::string& prop, + const base::Value* value, + SignedSettings::ReturnCode code, + const em::PolicyFetchResponse& policy) { + if (code != SignedSettings::SUCCESS) { + LOG(ERROR) << "Can't serialize to policy error code: " << code; + Reload(); + return; + } + SetInPolicy(prop, *value); +} + +void DeviceSettingsProvider::UpdateValuesCache() { + const em::PolicyData data = policy(); + values_cache_.Clear(); + + if (data.has_username() && !data.has_request_token()) + values_cache_.SetString(kDeviceOwner, data.username()); + + em::ChromeDeviceSettingsProto pol; + pol.ParseFromString(data.policy_value()); + + // For all our boolean settings the following is applicable: + // true is default permissive value and false is safe prohibitive value. + // Exception: kSignedDataRoamingEnabled which has default value of false. + if (pol.has_allow_new_users() && + pol.allow_new_users().has_allow_new_users() && + pol.allow_new_users().allow_new_users()) { + // New users allowed, user_whitelist() ignored. + values_cache_.SetBoolean(kAccountsPrefAllowNewUser, true); + } else if (!pol.has_user_whitelist()) { + // If we have the allow_new_users bool, and it is true, we honor that above. + // In all other cases (don't have it, have it and it is set to false, etc), + // We will honor the user_whitelist() if it is there and populated. + // Otherwise we default to allowing new users. + values_cache_.SetBoolean(kAccountsPrefAllowNewUser, true); + } else { + values_cache_.SetBoolean(kAccountsPrefAllowNewUser, + pol.user_whitelist().user_whitelist_size() == 0); + } + + values_cache_.SetBoolean( + kAccountsPrefAllowGuest, + !pol.has_guest_mode_enabled() || + !pol.guest_mode_enabled().has_guest_mode_enabled() || + pol.guest_mode_enabled().guest_mode_enabled()); + + values_cache_.SetBoolean( + kAccountsPrefShowUserNamesOnSignIn, + !pol.has_show_user_names() || + !pol.show_user_names().has_show_user_names() || + pol.show_user_names().show_user_names()); + + values_cache_.SetBoolean( + kSignedDataRoamingEnabled, + pol.has_data_roaming_enabled() && + pol.data_roaming_enabled().has_data_roaming_enabled() && + pol.data_roaming_enabled().data_roaming_enabled()); + + // TODO(cmasone): NOTIMPLEMENTED() once http://crosbug.com/13052 is fixed. + std::string serialized; + if (pol.has_device_proxy_settings() && + pol.device_proxy_settings().SerializeToString(&serialized)) { + values_cache_.SetString(kSettingProxyEverywhere, serialized); + } + + if (!pol.has_release_channel() || + !pol.release_channel().has_release_channel()) { + // Default to an invalid channel (will be ignored). + values_cache_.SetString(kReleaseChannel, ""); + } else { + values_cache_.SetString(kReleaseChannel, + pol.release_channel().release_channel()); + } + + if (pol.has_metrics_enabled()) { + values_cache_.SetBoolean(kStatsReportingPref, + pol.metrics_enabled().metrics_enabled()); + } else { + values_cache_.SetBoolean(kStatsReportingPref, HasOldMetricsFile()); + } + + base::ListValue* list = new base::ListValue(); + const em::UserWhitelistProto& whitelist_proto = pol.user_whitelist(); + const RepeatedPtrField<std::string>& whitelist = + whitelist_proto.user_whitelist(); + for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin(); + it != whitelist.end(); ++it) { + list->Append(base::Value::CreateStringValue(*it)); + } + values_cache_.SetValue(kAccountsPrefUsers, list); +} + +void DeviceSettingsProvider::ApplyMetricsSetting(bool use_file, + bool new_value) const { + // 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_file) { + new_value = HasOldMetricsFile(); + // Make sure the values will get eventually written to the policy file. + migration_helper_->AddMigrationValue( + kStatsReportingPref, base::Value::CreateBooleanValue(new_value)); + migration_helper_->MigrateValues(); + LOG(INFO) << "No metrics policy set will revert to checking " + << "consent file which is " + << (new_value ? "on." : "off."); + } + VLOG(1) << "Metrics policy is being set to : " << new_value + << "(use file : " << use_file << ")"; + // TODO(pastarmovj): Remove this once we don't need to regenerate the + // consent file for the GUID anymore. + OptionsUtil::ResolveMetricsReportingEnabled(new_value); +} + +void DeviceSettingsProvider::ApplyRoamingSetting(bool new_value) const { + 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 if (device_value != new_value) { + cros->SetCellularDataRoamingAllowed(new_value); + } + } +} + +void DeviceSettingsProvider::ApplySideEffects() const { + const em::PolicyData data = policy(); + em::ChromeDeviceSettingsProto pol; + pol.ParseFromString(data.policy_value()); + // First migrate metrics settings as needed. + if (pol.has_metrics_enabled()) + ApplyMetricsSetting(false, pol.metrics_enabled().metrics_enabled()); + else + ApplyMetricsSetting(true, false); + // Next set the roaming setting as needed. + ApplyRoamingSetting(pol.has_data_roaming_enabled() ? + pol.data_roaming_enabled().data_roaming_enabled() : false); +} + +const base::Value* DeviceSettingsProvider::Get(const std::string& path) const { + if (IsControlledSetting(path)) { + const base::Value* value; + if (values_cache_.GetValue(path, &value)) + return value; + } else { + NOTREACHED() << "Trying to get non cros setting."; + } + + return NULL; +} + +bool DeviceSettingsProvider::GetTrusted(const std::string& path, + const base::Closure& callback) { + if (!IsControlledSetting(path)) { + NOTREACHED(); + return true; + } + + if (RequestTrustedEntity()) { + return true; + } else { + if (!callback.is_null()) + callbacks_.push_back(callback); + return false; + } +} + +bool DeviceSettingsProvider::HandlesSetting(const std::string& path) const { + return IsControlledSetting(path); +} + +bool DeviceSettingsProvider::RequestTrustedEntity() { + if (ownership_status_ == OwnershipService::OWNERSHIP_NONE) + return true; + return trusted_; +} + +void DeviceSettingsProvider::OnStorePolicyCompleted( + SignedSettings::ReturnCode code) { + // In any case reload the policy cache to now. + if (code != SignedSettings::SUCCESS) + Reload(); + else + trusted_ = true; +} + +void DeviceSettingsProvider::OnRetrievePolicyCompleted( + SignedSettings::ReturnCode code, + const em::PolicyFetchResponse& policy_data) { + switch (code) { + case SignedSettings::SUCCESS: { + DCHECK(policy_data.has_policy_data()); + policy_.ParseFromString(policy_data.policy_data()); + signed_settings_cache::Store(policy(), + g_browser_process->local_state()); + UpdateValuesCache(); + trusted_ = true; + for (size_t i = 0; i < callbacks_.size(); ++i) + callbacks_[i].Run(); + callbacks_.clear(); + // TODO(pastarmovj): Make those side effects responsibility of the + // respective subsystems. + ApplySideEffects(); + break; + } + case SignedSettings::NOT_FOUND: + case SignedSettings::KEY_UNAVAILABLE: { + if (ownership_status_ != OwnershipService::OWNERSHIP_TAKEN) + NOTREACHED() << "No policies present yet, will use the temp storage."; + break; + } + case SignedSettings::BAD_SIGNATURE: + case SignedSettings::OPERATION_FAILED: { + LOG(ERROR) << "Failed to retrieve cros policies. Reason:" << code; + if (retries_left_ > 0) { + retries_left_ -= 1; + Reload(); + return; + } + LOG(ERROR) << "No retries left"; + break; + } + } +} + +} // namespace chromeos diff --git a/chrome/browser/chromeos/device_settings_provider.h b/chrome/browser/chromeos/device_settings_provider.h new file mode 100644 index 0000000..85ac3ed --- /dev/null +++ b/chrome/browser/chromeos/device_settings_provider.h @@ -0,0 +1,131 @@ +// 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. + +#ifndef CHROME_BROWSER_CHROMEOS_DEVICE_SETTINGS_PROVIDER_H_ +#define CHROME_BROWSER_CHROMEOS_DEVICE_SETTINGS_PROVIDER_H_ +#pragma once + +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/callback.h" +#include "base/hash_tables.h" +#include "chrome/browser/chromeos/cros_settings_provider.h" +#include "chrome/browser/chromeos/login/signed_settings_helper.h" +#include "chrome/browser/chromeos/signed_settings_migration_helper.h" +#include "chrome/browser/policy/proto/device_management_backend.pb.h" +#include "content/public/browser/notification_registrar.h" + +namespace em = enterprise_management; + +class PrefService; + +namespace base { +class ListValue; +} + +namespace chromeos { + +class OwnershipService; + +// CrosSettingsProvider implementation that works with SignedSettings. +class DeviceSettingsProvider : public CrosSettingsProvider, + public content::NotificationObserver { + public: + DeviceSettingsProvider(); + virtual ~DeviceSettingsProvider(); + + // CrosSettingsProvider implementation. + virtual const base::Value* Get(const std::string& path) const OVERRIDE; + virtual bool GetTrusted(const std::string& path, + const base::Closure& callback) OVERRIDE; + virtual bool HandlesSetting(const std::string& path) const OVERRIDE; + virtual void Reload() OVERRIDE; + + private: + // CrosSettingsProvider implementation: + virtual void DoSet(const std::string& path, + const base::Value& value) OVERRIDE; + + // content::NotificationObserver implementation: + virtual void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) OVERRIDE; + + const em::PolicyData policy() const; + + // Populates in-memory cache from the local_state cache that is used to store + // signed settings before the device is owned and to speed up policy + // availability before the policy blob is fetched on boot. + void RetrieveCachedData(); + + // Stores a value in the signed settings. If the device is not owned yet the + // data ends up only in the local_state cache and is serialized once ownership + // is acquired. + void SetInPolicy(const std::string& prop, const base::Value& value); + + // Finalizes stores to the policy file if the cache is dirty. + void FinishSetInPolicy(const std::string& prop, + const base::Value* value, + SignedSettings::ReturnCode code, + const em::PolicyFetchResponse& policy); + + // Parses the policy cache and fills the cache of base::Value objects. + void UpdateValuesCache(); + + // Applies the metrics policy and if not set migrates the legacy file. + void ApplyMetricsSetting(bool use_file, bool new_value) const; + + // Applies the data roaming policy. + void ApplyRoamingSetting(bool new_value) const; + + // Applies any changes of the policies that are not handled by the respective + // subsystms. + void ApplySideEffects() const; + + // Called right before boolean property is changed. + void OnBooleanPropertyChange(const std::string& path, bool new_value); + + // Checks if the current cache value can be trusted for being representative + // for the disk cache. + bool RequestTrustedEntity(); + + // Called right after signed value was checked. + void OnPropertyRetrieve(const std::string& path, + const base::Value* value, + bool use_default_value); + + // Callback of StorePolicyOp for ordinary policy stores. + void OnStorePolicyCompleted(SignedSettings::ReturnCode code); + + // Callback of RetrievePolicyOp for ordinary policy [re]loads. + void OnRetrievePolicyCompleted(SignedSettings::ReturnCode code, + const em::PolicyFetchResponse& policy); + + // Pending callbacks that need to be invoked after settings verification. + std::vector<base::Closure> callbacks_; + + OwnershipService::Status ownership_status_; + mutable scoped_ptr<SignedSettingsMigrationHelper> migration_helper_; + + content::NotificationRegistrar registrar_; + + // In order to guard against occasional failure to fetch a property + // we allow for some number of retries. + int retries_left_; + + em::PolicyData policy_; + bool trusted_; + + PrefValueMap values_cache_; + + friend class SignedSettingsHelper; + + DISALLOW_COPY_AND_ASSIGN(DeviceSettingsProvider); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_DEVICE_SETTINGS_PROVIDER_H_ diff --git a/chrome/browser/chromeos/login/mock_ownership_service.h b/chrome/browser/chromeos/login/mock_ownership_service.h index 74d3953..afeb3f3 100644 --- a/chrome/browser/chromeos/login/mock_ownership_service.h +++ b/chrome/browser/chromeos/login/mock_ownership_service.h @@ -18,9 +18,6 @@ class MockOwnershipService : public OwnershipService { MockOwnershipService(); virtual ~MockOwnershipService(); - MOCK_METHOD1(set_cached_policy, void(const em::PolicyData&)); - MOCK_METHOD0(has_cached_policy, bool(void)); - MOCK_METHOD0(cached_policy, const em::PolicyData&(void)); MOCK_METHOD0(IsAlreadyOwned, bool(void)); MOCK_METHOD1(GetStatus, OwnershipService::Status(bool)); MOCK_METHOD0(StartLoadOwnerKeyAttempt, void(void)); diff --git a/chrome/browser/chromeos/login/mock_signed_settings_helper.h b/chrome/browser/chromeos/login/mock_signed_settings_helper.h index 628b552..162fed1 100644 --- a/chrome/browser/chromeos/login/mock_signed_settings_helper.h +++ b/chrome/browser/chromeos/login/mock_signed_settings_helper.h @@ -17,25 +17,22 @@ class MockSignedSettingsHelper : public chromeos::SignedSettingsHelper { MockSignedSettingsHelper(); virtual ~MockSignedSettingsHelper(); - MOCK_METHOD3(StartStorePropertyOp, - void(const std::string&, const base::Value&, Callback*)); - MOCK_METHOD2(StartRetrieveProperty, - void(const std::string&, Callback*)); MOCK_METHOD2(StartStorePolicyOp, - void(const em::PolicyFetchResponse&, Callback*)); - MOCK_METHOD1(StartRetrievePolicyOp, void(Callback* callback)); - MOCK_METHOD1(CancelCallback, void(Callback*)); + void(const em::PolicyFetchResponse&, + SignedSettingsHelper::StorePolicyCallback)); + MOCK_METHOD1(StartRetrievePolicyOp, + void(SignedSettingsHelper::RetrievePolicyCallback)); private: DISALLOW_COPY_AND_ASSIGN(MockSignedSettingsHelper); }; ACTION_P(MockSignedSettingsHelperStorePolicy, status_code) { - arg1->OnStorePolicyCompleted(status_code); + arg1.Run(status_code); } ACTION_P2(MockSignedSettingsHelperRetrievePolicy, status_code, policy) { - arg0->OnRetrievePolicyCompleted(status_code, policy); + arg0.Run(status_code, policy); } } // namespace chromeos diff --git a/chrome/browser/chromeos/login/owner_manager.cc b/chrome/browser/chromeos/login/owner_manager.cc index 269bd31..00a8009 100644 --- a/chrome/browser/chromeos/login/owner_manager.cc +++ b/chrome/browser/chromeos/login/owner_manager.cc @@ -12,7 +12,7 @@ #include "base/file_util.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/boot_times_loader.h" -#include "chrome/browser/chromeos/login/signed_settings_temp_storage.h" +#include "chrome/browser/chromeos/login/signed_settings_cache.h" #include "chrome/common/chrome_notification_types.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h" diff --git a/chrome/browser/chromeos/login/ownership_service.cc b/chrome/browser/chromeos/login/ownership_service.cc index ffdcf57..184452f 100644 --- a/chrome/browser/chromeos/login/ownership_service.cc +++ b/chrome/browser/chromeos/login/ownership_service.cc @@ -30,7 +30,6 @@ OwnershipService* OwnershipService::GetSharedInstance() { OwnershipService::OwnershipService() : manager_(new OwnerManager), utils_(OwnerKeyUtils::Create()), - policy_(NULL), ownership_status_(OWNERSHIP_UNKNOWN) { notification_registrar_.Add( this, @@ -57,19 +56,6 @@ void OwnershipService::Prewarm() { } } -void OwnershipService::set_cached_policy(const em::PolicyData& pol) { - policy_.reset(pol.New()); - policy_->CheckTypeAndMergeFrom(pol); -} - -bool OwnershipService::has_cached_policy() { - return policy_.get(); -} - -const em::PolicyData& OwnershipService::cached_policy() { - return *(policy_.get()); -} - bool OwnershipService::IsAlreadyOwned() { return file_util::PathExists(utils_->GetOwnerKeyFilePath()); } diff --git a/chrome/browser/chromeos/login/ownership_service.h b/chrome/browser/chromeos/login/ownership_service.h index 458009f..e22bcfd 100644 --- a/chrome/browser/chromeos/login/ownership_service.h +++ b/chrome/browser/chromeos/login/ownership_service.h @@ -16,7 +16,6 @@ #include "base/synchronization/lock.h" #include "chrome/browser/chromeos/login/owner_key_utils.h" #include "chrome/browser/chromeos/login/owner_manager.h" -#include "chrome/browser/policy/proto/device_management_backend.pb.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" @@ -25,7 +24,6 @@ namespace base { template <typename T> struct DefaultLazyInstanceTraits; } -namespace em = enterprise_management; namespace chromeos { class OwnershipService : public content::NotificationObserver { @@ -45,17 +43,6 @@ class OwnershipService : public content::NotificationObserver { // blocking on UI thread. void Prewarm(); - // Owner settings are being re-implemented as a single, signed protobuf - // that is stored by the session manager. Thus, to write a setting, you - // need to have the existing policy, update it, re-sign it, and then have - // it stored. This could be done by requesting the policy every time, or - // by caching it and updating it upon every successful store. - // Caching is faster and easier, so we'll do that. These are the - // getters/setters for the cached policy. - virtual void set_cached_policy(const em::PolicyData& pol); - virtual bool has_cached_policy(); - virtual const em::PolicyData& cached_policy(); - // Sets a new owner key. This will _not_ load the key material from disk, but // rather update Chrome's in-memory copy of the key. |callback| will be // invoked once the operation completes. @@ -139,7 +126,6 @@ class OwnershipService : public content::NotificationObserver { scoped_refptr<OwnerManager> manager_; scoped_refptr<OwnerKeyUtils> utils_; - scoped_ptr<em::PolicyData> policy_; content::NotificationRegistrar notification_registrar_; volatile Status ownership_status_; base::Lock ownership_status_lock_; diff --git a/chrome/browser/chromeos/login/session_manager_observer.cc b/chrome/browser/chromeos/login/session_manager_observer.cc index b4401be..bd778ee 100644 --- a/chrome/browser/chromeos/login/session_manager_observer.cc +++ b/chrome/browser/chromeos/login/session_manager_observer.cc @@ -6,7 +6,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/login/signed_settings.h" -#include "chrome/browser/chromeos/login/signed_settings_temp_storage.h" +#include "chrome/browser/chromeos/login/signed_settings_cache.h" #include "chrome/common/chrome_notification_types.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h" @@ -64,7 +64,7 @@ void SessionManagerObserver::OwnerKeySet(bool success) { // Now owner is assigned and key is generated and we should persist // those settings into signed storage. if (g_browser_process && g_browser_process->local_state()) { - SignedSettingsTempStorage::Finalize(g_browser_process->local_state()); + signed_settings_cache::Finalize(g_browser_process->local_state()); } } diff --git a/chrome/browser/chromeos/login/signed_settings.cc b/chrome/browser/chromeos/login/signed_settings.cc index 32709d5..84b4838 100644 --- a/chrome/browser/chromeos/login/signed_settings.cc +++ b/chrome/browser/chromeos/login/signed_settings.cc @@ -9,17 +9,13 @@ #include "base/bind.h" #include "base/memory/ref_counted.h" -#include "base/stringprintf.h" #include "base/threading/thread_restrictions.h" -#include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/cros/cros_library.h" -#include "chrome/browser/chromeos/cros_settings_names.h" #include "chrome/browser/chromeos/dbus/dbus_thread_manager.h" #include "chrome/browser/chromeos/dbus/session_manager_client.h" #include "chrome/browser/chromeos/login/authenticator.h" #include "chrome/browser/chromeos/login/ownership_service.h" -#include "chrome/browser/chromeos/login/signed_settings_temp_storage.h" #include "chrome/browser/policy/proto/chrome_device_policy.pb.h" #include "chrome/browser/policy/proto/device_management_backend.pb.h" #include "content/public/browser/browser_thread.h" @@ -29,39 +25,14 @@ using content::BrowserThread; using google::protobuf::RepeatedPtrField; using std::string; -// static -const char SignedSettings::kDevicePolicyType[] = "google/chromeos/device"; - -SignedSettings::Relay::Relay(SignedSettings* s) : settings_(s) { -} - -SignedSettings::Relay::~Relay() {} - -void SignedSettings::Relay::OnSettingsOpCompleted( - SignedSettings::ReturnCode code, - const em::PolicyFetchResponse& value) { - if (code == SignedSettings::SUCCESS) { - settings_->Execute(); - return; - } - settings_->Fail(code); -} +const char kDevicePolicyType[] = "google/chromeos/device"; SignedSettings::SignedSettings() - : service_(OwnershipService::GetSharedInstance()), - relay_(NULL), - polfetcher_(NULL) { + : service_(OwnershipService::GetSharedInstance()) { } SignedSettings::~SignedSettings() {} -void SignedSettings::TryToFetchPolicyAndCallBack() { - relay_.reset(new Relay(this)); - polfetcher_ = SignedSettings::CreateRetrievePolicyOp(relay_.get()); - polfetcher_->set_service(service_); - polfetcher_->Execute(); -} - // static bool SignedSettings::PolicyIsSane(const em::PolicyFetchResponse& value, em::PolicyData* poldata) { @@ -83,64 +54,6 @@ SignedSettings::ReturnCode SignedSettings::MapKeyOpCode( KEY_UNAVAILABLE : BAD_SIGNATURE); } -class StorePropertyOp : public SignedSettings, - public SignedSettings::Delegate<bool> { - public: - StorePropertyOp(const std::string& name, - const base::Value& value, - SignedSettings::Delegate<bool>* d); - virtual ~StorePropertyOp(); - void Execute(); - void Fail(SignedSettings::ReturnCode code); - void Succeed(bool value); - // Implementation of OwnerManager::Delegate - void OnKeyOpComplete(const OwnerManager::KeyOpCode return_code, - const std::vector<uint8>& payload); - // Implementation of SignedSettings::Delegate - void OnSettingsOpCompleted(ReturnCode code, bool value); - - private: - void SetInPolicy(const std::string& prop, - const base::Value& value, - em::PolicyData* poldata); - // Always call d_->OnSettingOpCompleted() via this call. - // It guarantees that the callback will not be triggered until _after_ - // Execute() returns, which is implicitly assumed by SignedSettingsHelper - // in some cases. - void PerformCallback(SignedSettings::ReturnCode code, bool value); - - std::string name_; - scoped_ptr<base::Value> value_; - SignedSettings::Delegate<bool>* d_; - em::PolicyFetchResponse to_store_; - scoped_refptr<SignedSettings> store_op_; -}; - -class RetrievePropertyOp : public SignedSettings { - public: - RetrievePropertyOp(const std::string& name, - SignedSettings::Delegate<const base::Value*>* d); - virtual ~RetrievePropertyOp(); - void Execute(); - void Fail(SignedSettings::ReturnCode code); - void Succeed(const base::Value* value); - // Implementation of OwnerManager::Delegate::OnKeyOpComplete() - void OnKeyOpComplete(const OwnerManager::KeyOpCode return_code, - const std::vector<uint8>& payload); - - private: - base::Value* LookUpInPolicy(const std::string& prop); - // Always call d_->OnSettingOpCompleted() via this call. - // It guarantees that the callback will not be triggered until _after_ - // Execute() returns, which is implicitly assumed by SignedSettingsHelper - // in some cases. - void PerformCallback(SignedSettings::ReturnCode code, - const base::Value* value); - - std::string name_; - SignedSettings::Delegate<const base::Value*>* d_; -}; - class StorePolicyOp : public SignedSettings { public: StorePolicyOp(em::PolicyFetchResponse* policy, @@ -195,23 +108,6 @@ class RetrievePolicyOp : public SignedSettings { }; // static -SignedSettings* SignedSettings::CreateStorePropertyOp( - const std::string& name, - const base::Value& value, - SignedSettings::Delegate<bool>* d) { - DCHECK(d != NULL); - return new StorePropertyOp(name, value, d); -} - -// static -SignedSettings* SignedSettings::CreateRetrievePropertyOp( - const std::string& name, - SignedSettings::Delegate<const base::Value*>* d) { - DCHECK(d != NULL); - return new RetrievePropertyOp(name, d); -} - -// static SignedSettings* SignedSettings::CreateStorePolicyOp( em::PolicyFetchResponse* policy, SignedSettings::Delegate<bool>* d) { @@ -227,314 +123,6 @@ SignedSettings* SignedSettings::CreateRetrievePolicyOp( return new RetrievePolicyOp(d); } -StorePropertyOp::StorePropertyOp(const std::string& name, - const base::Value& value, - SignedSettings::Delegate<bool>* d) - : name_(name), - value_(value.DeepCopy()), - d_(d), - store_op_(NULL) { -} - -StorePropertyOp::~StorePropertyOp() {} - -void StorePropertyOp::Execute() { - if (service_->GetStatus(true) != OwnershipService::OWNERSHIP_TAKEN) { - if (g_browser_process && - g_browser_process->local_state() && - SignedSettingsTempStorage::Store(name_, *value_, - g_browser_process->local_state())) { - Succeed(true); - return; - } - } - if (!service_->has_cached_policy()) { - TryToFetchPolicyAndCallBack(); - return; - } - // Posts a task to the FILE thread to sign policy. - em::PolicyData to_sign; - to_sign.CheckTypeAndMergeFrom(service_->cached_policy()); - SetInPolicy(name_, *value_, &to_sign); - to_store_.set_policy_data(to_sign.SerializeAsString()); - service_->StartSigningAttempt(to_store_.policy_data(), this); -} - -void StorePropertyOp::Fail(SignedSettings::ReturnCode code) { - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&StorePropertyOp::PerformCallback, this, code, false)); -} - -void StorePropertyOp::Succeed(bool value) { - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&StorePropertyOp::PerformCallback, this, SUCCESS, value)); -} - -void StorePropertyOp::OnKeyOpComplete(const OwnerManager::KeyOpCode return_code, - const std::vector<uint8>& sig) { - // Ensure we're on the UI thread, due to the need to send DBus traffic. - if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&StorePropertyOp::OnKeyOpComplete, this, return_code, sig)); - return; - } - VLOG(2) << "StorePropertyOp::OnKeyOpComplete return_code = " << return_code; - // Now, sure we're on the UI thread. - if (return_code == OwnerManager::SUCCESS) { - to_store_.set_policy_data_signature( - std::string(reinterpret_cast<const char*>(&sig[0]), sig.size())); - store_op_ = CreateStorePolicyOp(&to_store_, this); - // d_->OnSettingsOpCompleted() will be called by this call. - store_op_->Execute(); - } else { - Fail(SignedSettings::MapKeyOpCode(return_code)); - } -} - -void StorePropertyOp::OnSettingsOpCompleted(ReturnCode code, bool value) { - if (value && to_store_.has_policy_data()) { - em::PolicyData poldata; - poldata.ParseFromString(to_store_.policy_data()); - service_->set_cached_policy(poldata); - Succeed(value); - return; - } - Fail(NOT_FOUND); -} - -void StorePropertyOp::SetInPolicy(const std::string& prop, - const base::Value& value, - em::PolicyData* poldata) { - em::ChromeDeviceSettingsProto pol; - pol.ParseFromString(poldata->policy_value()); - if (prop == kAccountsPrefAllowNewUser) { - em::AllowNewUsersProto* allow = pol.mutable_allow_new_users(); - bool allow_value; - if (value.GetAsBoolean(&allow_value)) - allow->set_allow_new_users(allow_value); - else - NOTREACHED(); - } else if (prop == kAccountsPrefAllowGuest) { - em::GuestModeEnabledProto* guest = pol.mutable_guest_mode_enabled(); - bool guest_value; - if (value.GetAsBoolean(&guest_value)) - guest->set_guest_mode_enabled(guest_value); - else - NOTREACHED(); - } else if (prop == kAccountsPrefShowUserNamesOnSignIn) { - em::ShowUserNamesOnSigninProto* show = pol.mutable_show_user_names(); - bool show_value; - if (value.GetAsBoolean(&show_value)) - show->set_show_user_names(show_value); - else - NOTREACHED(); - } else if (prop == kSignedDataRoamingEnabled) { - em::DataRoamingEnabledProto* roam = pol.mutable_data_roaming_enabled(); - bool roaming_value; - if (value.GetAsBoolean(&roaming_value)) - roam->set_data_roaming_enabled(roaming_value); - else - NOTREACHED(); - } else if (prop == kSettingProxyEverywhere) { - // TODO(cmasone): NOTIMPLEMENTED() once http://crosbug.com/13052 is fixed. - std::string proxy_value; - if (value.GetAsString(&proxy_value)) { - bool success = - pol.mutable_device_proxy_settings()->ParseFromString(proxy_value); - DCHECK(success); - } else { - NOTREACHED(); - } - } else if (prop == kReleaseChannel) { - em::ReleaseChannelProto* release_channel = pol.mutable_release_channel(); - std::string channel_value; - if (value.GetAsString(&channel_value)) - release_channel->set_release_channel(channel_value); - else - NOTREACHED(); - } else if (prop == kStatsReportingPref) { - em::MetricsEnabledProto* metrics = pol.mutable_metrics_enabled(); - bool metrics_value; - if (value.GetAsBoolean(&metrics_value)) - metrics->set_metrics_enabled(metrics_value); - else - NOTREACHED(); - } else if (prop == kAccountsPrefUsers) { - em::UserWhitelistProto* whitelist_proto = pol.mutable_user_whitelist(); - whitelist_proto->clear_user_whitelist(); - const base::ListValue& users = static_cast<const base::ListValue&>(value); - for (base::ListValue::const_iterator i = users.begin(); - i != users.end(); ++i) { - std::string email; - if ((*i)->GetAsString(&email)) - whitelist_proto->add_user_whitelist(email.c_str()); - } - } else if (prop == kDeviceOwner) { - // We don't serialize this one to the policy blob. - } else { - NOTREACHED(); - } - poldata->set_policy_value(pol.SerializeAsString()); -} - -void StorePropertyOp::PerformCallback(SignedSettings::ReturnCode code, - bool value) { - d_->OnSettingsOpCompleted(code, value); -} - -RetrievePropertyOp::RetrievePropertyOp( - const std::string& name, - SignedSettings::Delegate<const base::Value*>* d) - : name_(name), - d_(d) { -} - -RetrievePropertyOp::~RetrievePropertyOp() {} - -void RetrievePropertyOp::Execute() { - base::Value* value; - // TODO(dilmah): Fix the race: - // At the moment when device becomes owned there is lapse of time after - // device has been owned and before temp_storage settings are finally - // persisted into signed settings. - // In this lapse of time Retrieve loses access to those settings. - if (service_->GetStatus(true) != OwnershipService::OWNERSHIP_TAKEN) { - if (g_browser_process && - g_browser_process->local_state() && - SignedSettingsTempStorage::Retrieve( - name_, &value, g_browser_process->local_state())) { - Succeed(value->DeepCopy()); - return; - } - } - - if (!service_->has_cached_policy()) { - TryToFetchPolicyAndCallBack(); - return; - } - value = LookUpInPolicy(name_); - if (!value) - Fail(NOT_FOUND); - else - Succeed(value); -} - -void RetrievePropertyOp::Fail(SignedSettings::ReturnCode code) { - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&RetrievePropertyOp::PerformCallback, this, - code, static_cast<const base::Value*>(NULL))); -} - -void RetrievePropertyOp::Succeed(const base::Value* value) { - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&RetrievePropertyOp::PerformCallback, this, - SUCCESS, base::Owned(value))); -} - -// DEPRECATED. -void RetrievePropertyOp::OnKeyOpComplete( - const OwnerManager::KeyOpCode return_code, - const std::vector<uint8>& sig) { - NOTREACHED(); -} - -base::Value* RetrievePropertyOp::LookUpInPolicy(const std::string& prop) { - if (prop == kDeviceOwner) { - const em::PolicyData& data = service_->cached_policy(); - if (data.has_username() && !data.has_request_token()) - return base::Value::CreateStringValue(data.username()); - } - VLOG(2) << "Looking up " << prop; - em::ChromeDeviceSettingsProto pol; - pol.ParseFromString(service_->cached_policy().policy_value()); - if (prop == kAccountsPrefAllowNewUser) { - if (pol.has_allow_new_users() && - pol.allow_new_users().has_allow_new_users() && - pol.allow_new_users().allow_new_users()) { - // New users allowed, user_whitelist() ignored. - return base::Value::CreateBooleanValue(true); - } - // If we have the allow_new_users bool, and it is true, we honor that above. - // In all other cases (don't have it, have it and it is set to false, etc), - // We will honor the user_whitelist() if it is there and populated. - // Otherwise we default to allowing new users. - if (!pol.has_user_whitelist()) - return base::Value::CreateBooleanValue(true); - return base::Value::CreateBooleanValue( - pol.user_whitelist().user_whitelist_size() == 0); - - } else if (prop == kAccountsPrefAllowGuest) { - if (!pol.has_guest_mode_enabled() || - !pol.guest_mode_enabled().has_guest_mode_enabled()) { - // Default to allowing guests; - return base::Value::CreateBooleanValue(true); - } - return base::Value::CreateBooleanValue( - pol.guest_mode_enabled().guest_mode_enabled()); - - } else if (prop == kAccountsPrefShowUserNamesOnSignIn) { - if (!pol.has_show_user_names() || - !pol.show_user_names().has_show_user_names()) { - // Default to showing pods on the login screen; - return base::Value::CreateBooleanValue(true); - } - return base::Value::CreateBooleanValue( - pol.show_user_names().show_user_names()); - - } else if (prop == kSignedDataRoamingEnabled) { - if (!pol.has_data_roaming_enabled() || - !pol.data_roaming_enabled().has_data_roaming_enabled()) { - // Default to disabling cellular data roaming; - return base::Value::CreateBooleanValue(false); - } - return base::Value::CreateBooleanValue( - pol.data_roaming_enabled().data_roaming_enabled()); - - } else if (prop == kSettingProxyEverywhere) { - // TODO(cmasone): NOTIMPLEMENTED() once http://crosbug.com/13052 is fixed. - std::string serialized; - if (pol.has_device_proxy_settings() && - pol.device_proxy_settings().SerializeToString(&serialized)) { - return base::Value::CreateStringValue(serialized); - } - - } else if (prop == kReleaseChannel) { - if (!pol.has_release_channel() || - !pol.release_channel().has_release_channel()) { - // Default to an invalid channel (will be ignored). - return base::Value::CreateStringValue(""); - } - return base::Value::CreateStringValue( - pol.release_channel().release_channel()); - - } else if (prop == kStatsReportingPref) { - if (pol.has_metrics_enabled()) { - return base::Value::CreateBooleanValue( - pol.metrics_enabled().metrics_enabled()); - } - } else if (prop == kAccountsPrefUsers) { - base::ListValue* list = new base::ListValue(); - const em::UserWhitelistProto& whitelist_proto = pol.user_whitelist(); - const RepeatedPtrField<string>& whitelist = - whitelist_proto.user_whitelist(); - for (RepeatedPtrField<string>::const_iterator it = whitelist.begin(); - it != whitelist.end(); ++it) { - list->Append(base::Value::CreateStringValue(*it)); - } - return list; - } - return NULL; -} - -void RetrievePropertyOp::PerformCallback(SignedSettings::ReturnCode code, - const base::Value* value) { - d_->OnSettingsOpCompleted(code, value); -} StorePolicyOp::StorePolicyOp(em::PolicyFetchResponse* policy, SignedSettings::Delegate<bool>* d) @@ -572,7 +160,6 @@ void StorePolicyOp::Succeed(bool ignored) { bool to_ret = true; em::PolicyData poldata; if (SignedSettings::PolicyIsSane(*policy_, &poldata)) { - service_->set_cached_policy(poldata); } else { code = NOT_FOUND; to_ret = false; @@ -642,7 +229,6 @@ void RetrievePolicyOp::Fail(SignedSettings::ReturnCode code) { void RetrievePolicyOp::Succeed(const em::PolicyFetchResponse& value) { em::PolicyData poldata; if (SignedSettings::PolicyIsSane(value, &poldata)) { - service_->set_cached_policy(poldata); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(&RetrievePolicyOp::PerformCallback, this, SUCCESS, value)); diff --git a/chrome/browser/chromeos/login/signed_settings.h b/chrome/browser/chromeos/login/signed_settings.h index 45327cb..18ddf35 100644 --- a/chrome/browser/chromeos/login/signed_settings.h +++ b/chrome/browser/chromeos/login/signed_settings.h @@ -14,17 +14,9 @@ #include "base/memory/scoped_ptr.h" #include "chrome/browser/chromeos/login/owner_manager.h" -// There are two categories of operations that can be performed on the -// Chrome OS owner-signed settings store: -// 1) doing stuff to the whitelist (adding/removing/checking) -// 2) Storing/Retrieving arbitrary name=value pairs +// There are two operations that can be performed on the Chrome OS owner-signed +// settings store: Storing and Retrieving the policy blob. // -// Unfortunately, it is currently a limitation that only one of each -// category can be in-flight at a time. You can be doing exactly one thing -// to the whitelist, and exactly one thing to the property store at a time. -// I've filed an issue on me to remove that restriction. -// http://code.google.com/p/chromium-os/issues/detail?id=6415 - // The pattern of use here is that the caller instantiates some // subclass of SignedSettings by calling one of the create // methods. Then, call Execute() on this object from the UI @@ -45,6 +37,8 @@ namespace em = enterprise_management; namespace chromeos { class OwnershipService; +extern const char kDevicePolicyType[]; + class SignedSettings : public base::RefCountedThreadSafe<SignedSettings>, public OwnerManager::Delegate { public: @@ -66,17 +60,6 @@ class SignedSettings : public base::RefCountedThreadSafe<SignedSettings>, SignedSettings(); virtual ~SignedSettings(); - // These are both "property" operations, and only one instance of - // one type can be in flight at a time. - static SignedSettings* CreateStorePropertyOp( - const std::string& name, - const base::Value& value, - SignedSettings::Delegate<bool>* d); - - static SignedSettings* CreateRetrievePropertyOp( - const std::string& name, - SignedSettings::Delegate<const base::Value*>* d); - // These are both "policy" operations, and only one instance of // one type can be in flight at a time. static SignedSettings* CreateStorePolicyOp( @@ -102,34 +85,12 @@ class SignedSettings : public base::RefCountedThreadSafe<SignedSettings>, void set_service(OwnershipService* service) { service_ = service; } - void TryToFetchPolicyAndCallBack(); - OwnershipService* service_; private: friend class SignedSettingsTest; friend class SignedSettingsHelperTest; - class Relay - : public SignedSettings::Delegate<const em::PolicyFetchResponse&> { - public: - // |s| must outlive your Relay instance. - explicit Relay(SignedSettings* s); - virtual ~Relay(); - // Implementation of SignedSettings::Delegate - virtual void OnSettingsOpCompleted( - SignedSettings::ReturnCode code, - const em::PolicyFetchResponse& value) OVERRIDE; - private: - SignedSettings* settings_; - DISALLOW_COPY_AND_ASSIGN(Relay); - }; - - // Format of this string is documented in device_management_backend.proto. - static const char kDevicePolicyType[]; - - scoped_ptr<Relay> relay_; - scoped_refptr<SignedSettings> polfetcher_; DISALLOW_COPY_AND_ASSIGN(SignedSettings); }; diff --git a/chrome/browser/chromeos/login/signed_settings_cache.cc b/chrome/browser/chromeos/login/signed_settings_cache.cc new file mode 100644 index 0000000..878149b --- /dev/null +++ b/chrome/browser/chromeos/login/signed_settings_cache.cc @@ -0,0 +1,114 @@ +// 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/login/signed_settings_cache.h" + +#include "base/base64.h" +#include "base/bind.h" +#include "base/values.h" +#include "chrome/browser/chromeos/login/ownership_service.h" +#include "chrome/browser/chromeos/login/signed_settings_helper.h" +#include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/prefs/scoped_user_pref_update.h" +#include "chrome/common/pref_names.h" + +using content::BrowserThread; + +namespace chromeos { + +namespace { + +void OnStorePolicyCompleted(SignedSettings::ReturnCode code) { + if (code != SignedSettings::SUCCESS) + LOG(ERROR) << "Couldn't save temp store to the policy blob. code: " << code; +} + +void FinishFinalize(PrefService* local_state, + SignedSettings::ReturnCode code, + const em::PolicyFetchResponse& policy) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + if (code != SignedSettings::SUCCESS) { + LOG(ERROR) << "Can't finalize temp store error code:" << code; + return; + } + + if (local_state) { + std::string encoded = + local_state->GetString(prefs::kSignedSettingsCache); + std::string policy_string; + if (!base::Base64Decode(encoded, &policy_string)) { + LOG(WARNING) << "Can't decode policy from base64 on finalizing."; + return; + } + + em::PolicyData merging_policy_data; + if (!merging_policy_data.ParseFromString(policy_string)) { + LOG(WARNING) << "Can't decode policy from string on finalizing."; + return; + } + + em::PolicyFetchResponse policy_envelope = policy; + DCHECK(policy_envelope.has_policy_data()); + em::PolicyData base_policy_data; + base_policy_data.ParseFromString(policy_envelope.policy_data()); + // Merge only the policy value as we should never ever rewrite the other + // fields of the PolicyData protobuf. + base_policy_data.set_policy_value(merging_policy_data.policy_value()); + policy_envelope.set_policy_data(base_policy_data.SerializeAsString()); + DCHECK(base_policy_data.has_username()); + policy_envelope.clear_policy_data_signature(); + SignedSettingsHelper::Get()->StartStorePolicyOp( + policy_envelope, base::Bind(&OnStorePolicyCompleted)); + } +} + +} // namespace + +namespace signed_settings_cache { + +void RegisterPrefs(PrefService* local_state) { + local_state->RegisterStringPref(prefs::kSignedSettingsCache, + "invalid", + PrefService::UNSYNCABLE_PREF); +} + +bool Store(const em::PolicyData& policy, PrefService* local_state) { + if (local_state) { + std::string policy_string = policy.SerializeAsString(); + std::string encoded; + if (!base::Base64Encode(policy_string, &encoded)) { + LOG(WARNING) << "Can't encode policy in base64."; + return false; + } + local_state->SetString(prefs::kSignedSettingsCache, encoded); + return true; + } + return false; +} + +bool Retrieve(em::PolicyData *policy, PrefService* local_state) { + if (local_state) { + std::string encoded = + local_state->GetString(prefs::kSignedSettingsCache); + std::string policy_string; + if (!base::Base64Decode(encoded, &policy_string)) { + LOG(WARNING) << "Can't decode policy from base64."; + return false; + } + return policy->ParseFromString(policy_string); + } + return false; +} + +void Finalize(PrefService* local_state) { + // Reload the initial policy blob, apply settings from temp storage, + // and write back the blob. + SignedSettingsHelper::Get()->StartRetrievePolicyOp( + base::Bind(FinishFinalize, local_state)); +} + +} // namespace signed_settings_cache + +} // namespace chromeos diff --git a/chrome/browser/chromeos/login/signed_settings_cache.h b/chrome/browser/chromeos/login/signed_settings_cache.h new file mode 100644 index 0000000..4449a38 --- /dev/null +++ b/chrome/browser/chromeos/login/signed_settings_cache.h @@ -0,0 +1,43 @@ +// 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. + +#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_SIGNED_SETTINGS_CACHE_H_ +#define CHROME_BROWSER_CHROMEOS_LOGIN_SIGNED_SETTINGS_CACHE_H_ +#pragma once + +#include <string> + +#include "base/basictypes.h" +#include "base/values.h" +#include "chrome/browser/policy/proto/chrome_device_policy.pb.h" +#include "chrome/browser/policy/proto/device_management_backend.pb.h" + +namespace em = enterprise_management; + +class PrefService; + +namespace chromeos { + +// There is need (metrics at OOBE stage) to store settings +// (that normally would go into SignedSettings storage) +// before owner has been assigned (hence no key is available). +// This set of functions serves as a transient storage in that case. +namespace signed_settings_cache { +// Registers required pref section. +void RegisterPrefs(PrefService* local_state); + +// Stores a new policy blob inside the cache stored in |local_state|. +bool Store(const em::PolicyData &policy, PrefService* local_state); + +// Retrieves the policy blob from the cache stored in |local_state|. +bool Retrieve(em::PolicyData *policy, PrefService* local_state); + +// Call this after owner has been assigned to persist settings +// into SignedSettings storage. +void Finalize(PrefService* local_state); +} // namespace signed_settings_cache + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_LOGIN_SIGNED_SETTINGS_CACHE_H_ diff --git a/chrome/browser/chromeos/login/signed_settings_cache_unittest.cc b/chrome/browser/chromeos/login/signed_settings_cache_unittest.cc new file mode 100644 index 0000000..9683b47 --- /dev/null +++ b/chrome/browser/chromeos/login/signed_settings_cache_unittest.cc @@ -0,0 +1,57 @@ +// 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/login/signed_settings_cache.h" + +#include "chrome/browser/policy/proto/chrome_device_policy.pb.h" +#include "chrome/browser/policy/proto/device_management_backend.pb.h" +#include "chrome/common/pref_names.h" +#include "chrome/test/base/testing_pref_service.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace em = enterprise_management; + +namespace chromeos { + +class SignedSettingsCacheTest : public testing::Test { + protected: + virtual void SetUp() { + // prepare some data. + policy_.set_policy_type("google/chromeos/device"); + em::ChromeDeviceSettingsProto pol; + pol.mutable_allow_new_users()->set_allow_new_users(false); + policy_.set_policy_value(pol.SerializeAsString()); + + signed_settings_cache::RegisterPrefs(&local_state_); + } + + TestingPrefService local_state_; + em::PolicyData policy_; +}; + +TEST_F(SignedSettingsCacheTest, Basic) { + EXPECT_TRUE(signed_settings_cache::Store(policy_, &local_state_)); + + em::PolicyData policy_out; + EXPECT_TRUE(signed_settings_cache::Retrieve(&policy_out, &local_state_)); + + EXPECT_TRUE(policy_out.has_policy_type()); + EXPECT_TRUE(policy_out.has_policy_value()); + + em::ChromeDeviceSettingsProto pol; + pol.ParseFromString(policy_out.policy_value()); + EXPECT_TRUE(pol.has_allow_new_users()); + EXPECT_FALSE(pol.allow_new_users().allow_new_users()); +} + +TEST_F(SignedSettingsCacheTest, CorruptData) { + EXPECT_TRUE(signed_settings_cache::Store(policy_, &local_state_)); + + local_state_.SetString(prefs::kSignedSettingsCache, "blaaa"); + + em::PolicyData policy_out; + EXPECT_FALSE(signed_settings_cache::Retrieve(&policy_out, &local_state_)); +} + +} // namespace chromeos diff --git a/chrome/browser/chromeos/login/signed_settings_helper.cc b/chrome/browser/chromeos/login/signed_settings_helper.cc index e61cdb1..200dab6 100644 --- a/chrome/browser/chromeos/login/signed_settings_helper.cc +++ b/chrome/browser/chromeos/login/signed_settings_helper.cc @@ -49,15 +49,8 @@ class OpContext { delegate->OnOpStarted(this); } - // Cancels the callback. - void CancelCallback() { - callback_ = NULL; - } - // Cancels the callback and cancels the op if it is not executing. void Cancel() { - CancelCallback(); - if (!executing_) OnOpCompleted(); } @@ -67,20 +60,14 @@ class OpContext { return op_.get(); } - SignedSettingsHelper::Callback* callback() const { - return callback_; - } - void set_delegate(Delegate* delegate) { delegate_ = delegate; } protected: - OpContext(SignedSettingsHelper::Callback* callback, - Delegate* delegate) + explicit OpContext(Delegate* delegate) : executing_(false), - delegate_(delegate), - callback_(callback) { + delegate_(delegate) { } // Creates the op to execute. @@ -98,82 +85,17 @@ class OpContext { Delegate* delegate_; scoped_refptr<SignedSettings> op_; - SignedSettingsHelper::Callback* callback_; -}; - -class StorePropertyOpContext : public SignedSettings::Delegate<bool>, - public OpContext { - public: - StorePropertyOpContext(const std::string& name, - const base::Value& value, - SignedSettingsHelper::Callback* callback, - OpContext::Delegate* delegate) - : OpContext(callback, delegate), - name_(name), - value_(value.DeepCopy()) { - } - - // chromeos::SignedSettings::Delegate implementation - virtual void OnSettingsOpCompleted(SignedSettings::ReturnCode code, - bool unused) OVERRIDE { - VLOG(2) << "OnSettingsOpCompleted, code = " << code; - if (callback_) - callback_->OnStorePropertyCompleted(code, name_, *value_); - OnOpCompleted(); - } - - protected: - // OpContext implemenetation - virtual void CreateOp() OVERRIDE { - op_ = SignedSettings::CreateStorePropertyOp(name_, *value_, this); - } - - private: - std::string name_; - scoped_ptr<base::Value> value_; - - DISALLOW_COPY_AND_ASSIGN(StorePropertyOpContext); }; -class RetrievePropertyOpContext - : public SignedSettings::Delegate<const base::Value*>, +class StorePolicyOpContext + : public SignedSettings::Delegate<bool>, public OpContext { public: - RetrievePropertyOpContext(const std::string& name, - SignedSettingsHelper::Callback* callback, - OpContext::Delegate* delegate) - : OpContext(callback, delegate), - name_(name) { - } - - // chromeos::SignedSettings::Delegate implementation - virtual void OnSettingsOpCompleted(SignedSettings::ReturnCode code, - const base::Value* value) OVERRIDE { - if (callback_) - callback_->OnRetrievePropertyCompleted(code, name_, value); - - OnOpCompleted(); - } - - protected: - // OpContext implemenetation - virtual void CreateOp() OVERRIDE { - op_ = SignedSettings::CreateRetrievePropertyOp(name_, this); - } - - private: - std::string name_; - - DISALLOW_COPY_AND_ASSIGN(RetrievePropertyOpContext); -}; - -class StorePolicyOpContext : public SignedSettings::Delegate<bool>, - public OpContext { - public: StorePolicyOpContext(const em::PolicyFetchResponse& policy, - SignedSettingsHelper::Callback* callback, + SignedSettingsHelper::StorePolicyCallback callback, OpContext::Delegate* delegate) - : OpContext(callback, delegate), + : OpContext(delegate), + callback_(callback), policy_(policy) { } @@ -181,8 +103,7 @@ class StorePolicyOpContext : public SignedSettings::Delegate<bool>, virtual void OnSettingsOpCompleted(SignedSettings::ReturnCode code, bool unused) OVERRIDE { VLOG(2) << "OnSettingsOpCompleted, code = " << code; - if (callback_) - callback_->OnStorePolicyCompleted(code); + callback_.Run(code); OnOpCompleted(); } @@ -193,7 +114,9 @@ class StorePolicyOpContext : public SignedSettings::Delegate<bool>, } private: + SignedSettingsHelper::StorePolicyCallback callback_; em::PolicyFetchResponse policy_; + DISALLOW_COPY_AND_ASSIGN(StorePolicyOpContext); }; @@ -201,17 +124,17 @@ class RetrievePolicyOpContext : public SignedSettings::Delegate<const em::PolicyFetchResponse&>, public OpContext { public: - RetrievePolicyOpContext(SignedSettingsHelper::Callback* callback, + RetrievePolicyOpContext(SignedSettingsHelper::RetrievePolicyCallback callback, OpContext::Delegate* delegate) - : OpContext(callback, delegate) { + : OpContext(delegate), + callback_(callback){ } // chromeos::SignedSettings::Delegate implementation virtual void OnSettingsOpCompleted( SignedSettings::ReturnCode code, const em::PolicyFetchResponse& policy) OVERRIDE { - if (callback_) - callback_->OnRetrievePolicyCompleted(code, policy); + callback_.Run(code, policy); OnOpCompleted(); } @@ -222,6 +145,8 @@ class RetrievePolicyOpContext } private: + SignedSettingsHelper::RetrievePolicyCallback callback_; + DISALLOW_COPY_AND_ASSIGN(RetrievePolicyOpContext); }; @@ -232,15 +157,9 @@ class SignedSettingsHelperImpl : public SignedSettingsHelper, public OpContext::Delegate { public: // SignedSettingsHelper implementation - virtual void StartStorePropertyOp(const std::string& name, - const base::Value& value, - Callback* callback) OVERRIDE; - virtual void StartRetrieveProperty(const std::string& name, - Callback* callback) OVERRIDE; virtual void StartStorePolicyOp(const em::PolicyFetchResponse& policy, - Callback* callback) OVERRIDE; - virtual void StartRetrievePolicyOp(Callback* callback) OVERRIDE; - virtual void CancelCallback(Callback* callback) OVERRIDE; + StorePolicyCallback callback) OVERRIDE; + virtual void StartRetrievePolicyOp(RetrievePolicyCallback callback) OVERRIDE; // OpContext::Delegate implementation virtual void OnOpCreated(OpContext* context); @@ -249,7 +168,7 @@ class SignedSettingsHelperImpl : public SignedSettingsHelper, private: SignedSettingsHelperImpl(); - ~SignedSettingsHelperImpl(); + virtual ~SignedSettingsHelperImpl(); void AddOpContext(OpContext* context); void ClearAll(); @@ -274,48 +193,17 @@ SignedSettingsHelperImpl::~SignedSettingsHelperImpl() { } } -void SignedSettingsHelperImpl::StartStorePropertyOp( - const std::string& name, - const base::Value& value, - SignedSettingsHelper::Callback* callback) { - AddOpContext(new StorePropertyOpContext( - name, - value, - callback, - this)); -} - -void SignedSettingsHelperImpl::StartRetrieveProperty( - const std::string& name, - SignedSettingsHelper::Callback* callback) { - AddOpContext(new RetrievePropertyOpContext( - name, - callback, - this)); -} - void SignedSettingsHelperImpl::StartStorePolicyOp( const em::PolicyFetchResponse& policy, - SignedSettingsHelper::Callback* callback) { + StorePolicyCallback callback) { AddOpContext(new StorePolicyOpContext(policy, callback, this)); } void SignedSettingsHelperImpl::StartRetrievePolicyOp( - SignedSettingsHelper::Callback* callback) { + RetrievePolicyCallback callback) { AddOpContext(new RetrievePolicyOpContext(callback, this)); } -void SignedSettingsHelperImpl::CancelCallback( - SignedSettingsHelper::Callback* callback) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - for (size_t i = 0; i < pending_contexts_.size(); ++i) { - if (pending_contexts_[i]->callback() == callback) { - pending_contexts_[i]->CancelCallback(); - } - } -} - void SignedSettingsHelperImpl::AddOpContext(OpContext* context) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); CHECK(context); diff --git a/chrome/browser/chromeos/login/signed_settings_helper.h b/chrome/browser/chromeos/login/signed_settings_helper.h index 61ed873..a46a2bd 100644 --- a/chrome/browser/chromeos/login/signed_settings_helper.h +++ b/chrome/browser/chromeos/login/signed_settings_helper.h @@ -26,45 +26,19 @@ class SignedSettings; // and handle callbacks destruction before ops completion. class SignedSettingsHelper { public: - class Callback { - public: - // Callback of StorePropertyOp. - virtual void OnStorePropertyCompleted( - SignedSettings::ReturnCode code, - const std::string& name, - const base::Value& value) {} - - // Callback of RetrievePropertyOp. - virtual void OnRetrievePropertyCompleted( - SignedSettings::ReturnCode code, - const std::string& name, - const base::Value* value) {} - - // Callback of StorePolicyOp. - virtual void OnStorePolicyCompleted( - SignedSettings::ReturnCode code) {} - - // Callback of RetrievePolicyOp. - virtual void OnRetrievePolicyCompleted( - SignedSettings::ReturnCode code, - const em::PolicyFetchResponse& policy) {} - }; + typedef base::Callback<void(SignedSettings::ReturnCode)> StorePolicyCallback; + typedef base::Callback<void(SignedSettings::ReturnCode, + const em::PolicyFetchResponse&)> RetrievePolicyCallback; // Class factory static SignedSettingsHelper* Get(); // Functions to start signed settings ops. - virtual void StartStorePropertyOp(const std::string& name, - const base::Value& value, - Callback* callback) = 0; - virtual void StartRetrieveProperty(const std::string& name, - Callback* callback) = 0; - virtual void StartStorePolicyOp(const em::PolicyFetchResponse& policy, - Callback* callback) = 0; - virtual void StartRetrievePolicyOp(Callback* callback) = 0; - - // Cancels all pending calls of given callback. - virtual void CancelCallback(Callback* callback) = 0; + virtual void StartStorePolicyOp( + const em::PolicyFetchResponse& policy, + StorePolicyCallback callback) = 0; + virtual void StartRetrievePolicyOp( + RetrievePolicyCallback callback) = 0; class TestDelegate { public: diff --git a/chrome/browser/chromeos/login/signed_settings_helper_unittest.cc b/chrome/browser/chromeos/login/signed_settings_helper_unittest.cc index 5cb2e61..9903822 100644 --- a/chrome/browser/chromeos/login/signed_settings_helper_unittest.cc +++ b/chrome/browser/chromeos/login/signed_settings_helper_unittest.cc @@ -4,10 +4,14 @@ #include "chrome/browser/chromeos/login/signed_settings_helper.h" +#include "base/bind.h" #include "base/message_loop.h" #include "chrome/browser/chromeos/cros/cros_library.h" #include "chrome/browser/chromeos/cros_settings_names.h" #include "chrome/browser/chromeos/dbus/dbus_thread_manager.h" +#include "chrome/browser/chromeos/dbus/mock_dbus_thread_manager.h" +#include "chrome/browser/chromeos/dbus/mock_session_manager_client.h" +#include "chrome/browser/chromeos/login/mock_owner_key_utils.h" #include "chrome/browser/chromeos/login/mock_ownership_service.h" #include "chrome/browser/chromeos/login/owner_manager.h" #include "chrome/browser/chromeos/login/signed_settings.h" @@ -17,51 +21,55 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -using content::BrowserThread; using ::testing::_; using ::testing::A; -using ::testing::AtLeast; using ::testing::InSequence; using ::testing::Invoke; -using ::testing::Return; -using ::testing::ReturnRef; -using ::testing::SaveArg; using ::testing::WithArg; namespace em = enterprise_management; namespace chromeos { -class MockSignedSettingsHelperCallback : public SignedSettingsHelper::Callback { - public: - virtual ~MockSignedSettingsHelperCallback() {} - - MOCK_METHOD3(OnStorePropertyCompleted, void( - SignedSettings::ReturnCode code, - const std::string& name, - const base::Value& value)); - MOCK_METHOD3(OnRetrievePropertyCompleted, void( - SignedSettings::ReturnCode code, - const std::string& name, - const base::Value* value)); -}; +ACTION_P(Retrieve, policy_blob) { arg0.Run(policy_blob); } +ACTION_P(Store, success) { arg1.Run(success); } class SignedSettingsHelperTest : public testing::Test, public SignedSettingsHelper::TestDelegate { public: SignedSettingsHelperTest() - : fake_email_("fakey@example.com"), - fake_prop_(kReleaseChannel), - fake_value_("false"), - message_loop_(MessageLoop::TYPE_UI), - ui_thread_(BrowserThread::UI, &message_loop_), - file_thread_(BrowserThread::FILE), - pending_ops_(0) { + : message_loop_(MessageLoop::TYPE_UI), + ui_thread_(content::BrowserThread::UI, &message_loop_), + file_thread_(content::BrowserThread::FILE, &message_loop_), + pending_ops_(0), + mock_dbus_thread_manager_(new MockDBusThreadManager) { } virtual void SetUp() { - file_thread_.Start(); SignedSettingsHelper::Get()->set_test_delegate(this); - DBusThreadManager::Initialize(); + DBusThreadManager::InitializeForTesting(mock_dbus_thread_manager_); + + fake_policy_data_ = BuildPolicyData(); + std::string data_serialized = fake_policy_data_.SerializeAsString(); + std::string serialized_policy_; + fake_policy_ = BuildProto(data_serialized, + std::string("false"), + &serialized_policy_); + + MockSessionManagerClient* client = + mock_dbus_thread_manager_->mock_session_manager_client(); + // Make sure the mocked out class calls back to notify success on store and + // retrieve ops. + EXPECT_CALL(*client, StorePolicy(_, _)) + .WillRepeatedly(Store(true)); + EXPECT_CALL(*client, RetrievePolicy(_)) + .WillRepeatedly(Retrieve(serialized_policy_)); + + EXPECT_CALL(m_, StartSigningAttempt(_, A<OwnerManager::Delegate*>())) + .WillRepeatedly(WithArg<1>( + Invoke(&SignedSettingsHelperTest::OnKeyOpComplete))); + EXPECT_CALL(m_, StartVerifyAttempt(_, _, A<OwnerManager::Delegate*>())) + .WillRepeatedly(WithArg<2>( + Invoke(&SignedSettingsHelperTest::OnKeyOpComplete))); } virtual void TearDown() { @@ -79,8 +87,6 @@ class SignedSettingsHelperTest : public testing::Test, virtual void OnOpCompleted(SignedSettings* op) { --pending_ops_; - if (!pending_ops_) - MessageLoop::current()->Quit(); } static void OnKeyOpComplete(OwnerManager::Delegate* op) { @@ -90,14 +96,26 @@ class SignedSettingsHelperTest : public testing::Test, em::PolicyData BuildPolicyData() { em::PolicyData to_return; em::ChromeDeviceSettingsProto pol; - to_return.set_policy_type(SignedSettings::kDevicePolicyType); + to_return.set_policy_type(chromeos::kDevicePolicyType); to_return.set_policy_value(pol.SerializeAsString()); return to_return; } - const std::string fake_email_; - const std::string fake_prop_; - const base::StringValue fake_value_; + em::PolicyFetchResponse BuildProto(const std::string& data, + const std::string& sig, + std::string* out_serialized) { + em::PolicyFetchResponse fake_policy; + if (!data.empty()) + fake_policy.set_policy_data(data); + if (!sig.empty()) + fake_policy.set_policy_data_signature(sig); + EXPECT_TRUE(fake_policy.SerializeToString(out_serialized)); + return fake_policy; + } + + em::PolicyData fake_policy_data_; + em::PolicyFetchResponse fake_policy_; + std::string serialized_policy_; MockOwnershipService m_; MessageLoop message_loop_; @@ -106,83 +124,86 @@ class SignedSettingsHelperTest : public testing::Test, int pending_ops_; + MockDBusThreadManager* mock_dbus_thread_manager_; + ScopedStubCrosEnabler stub_cros_enabler_; }; +class SignedSettingsCallbacks { + public: + virtual ~SignedSettingsCallbacks() {} + // Callback of StorePolicyOp. + virtual void OnStorePolicyCompleted(SignedSettings::ReturnCode code) = 0; + // Callback of RetrievePolicyOp. + virtual void OnRetrievePolicyCompleted( + SignedSettings::ReturnCode code, + const em::PolicyFetchResponse& policy) = 0; +}; + +class MockSignedSettingsCallbacks + : public SignedSettingsCallbacks, + public base::SupportsWeakPtr<MockSignedSettingsCallbacks> { +public: + virtual ~MockSignedSettingsCallbacks() {} + + MOCK_METHOD1(OnStorePolicyCompleted, void(SignedSettings::ReturnCode)); + MOCK_METHOD2(OnRetrievePolicyCompleted, void(SignedSettings::ReturnCode, + const em::PolicyFetchResponse&)); +}; + TEST_F(SignedSettingsHelperTest, SerializedOps) { - MockSignedSettingsHelperCallback cb; - - EXPECT_CALL(m_, GetStatus(_)) - .Times(2) - .WillRepeatedly(Return(OwnershipService::OWNERSHIP_TAKEN)); - EXPECT_CALL(m_, has_cached_policy()) - .Times(2) - .WillRepeatedly(Return(true)); - em::PolicyData fake_pol = BuildPolicyData(); - EXPECT_CALL(m_, cached_policy()) - .Times(2) - .WillRepeatedly(ReturnRef(fake_pol)); - EXPECT_CALL(m_, set_cached_policy(A<const em::PolicyData&>())) - .Times(1) - .WillRepeatedly(SaveArg<0>(&fake_pol)); + MockSignedSettingsCallbacks cb; InSequence s; - EXPECT_CALL(m_, StartSigningAttempt(_, A<OwnerManager::Delegate*>())) - .WillOnce(WithArg<1>(Invoke(&SignedSettingsHelperTest::OnKeyOpComplete))); - EXPECT_CALL(cb, OnStorePropertyCompleted(SignedSettings::SUCCESS, _, _)) + EXPECT_CALL(cb, OnStorePolicyCompleted(SignedSettings::SUCCESS)) .Times(1); - - EXPECT_CALL(cb, OnRetrievePropertyCompleted(SignedSettings::SUCCESS, _, _)) + EXPECT_CALL(cb, OnRetrievePolicyCompleted(SignedSettings::SUCCESS, _)) .Times(1); pending_ops_ = 2; - SignedSettingsHelper::Get()->StartStorePropertyOp(fake_prop_, fake_value_, - &cb); - SignedSettingsHelper::Get()->StartRetrieveProperty(fake_prop_, &cb); - - message_loop_.Run(); + SignedSettingsHelper::Get()->StartStorePolicyOp( + fake_policy_, + base::Bind(&MockSignedSettingsCallbacks::OnStorePolicyCompleted, + base::Unretained(&cb))); + SignedSettingsHelper::Get()->StartRetrievePolicyOp( + base::Bind(&MockSignedSettingsCallbacks::OnRetrievePolicyCompleted, + base::Unretained(&cb))); + + message_loop_.RunAllPending(); + ASSERT_EQ(0, pending_ops_); } TEST_F(SignedSettingsHelperTest, CanceledOps) { - MockSignedSettingsHelperCallback cb; - - EXPECT_CALL(m_, GetStatus(_)) - .Times(3) - .WillRepeatedly(Return(OwnershipService::OWNERSHIP_TAKEN)); - EXPECT_CALL(m_, has_cached_policy()) - .Times(3) - .WillRepeatedly(Return(true)); - em::PolicyData fake_pol = BuildPolicyData(); - EXPECT_CALL(m_, cached_policy()) - .Times(3) - .WillRepeatedly(ReturnRef(fake_pol)); - EXPECT_CALL(m_, set_cached_policy(A<const em::PolicyData&>())) - .Times(1) - .WillRepeatedly(SaveArg<0>(&fake_pol)); + MockSignedSettingsCallbacks cb; InSequence s; - - // RetrievePropertyOp for cb_to_be_canceled still gets executed but callback - // does not happen. - EXPECT_CALL(m_, StartSigningAttempt(_, A<OwnerManager::Delegate*>())) - .WillOnce(WithArg<1>(Invoke(&SignedSettingsHelperTest::OnKeyOpComplete))); - EXPECT_CALL(cb, OnStorePropertyCompleted(SignedSettings::SUCCESS, _, _)) + EXPECT_CALL(cb, OnStorePolicyCompleted(SignedSettings::SUCCESS)) .Times(1); - EXPECT_CALL(cb, OnRetrievePropertyCompleted(SignedSettings::SUCCESS, _, _)) + EXPECT_CALL(cb, OnRetrievePolicyCompleted(SignedSettings::SUCCESS, _)) .Times(1); pending_ops_ = 3; - MockSignedSettingsHelperCallback cb_to_be_canceled; - SignedSettingsHelper::Get()->StartRetrieveProperty(fake_prop_, - &cb_to_be_canceled); - SignedSettingsHelper::Get()->CancelCallback(&cb_to_be_canceled); - SignedSettingsHelper::Get()->StartStorePropertyOp(fake_prop_, fake_value_, - &cb); - SignedSettingsHelper::Get()->StartRetrieveProperty(fake_prop_, &cb); - - message_loop_.Run(); + { + // This op will be deleted and never will be executed (expect only one call + // to OnRetrievePolicyCompleted above). However the OpComplete callback will + // be still called, therefore we expect three pending ops. + MockSignedSettingsCallbacks cb_to_be_deleted; + SignedSettingsHelper::Get()->StartRetrievePolicyOp( + base::Bind(&MockSignedSettingsCallbacks::OnRetrievePolicyCompleted, + cb_to_be_deleted.AsWeakPtr())); + } + SignedSettingsHelper::Get()->StartStorePolicyOp( + fake_policy_, + base::Bind(&MockSignedSettingsCallbacks::OnStorePolicyCompleted, + base::Unretained(&cb))); + SignedSettingsHelper::Get()->StartRetrievePolicyOp( + base::Bind(&MockSignedSettingsCallbacks::OnRetrievePolicyCompleted, + base::Unretained(&cb))); + + message_loop_.RunAllPending(); + ASSERT_EQ(0, pending_ops_); } } // namespace chromeos diff --git a/chrome/browser/chromeos/login/signed_settings_temp_storage.cc b/chrome/browser/chromeos/login/signed_settings_temp_storage.cc deleted file mode 100644 index 4435b99..0000000 --- a/chrome/browser/chromeos/login/signed_settings_temp_storage.cc +++ /dev/null @@ -1,77 +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/login/signed_settings_temp_storage.h" - -#include "base/values.h" -#include "chrome/browser/chromeos/login/ownership_service.h" -#include "chrome/browser/chromeos/login/signed_settings_helper.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/prefs/scoped_user_pref_update.h" -#include "chrome/common/pref_names.h" - -using content::BrowserThread; - -namespace chromeos { - -// static -void SignedSettingsTempStorage::RegisterPrefs(PrefService* local_state) { - local_state->RegisterDictionaryPref(prefs::kSignedSettingsTempStorage); -} - -// static -bool SignedSettingsTempStorage::Store(const std::string& name, - const base::Value& value, - PrefService* local_state) { - if (local_state) { - DictionaryPrefUpdate temp_storage_update( - local_state, prefs::kSignedSettingsTempStorage); - temp_storage_update->SetWithoutPathExpansion( - name, value.DeepCopy()); - return true; - } - return false; -} - -// static -bool SignedSettingsTempStorage::Retrieve(const std::string& name, - base::Value** value, - PrefService* local_state) { - if (local_state) { - const DictionaryValue* temp_storage = - local_state->GetDictionary(prefs::kSignedSettingsTempStorage); - if (temp_storage && temp_storage->HasKey(name)) { - temp_storage->GetWithoutPathExpansion(name, value); - return true; - } - } - return false; -} - -// static -void SignedSettingsTempStorage::Finalize(PrefService* local_state) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - if (local_state) { - const DictionaryValue* temp_storage = - local_state->GetDictionary(prefs::kSignedSettingsTempStorage); - if (temp_storage) { - // We've stored some settings in transient storage - // before owner has been assigned. - // Now owner is assigned and key is generated and we should persist - // those settings into signed storage. - for (DictionaryValue::key_iterator it = temp_storage->begin_keys(); - it != temp_storage->end_keys(); - ++it) { - base::Value* value = NULL; - bool get_result = temp_storage->GetWithoutPathExpansion(*it, &value); - DCHECK(value && get_result); - if (value) - SignedSettingsHelper::Get()->StartStorePropertyOp(*it, *value, NULL); - } - local_state->ClearPref(prefs::kSignedSettingsTempStorage); - } - } -} - -} // namespace chromeos diff --git a/chrome/browser/chromeos/login/signed_settings_temp_storage.h b/chrome/browser/chromeos/login/signed_settings_temp_storage.h deleted file mode 100644 index 6633c99..0000000 --- a/chrome/browser/chromeos/login/signed_settings_temp_storage.h +++ /dev/null @@ -1,45 +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. - -#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_SIGNED_SETTINGS_TEMP_STORAGE_H_ -#define CHROME_BROWSER_CHROMEOS_LOGIN_SIGNED_SETTINGS_TEMP_STORAGE_H_ -#pragma once - -#include <string> - -#include "base/basictypes.h" -#include "base/values.h" - -class PrefService; - -namespace chromeos { - -// There is need (proxy settings at OOBE stage) to store settings -// (that are normally go into SignedSettings storage) -// before owner has been assigned (hence no key is available). -// This class serves as a transient storage in that case. -class SignedSettingsTempStorage { - public: - // Registers required pref section. - static void RegisterPrefs(PrefService* local_state); - - static bool Store(const std::string& name, - const base::Value& value, - PrefService* local_state); - static bool Retrieve(const std::string& name, - base::Value** value, - PrefService* local_state); - - // Call this after owner has been assigned to persist settings - // into SignedSettings storage. - static void Finalize(PrefService* local_state); - - private: - SignedSettingsTempStorage() {} - DISALLOW_COPY_AND_ASSIGN(SignedSettingsTempStorage); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_LOGIN_SIGNED_SETTINGS_TEMP_STORAGE_H_ diff --git a/chrome/browser/chromeos/login/signed_settings_temp_storage_unittest.cc b/chrome/browser/chromeos/login/signed_settings_temp_storage_unittest.cc deleted file mode 100644 index ac1a9a3..0000000 --- a/chrome/browser/chromeos/login/signed_settings_temp_storage_unittest.cc +++ /dev/null @@ -1,57 +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/login/signed_settings_temp_storage.h" - -#include <algorithm> -#include <iterator> -#include <map> -#include <vector> - -#include "base/file_util.h" -#include "base/memory/scoped_ptr.h" -#include "base/scoped_temp_dir.h" -#include "chrome/common/logging_chrome.h" -#include "chrome/test/base/testing_pref_service.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace chromeos { - -class SignedSettingsTempStorageTest : public testing::Test { - protected: - virtual void SetUp() { - ref_map_.Set("some_stuff", base::Value::CreateStringValue("a=35;code=64")); - ref_map_.Set("another_stuff", base::Value::CreateBooleanValue(false)); - ref_map_.Set("name", base::Value::CreateStringValue("value")); - ref_map_.Set("2bc6aa16-e0ea-11df-b13d-18a90520e2e5", - base::Value::CreateIntegerValue(512)); - - SignedSettingsTempStorage::RegisterPrefs(&local_state_); - } - - base::DictionaryValue ref_map_; - TestingPrefService local_state_; -}; - -TEST_F(SignedSettingsTempStorageTest, Basic) { - typedef base::DictionaryValue::key_iterator It; - base::Value* value; - for (It it = ref_map_.begin_keys(); it != ref_map_.end_keys(); ++it) { - ref_map_.Get(*it, &value); - EXPECT_TRUE(SignedSettingsTempStorage::Store(*it, *value, - &local_state_)); - } - for (It it = ref_map_.begin_keys(); it != ref_map_.end_keys(); ++it) { - EXPECT_TRUE(SignedSettingsTempStorage::Retrieve(*it, &value, - &local_state_)); - base::Value* orignal_value; - ref_map_.Get(*it, &orignal_value); - EXPECT_TRUE(orignal_value->Equals(value)); - } - EXPECT_FALSE(SignedSettingsTempStorage::Retrieve("non-existent tv-series", - &value, - &local_state_)); -} - -} // namespace chromeos diff --git a/chrome/browser/chromeos/login/signed_settings_unittest.cc b/chrome/browser/chromeos/login/signed_settings_unittest.cc index 65598dd..1287e0e 100644 --- a/chrome/browser/chromeos/login/signed_settings_unittest.cc +++ b/chrome/browser/chromeos/login/signed_settings_unittest.cc @@ -4,11 +4,8 @@ #include "chrome/browser/chromeos/login/signed_settings.h" -#include "base/file_util.h" #include "base/logging.h" #include "base/message_loop.h" -#include "base/scoped_temp_dir.h" -#include "base/stringprintf.h" #include "chrome/browser/chromeos/cros/cros_library.h" #include "chrome/browser/chromeos/cros/mock_library_loader.h" #include "chrome/browser/chromeos/cros_settings_names.h" @@ -20,7 +17,6 @@ #include "chrome/browser/policy/proto/chrome_device_policy.pb.h" #include "chrome/browser/policy/proto/device_management_backend.pb.h" #include "content/test/test_browser_thread.h" -#include "crypto/rsa_private_key.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -84,19 +80,6 @@ class NormalDelegate : public DummyDelegate<T> { } }; -// Specialized version for Value objects because these compare differently. -class PolicyDelegate : public DummyDelegate<const base::Value*> { - public: - explicit PolicyDelegate(const base::Value* to_expect) - : DummyDelegate<const base::Value*>(to_expect) {} - virtual ~PolicyDelegate() {} - protected: - virtual void compare_expected(const base::Value* to_compare) { - // without this-> this won't build. - EXPECT_TRUE(this->expected_->Equals(to_compare)); - } -}; - class ProtoDelegate : public DummyDelegate<const em::PolicyFetchResponse&> { public: explicit ProtoDelegate(const em::PolicyFetchResponse& e) @@ -117,9 +100,7 @@ class ProtoDelegate : public DummyDelegate<const em::PolicyFetchResponse&> { class SignedSettingsTest : public testing::Test { public: SignedSettingsTest() - : fake_email_("fakey@example.com"), - fake_domain_("*@example.com"), - fake_prop_(kAccountsPrefAllowGuest), + : fake_prop_(kAccountsPrefAllowGuest), fake_signature_("false"), fake_value_(false), fake_value_signature_( @@ -149,57 +130,6 @@ class SignedSettingsTest : public testing::Test { s->set_service(m); } - em::PolicyData BuildPolicyData(std::vector<std::string> whitelist) { - em::PolicyData to_return; - em::ChromeDeviceSettingsProto pol; - em::GuestModeEnabledProto* allow = pol.mutable_guest_mode_enabled(); - allow->set_guest_mode_enabled(false); - pol.mutable_device_proxy_settings()->set_proxy_mode("direct"); - - if (!whitelist.empty()) { - em::UserWhitelistProto* whitelist_proto = pol.mutable_user_whitelist(); - for (std::vector<std::string>::const_iterator it = whitelist.begin(); - it != whitelist.end(); - ++it) { - whitelist_proto->add_user_whitelist(*it); - } - } - - to_return.set_policy_type(SignedSettings::kDevicePolicyType); - to_return.set_policy_value(pol.SerializeAsString()); - return to_return; - } - - void SetAllowNewUsers(bool desired, em::PolicyData* poldata) { - em::ChromeDeviceSettingsProto pol; - pol.ParseFromString(poldata->policy_value()); - em::AllowNewUsersProto* allow = pol.mutable_allow_new_users(); - allow->set_allow_new_users(desired); - poldata->set_policy_value(pol.SerializeAsString()); - } - - void FailingStorePropertyOp(const OwnerManager::KeyOpCode return_code) { - NormalDelegate<bool> d(false); - scoped_refptr<SignedSettings> s( - SignedSettings::CreateStorePropertyOp(fake_prop_, fake_value_, &d)); - d.expect_failure(SignedSettings::MapKeyOpCode(return_code)); - - mock_service(s.get(), &m_); - EXPECT_CALL(m_, StartSigningAttempt(_, _)) - .Times(1); - EXPECT_CALL(m_, GetStatus(_)) - .WillOnce(Return(OwnershipService::OWNERSHIP_TAKEN)); - EXPECT_CALL(m_, has_cached_policy()) - .WillOnce(Return(true)); - em::PolicyData fake_pol; - EXPECT_CALL(m_, cached_policy()) - .WillOnce(ReturnRef(fake_pol)); - - s->Execute(); - s->OnKeyOpComplete(return_code, std::vector<uint8>()); - message_loop_.RunAllPending(); - } - void FailingStorePolicyOp(const OwnerManager::KeyOpCode return_code) { NormalDelegate<bool> d(false); d.expect_failure(SignedSettings::MapKeyOpCode(return_code)); @@ -221,6 +151,27 @@ class SignedSettingsTest : public testing::Test { message_loop_.RunAllPending(); } + em::PolicyData BuildPolicyData(std::vector<std::string> whitelist) { + em::PolicyData to_return; + em::ChromeDeviceSettingsProto pol; + em::GuestModeEnabledProto* allow = pol.mutable_guest_mode_enabled(); + allow->set_guest_mode_enabled(false); + pol.mutable_device_proxy_settings()->set_proxy_mode("direct"); + + if (!whitelist.empty()) { + em::UserWhitelistProto* whitelist_proto = pol.mutable_user_whitelist(); + for (std::vector<std::string>::const_iterator it = whitelist.begin(); + it != whitelist.end(); + ++it) { + whitelist_proto->add_user_whitelist(*it); + } + } + + to_return.set_policy_type(chromeos::kDevicePolicyType); + to_return.set_policy_value(pol.SerializeAsString()); + return to_return; + } + em::PolicyFetchResponse BuildProto(const std::string& data, const std::string& sig, std::string* out_serialized) { @@ -233,44 +184,16 @@ class SignedSettingsTest : public testing::Test { return fake_policy; } - void DoRetrieveProperty(const std::string& name, - const base::Value* value, - em::PolicyData* fake_pol) { - PolicyDelegate d(value); - d.expect_success(); - scoped_refptr<SignedSettings> s( - SignedSettings::CreateRetrievePropertyOp(name, &d)); - mock_service(s.get(), &m_); - EXPECT_CALL(m_, GetStatus(_)) - .WillOnce(Return(OwnershipService::OWNERSHIP_TAKEN)); - EXPECT_CALL(m_, has_cached_policy()) - .WillOnce(Return(true)); - - EXPECT_CALL(m_, cached_policy()) - .WillOnce(ReturnRef(*fake_pol)); - - s->Execute(); - message_loop_.RunAllPending(); - } - - const std::string fake_email_; - const std::string fake_domain_; const std::string fake_prop_; const std::string fake_signature_; const base::FundamentalValue fake_value_; const std::vector<uint8> fake_value_signature_; MockOwnershipService m_; - ScopedTempDir tmpdir_; - FilePath tmpfile_; - MessageLoop message_loop_; content::TestBrowserThread ui_thread_; content::TestBrowserThread file_thread_; - std::vector<uint8> fake_public_key_; - scoped_ptr<crypto::RSAPrivateKey> fake_private_key_; - MockKeyUtils* mock_; MockInjector injector_; MockDBusThreadManager* mock_dbus_thread_manager_; @@ -280,156 +203,6 @@ class SignedSettingsTest : public testing::Test { ACTION_P(Retrieve, policy_blob) { arg0.Run(policy_blob); } ACTION_P(Store, success) { arg1.Run(success); } -ACTION_P(FinishKeyOp, s) { arg2->OnKeyOpComplete(OwnerManager::SUCCESS, s); } - -TEST_F(SignedSettingsTest, StoreProperty) { - NormalDelegate<bool> d(true); - d.expect_success(); - scoped_refptr<SignedSettings> s( - SignedSettings::CreateStorePropertyOp(fake_prop_, fake_value_, &d)); - - mock_service(s.get(), &m_); - EXPECT_CALL(m_, StartSigningAttempt(_, _)) - .Times(1); - EXPECT_CALL(m_, GetStatus(_)) - .WillOnce(Return(OwnershipService::OWNERSHIP_TAKEN)); - EXPECT_CALL(m_, has_cached_policy()) - .WillOnce(Return(true)); - em::PolicyData in_pol = - BuildPolicyData(std::vector<std::string>(1, fake_email_)); - EXPECT_CALL(m_, cached_policy()) - .WillOnce(ReturnRef(in_pol)); - em::PolicyData out_pol; - EXPECT_CALL(m_, set_cached_policy(A<const em::PolicyData&>())) - .WillOnce(SaveArg<0>(&out_pol)); - - MockSessionManagerClient* client = - mock_dbus_thread_manager_->mock_session_manager_client(); - EXPECT_CALL(*client, StorePolicy(_, _)) - .WillOnce(Store(true)) - .RetiresOnSaturation(); - - s->Execute(); - s->OnKeyOpComplete(OwnerManager::SUCCESS, std::vector<uint8>()); - message_loop_.RunAllPending(); - - ASSERT_TRUE(out_pol.has_policy_value()); - em::ChromeDeviceSettingsProto pol; - pol.ParseFromString(out_pol.policy_value()); - ASSERT_TRUE(pol.has_guest_mode_enabled()); - ASSERT_TRUE(pol.guest_mode_enabled().has_guest_mode_enabled()); - ASSERT_FALSE(pol.guest_mode_enabled().guest_mode_enabled()); -} - -TEST_F(SignedSettingsTest, StorePropertyNoKey) { - FailingStorePropertyOp(OwnerManager::KEY_UNAVAILABLE); -} - -TEST_F(SignedSettingsTest, StorePropertyFailed) { - FailingStorePropertyOp(OwnerManager::OPERATION_FAILED); -} - -TEST_F(SignedSettingsTest, RetrieveProperty) { - em::PolicyData fake_pol = BuildPolicyData(std::vector<std::string>()); - base::FundamentalValue fake_value(false); - DoRetrieveProperty(fake_prop_, &fake_value, &fake_pol); -} - -TEST_F(SignedSettingsTest, RetrieveOwnerProperty) { - em::PolicyData fake_pol = BuildPolicyData(std::vector<std::string>()); - fake_pol.set_username(fake_email_); - base::StringValue fake_value(fake_email_); - DoRetrieveProperty(kDeviceOwner, &fake_value, &fake_pol); -} - -TEST_F(SignedSettingsTest, ExplicitlyAllowNewUsers) { - em::PolicyData fake_pol = BuildPolicyData(std::vector<std::string>()); - SetAllowNewUsers(true, &fake_pol); - base::FundamentalValue fake_value(true); - DoRetrieveProperty(kAccountsPrefAllowNewUser, &fake_value, &fake_pol); -} - -TEST_F(SignedSettingsTest, ExplicitlyDisallowNewUsers) { - std::vector<std::string> whitelist(1, fake_email_ + "m"); - em::PolicyData fake_pol = BuildPolicyData(whitelist); - SetAllowNewUsers(false, &fake_pol); - base::FundamentalValue fake_value(false); - DoRetrieveProperty(kAccountsPrefAllowNewUser, &fake_value, &fake_pol); -} - -TEST_F(SignedSettingsTest, ImplicitlyDisallowNewUsers) { - std::vector<std::string> whitelist(1, fake_email_ + "m"); - em::PolicyData fake_pol = BuildPolicyData(whitelist); - base::FundamentalValue fake_value(false); - DoRetrieveProperty(kAccountsPrefAllowNewUser, &fake_value, &fake_pol); -} - -TEST_F(SignedSettingsTest, AccidentallyDisallowNewUsers) { - em::PolicyData fake_pol = BuildPolicyData(std::vector<std::string>()); - SetAllowNewUsers(false, &fake_pol); - base::FundamentalValue fake_value(true); - DoRetrieveProperty(kAccountsPrefAllowNewUser, &fake_value, &fake_pol); -} - -TEST_F(SignedSettingsTest, RetrievePropertyNotFound) { - PolicyDelegate d(&fake_value_); - d.expect_failure(SignedSettings::NOT_FOUND); - scoped_refptr<SignedSettings> s( - SignedSettings::CreateRetrievePropertyOp("unknown_prop", &d)); - mock_service(s.get(), &m_); - EXPECT_CALL(m_, GetStatus(_)) - .WillOnce(Return(OwnershipService::OWNERSHIP_TAKEN)); - EXPECT_CALL(m_, has_cached_policy()) - .WillOnce(Return(true)); - - em::PolicyData fake_pol = BuildPolicyData(std::vector<std::string>()); - EXPECT_CALL(m_, cached_policy()) - .WillOnce(ReturnRef(fake_pol)); - - s->Execute(); - message_loop_.RunAllPending(); -} - -TEST_F(SignedSettingsTest, RetrievePolicyToRetrieveProperty) { - base::FundamentalValue fake_value(false); - PolicyDelegate d(&fake_value); - d.expect_success(); - scoped_refptr<SignedSettings> s( - SignedSettings::CreateRetrievePropertyOp(fake_prop_, &d)); - - em::PolicyData fake_pol = BuildPolicyData(std::vector<std::string>()); - std::string data = fake_pol.SerializeAsString(); - std::string signed_serialized; - em::PolicyFetchResponse signed_policy = BuildProto(data, - fake_signature_, - &signed_serialized); - MockSessionManagerClient* client = - mock_dbus_thread_manager_->mock_session_manager_client(); - EXPECT_CALL(*client, RetrievePolicy(_)) - .WillOnce(Retrieve(signed_serialized)) - .RetiresOnSaturation(); - - mock_service(s.get(), &m_); - - EXPECT_CALL(m_, GetStatus(_)) - .WillOnce(Return(OwnershipService::OWNERSHIP_TAKEN)) - .WillOnce(Return(OwnershipService::OWNERSHIP_TAKEN)); - EXPECT_CALL(m_, has_cached_policy()) - .WillOnce(Return(false)) - .WillOnce(Return(true)); - em::PolicyData out_pol; - EXPECT_CALL(m_, set_cached_policy(A<const em::PolicyData&>())) - .WillOnce(SaveArg<0>(&out_pol)); - EXPECT_CALL(m_, cached_policy()) - .WillOnce(ReturnRef(out_pol)); - - EXPECT_CALL(m_, StartVerifyAttempt(data, fake_value_signature_, _)) - .WillOnce(FinishKeyOp(fake_value_signature_)) - .RetiresOnSaturation(); - - s->Execute(); - message_loop_.RunAllPending(); -} TEST_F(SignedSettingsTest, SignAndStorePolicy) { NormalDelegate<bool> d(true); @@ -448,8 +221,6 @@ TEST_F(SignedSettingsTest, SignAndStorePolicy) { EXPECT_CALL(m_, StartSigningAttempt(StrEq(data_serialized), _)) .Times(1); em::PolicyData out_pol; - EXPECT_CALL(m_, set_cached_policy(A<const em::PolicyData&>())) - .WillOnce(SaveArg<0>(&out_pol)); // Ask for signature over unsigned policy. s->Execute(); @@ -489,8 +260,6 @@ TEST_F(SignedSettingsTest, StoreSignedPolicy) { mock_service(s.get(), &m_); em::PolicyData out_pol; - EXPECT_CALL(m_, set_cached_policy(A<const em::PolicyData&>())) - .WillOnce(SaveArg<0>(&out_pol)); s->Execute(); message_loop_.RunAllPending(); @@ -540,8 +309,6 @@ TEST_F(SignedSettingsTest, RetrievePolicy) { EXPECT_CALL(m_, StartVerifyAttempt(serialized, fake_value_signature_, _)) .Times(1); em::PolicyData out_pol; - EXPECT_CALL(m_, set_cached_policy(A<const em::PolicyData&>())) - .WillOnce(SaveArg<0>(&out_pol)); s->Execute(); message_loop_.RunAllPending(); diff --git a/chrome/browser/chromeos/login/user_manager.cc b/chrome/browser/chromeos/login/user_manager.cc index 6f3737b..eb84b3e 100644 --- a/chrome/browser/chromeos/login/user_manager.cc +++ b/chrome/browser/chromeos/login/user_manager.cc @@ -34,7 +34,6 @@ #include "chrome/browser/chromeos/login/login_display.h" #include "chrome/browser/chromeos/login/ownership_service.h" #include "chrome/browser/chromeos/system/runtime_environment.h" -#include "chrome/browser/chromeos/user_cros_settings_provider.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/prefs/scoped_user_pref_update.h" #include "chrome/browser/profiles/profile_downloader.h" diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc index 693712d..0fc3e90 100644 --- a/chrome/browser/chromeos/login/wizard_controller.cc +++ b/chrome/browser/chromeos/login/wizard_controller.cc @@ -18,6 +18,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/cros/cros_library.h" #include "chrome/browser/chromeos/cros/cryptohome_library.h" +#include "chrome/browser/chromeos/cros_settings.h" #include "chrome/browser/chromeos/cros_settings_names.h" #include "chrome/browser/chromeos/customization_document.h" #include "chrome/browser/chromeos/language_preferences.h" @@ -31,7 +32,6 @@ #include "chrome/browser/chromeos/login/network_screen.h" #include "chrome/browser/chromeos/login/oobe_display.h" #include "chrome/browser/chromeos/login/registration_screen.h" -#include "chrome/browser/chromeos/login/signed_settings_temp_storage.h" #include "chrome/browser/chromeos/login/update_screen.h" #include "chrome/browser/chromeos/login/user_image_screen.h" #include "chrome/browser/chromeos/login/user_manager.h" @@ -376,23 +376,9 @@ void WizardController::OnUpdateCompleted() { void WizardController::OnEulaAccepted() { MarkEulaAccepted(); - // TODO(pastarmovj): Make this code cache the value for the pref in a better - // way until we can store it in the policy blob. See explanation below: - // At this point we can not write this in the signed settings pref blob. - // But we can at least create the consent file and Chrome would port that - // if the device is owned by a local user. In case of enterprise enrolled - // device the setting will be respected only until the policy is not set. - base::FundamentalValue value(usage_statistics_reporting_); - SignedSettingsTempStorage::Store( - kStatsReportingPref, - value, - g_browser_process->local_state()); bool enabled = OptionsUtil::ResolveMetricsReportingEnabled(usage_statistics_reporting_); - // Make sure the local state cached value is updated too because the real - // policy will only get written when the owner is created and the cache won't - // be updated until the policy is reread. - g_browser_process->local_state()->SetBoolean(kStatsReportingPref, enabled); + CrosSettings::Get()->SetBoolean(kStatsReportingPref, enabled); if (enabled) { #if defined(USE_LINUX_BREAKPAD) // The crash reporter initialization needs IO to complete. diff --git a/chrome/browser/chromeos/proxy_config_service_impl.cc b/chrome/browser/chromeos/proxy_config_service_impl.cc index 38aca01..78bb749 100644 --- a/chrome/browser/chromeos/proxy_config_service_impl.cc +++ b/chrome/browser/chromeos/proxy_config_service_impl.cc @@ -6,10 +6,12 @@ #include <ostream> +#include "base/bind.h" #include "base/json/json_value_serializer.h" #include "base/logging.h" #include "base/string_util.h" #include "chrome/browser/chromeos/cros/cros_library.h" +#include "chrome/browser/chromeos/cros_settings.h" #include "chrome/browser/chromeos/cros_settings_names.h" #include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/policy/proto/chrome_device_policy.pb.h" @@ -352,7 +354,8 @@ void ProxyConfigServiceImpl::ProxyConfig::EncodeAndAppendProxyServer( ProxyConfigServiceImpl::ProxyConfigServiceImpl(PrefService* pref_service) : PrefProxyConfigTrackerImpl(pref_service), - active_config_state_(ProxyPrefs::CONFIG_UNSET) { + active_config_state_(ProxyPrefs::CONFIG_UNSET), + pointer_factory_(this) { // Register for notification when user logs in, so that we can activate the // new proxy config. @@ -363,16 +366,11 @@ ProxyConfigServiceImpl::ProxyConfigServiceImpl(PrefService* pref_service) if (pref_service->FindPreference(prefs::kUseSharedProxies)) use_shared_proxies_.Init(prefs::kUseSharedProxies, pref_service, this); - // Start async fetch of proxy config from settings persisted on device. - if (CrosLibrary::Get()->libcros_loaded()) { - retrieve_property_op_ = SignedSettings::CreateRetrievePropertyOp( - kSettingProxyEverywhere, this); - if (retrieve_property_op_) { - retrieve_property_op_->Execute(); - VLOG(1) << this << ": Start retrieving proxy setting from device"; - } else { - VLOG(1) << this << ": Fail to retrieve proxy setting from device"; - } + if (CrosSettings::Get()->GetTrusted( + kSettingProxyEverywhere, + base::Bind(&ProxyConfigServiceImpl::FetchProxyPolicy, + pointer_factory_.GetWeakPtr()))) { + FetchProxyPolicy(); } // Register for flimflam network notifications. @@ -524,32 +522,6 @@ void ProxyConfigServiceImpl::OnProxyConfigChanged( DetermineEffectiveConfig(network, true); } -void ProxyConfigServiceImpl::OnSettingsOpCompleted( - SignedSettings::ReturnCode code, - const base::Value* value) { - retrieve_property_op_ = NULL; - if (code != SignedSettings::SUCCESS) { - LOG(WARNING) << this << ": Error retrieving proxy setting from device"; - device_config_.clear(); - return; - } - std::string policy_value; - value->GetAsString(&policy_value); - VLOG(1) << "Retrieved proxy setting from device, value=[" - << policy_value << "]"; - ProxyConfig device_config; - if (!device_config.DeserializeForDevice(policy_value) || - !device_config.SerializeForNetwork(&device_config_)) { - LOG(WARNING) << "Can't deserialize device setting or serialize for network"; - device_config_.clear(); - return; - } - if (!active_network_.empty()) { - VLOG(1) << this << ": try migrating device config to " << active_network_; - SetProxyConfigForNetwork(active_network_, device_config_, true); - } -} - void ProxyConfigServiceImpl::OnNetworkManagerChanged( NetworkLibrary* network_lib) { VLOG(1) << this << " OnNetworkManagerChanged: use-shared-proxies=" @@ -819,4 +791,28 @@ void ProxyConfigServiceImpl::ResetUICache() { current_ui_config_ = ProxyConfig(); } +void ProxyConfigServiceImpl::FetchProxyPolicy() { + std::string policy_value; + if (!CrosSettings::Get()->GetString(kSettingProxyEverywhere, + &policy_value)) { + LOG(WARNING) << this << ": Error retrieving proxy setting from device"; + device_config_.clear(); + return; + } + + VLOG(1) << "Retrieved proxy setting from device, value=[" + << policy_value << "]"; + ProxyConfig device_config; + if (!device_config.DeserializeForDevice(policy_value) || + !device_config.SerializeForNetwork(&device_config_)) { + LOG(WARNING) << "Can't deserialize device setting or serialize for network"; + device_config_.clear(); + return; + } + if (!active_network_.empty()) { + VLOG(1) << this << ": try migrating device config to " << active_network_; + SetProxyConfigForNetwork(active_network_, device_config_, true); + } +} + } // namespace chromeos diff --git a/chrome/browser/chromeos/proxy_config_service_impl.h b/chrome/browser/chromeos/proxy_config_service_impl.h index 4cb5b87..ac07dd6 100644 --- a/chrome/browser/chromeos/proxy_config_service_impl.h +++ b/chrome/browser/chromeos/proxy_config_service_impl.h @@ -12,7 +12,6 @@ #include "base/basictypes.h" #include "base/values.h" #include "chrome/browser/chromeos/cros/network_library.h" -#include "chrome/browser/chromeos/login/signed_settings.h" #include "chrome/browser/net/pref_proxy_config_tracker_impl.h" #include "chrome/browser/prefs/pref_member.h" #include "content/public/browser/notification_registrar.h" @@ -35,7 +34,6 @@ namespace chromeos { // user profile class ProxyConfigServiceImpl : public PrefProxyConfigTrackerImpl, - public SignedSettings::Delegate<const base::Value*>, public NetworkLibrary::NetworkManagerObserver, public NetworkLibrary::NetworkObserver { public: @@ -191,10 +189,6 @@ class ProxyConfigServiceImpl virtual void OnProxyConfigChanged(ProxyPrefs::ConfigState config_state, const net::ProxyConfig& config) OVERRIDE; - // Implementation for SignedSettings::Delegate - virtual void OnSettingsOpCompleted(SignedSettings::ReturnCode code, - const base::Value* value) OVERRIDE; - // NetworkLibrary::NetworkManagerObserver implementation. virtual void OnNetworkManagerChanged(NetworkLibrary* cros) OVERRIDE; @@ -264,6 +258,8 @@ class ProxyConfigServiceImpl // Reset UI cache variables that keep track of UI activities. void ResetUICache(); + void FetchProxyPolicy(); + // Data members. // Service path of currently active network (determined via flimflam @@ -295,13 +291,12 @@ class ProxyConfigServiceImpl content::NotificationRegistrar registrar_; - // Operation to retrieve proxy setting from device. - scoped_refptr<SignedSettings> retrieve_property_op_; - // Callbacks for notification when network to be viewed has been changed from // the UI. std::vector<base::Closure> callbacks_; + base::WeakPtrFactory<ProxyConfigServiceImpl> pointer_factory_; + DISALLOW_COPY_AND_ASSIGN(ProxyConfigServiceImpl); }; diff --git a/chrome/browser/chromeos/signed_settings_migration_helper.cc b/chrome/browser/chromeos/signed_settings_migration_helper.cc new file mode 100644 index 0000000..2504ac8 --- /dev/null +++ b/chrome/browser/chromeos/signed_settings_migration_helper.cc @@ -0,0 +1,66 @@ +// 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/signed_settings_migration_helper.h" + +#include "base/bind.h" +#include "base/values.h" +#include "chrome/browser/chromeos/cros_settings.h" +#include "chrome/common/chrome_notification_types.h" +#include "content/public/browser/notification_service.h" + +namespace chromeos { + +SignedSettingsMigrationHelper::SignedSettingsMigrationHelper() { + registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_CHECKED, + content::NotificationService::AllSources()); +} + +SignedSettingsMigrationHelper::~SignedSettingsMigrationHelper() { + registrar_.RemoveAll(); + migration_values_.Clear(); +} + +void SignedSettingsMigrationHelper::AddMigrationValue(const std::string& path, + base::Value* value) { + migration_values_.SetValue(path, value); +} + +void SignedSettingsMigrationHelper::MigrateValues(void) { + ownership_checker_.reset(new OwnershipStatusChecker( + base::Bind(&SignedSettingsMigrationHelper::DoMigrateValues, + base::Unretained(this)))); +} + +// NotificationObserver overrides: +void SignedSettingsMigrationHelper::Observe( + int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { + if (type == chrome::NOTIFICATION_OWNERSHIP_CHECKED) + MigrateValues(); +} + +void SignedSettingsMigrationHelper::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 + // SignedSettingsCache 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) { + std::map<std::string, base::Value*>::const_iterator i; + for (i = migration_values_.begin(); i != migration_values_.end(); ++i) { + // Queue all values for storing. + CrosSettings::Get()->Set(i->first, *i->second); + } + migration_values_.Clear(); + } +} + +} // namespace chromeos + diff --git a/chrome/browser/chromeos/signed_settings_migration_helper.h b/chrome/browser/chromeos/signed_settings_migration_helper.h new file mode 100644 index 0000000..92a6c30 --- /dev/null +++ b/chrome/browser/chromeos/signed_settings_migration_helper.h @@ -0,0 +1,59 @@ +// 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. + +#ifndef CHROME_BROWSER_CHROMEOS_SIGNED_SETTINGS_MIGRATION_HELPER_H_ +#define CHROME_BROWSER_CHROMEOS_SIGNED_SETTINGS_MIGRATION_HELPER_H_ +#pragma once + +#include "chrome/browser/chromeos/login/ownership_status_checker.h" +#include "chrome/browser/chromeos/login/signed_settings_helper.h" +#include "chrome/browser/prefs/pref_value_map.h" +#include "content/public/browser/notification_observer.h" +#include "content/public/browser/notification_registrar.h" + +namespace base { +class Value; +} + +namespace chromeos { + +// 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 +// SignedSettingsCache if there is no owner yet, or waits for an +// OWNERSHIP_CHECKED notification to delay the storing until the owner has +// logged in. +class SignedSettingsMigrationHelper : public content::NotificationObserver { + public: + SignedSettingsMigrationHelper(); + virtual ~SignedSettingsMigrationHelper(); + + // Adds a value to be migrated. The class takes ownership of the |value|. + void AddMigrationValue(const std::string& path, base::Value* value); + + // Initiates values migration. If the device is already owned this will + // happen immediately if not it will wait for ownership login and finish the + // migration then. + void MigrateValues(void); + + // NotificationObserver overrides: + virtual void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) OVERRIDE; + + private: + // Does the actual migration when ownership has been confirmed. + void DoMigrateValues(OwnershipService::Status status, + bool current_user_is_owner); + + content::NotificationRegistrar registrar_; + scoped_ptr<OwnershipStatusChecker> ownership_checker_; + PrefValueMap migration_values_; + + DISALLOW_COPY_AND_ASSIGN(SignedSettingsMigrationHelper); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_SIGNED_SETTINGS_MIGRATION_HELPER_H_ 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 7d855df..0000000 --- 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 diff --git a/chrome/browser/chromeos/user_cros_settings_provider.h b/chrome/browser/chromeos/user_cros_settings_provider.h deleted file mode 100644 index 1bbb12f..0000000 --- a/chrome/browser/chromeos/user_cros_settings_provider.h +++ /dev/null @@ -1,54 +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. - -#ifndef CHROME_BROWSER_CHROMEOS_USER_CROS_SETTINGS_PROVIDER_H_ -#define CHROME_BROWSER_CHROMEOS_USER_CROS_SETTINGS_PROVIDER_H_ -#pragma once - -#include <string> - -#include "base/basictypes.h" -#include "base/callback.h" -#include "chrome/browser/chromeos/cros_settings_provider.h" -#include "chrome/browser/chromeos/login/signed_settings_helper.h" - -class PrefService; - -namespace base { -class ListValue; -} - -namespace chromeos { - -// CrosSettingsProvider implementation that works with SignedSettings. -// TODO(nkostylev): Rename this class to indicate that it is -// SignedSettings specific. -class UserCrosSettingsProvider : public CrosSettingsProvider { - public: - UserCrosSettingsProvider(); - virtual ~UserCrosSettingsProvider() {} - - // Registers cached users settings in preferences. - static void RegisterPrefs(PrefService* local_state); - - // Reloads values from device settings. - void Reload(); - - // CrosSettingsProvider implementation. - virtual const base::Value* Get(const std::string& path) const OVERRIDE; - virtual bool GetTrusted(const std::string& path, - const base::Closure& callback) const OVERRIDE; - virtual bool HandlesSetting(const std::string& path) const OVERRIDE; - - private: - // CrosSettingsProvider implementation. - virtual void DoSet(const std::string& path, - const base::Value& value) OVERRIDE; - - DISALLOW_COPY_AND_ASSIGN(UserCrosSettingsProvider); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_USER_CROS_SETTINGS_PROVIDER_H_ diff --git a/chrome/browser/policy/device_policy_cache.cc b/chrome/browser/policy/device_policy_cache.cc index f96a722..75a6890 100644 --- a/chrome/browser/policy/device_policy_cache.cc +++ b/chrome/browser/policy/device_policy_cache.cc @@ -15,10 +15,11 @@ #include "base/logging.h" #include "base/metrics/histogram.h" #include "base/values.h" +#include "chrome/browser/chromeos/cros_settings.h" #include "chrome/browser/chromeos/dbus/dbus_thread_manager.h" #include "chrome/browser/chromeos/dbus/update_engine_client.h" #include "chrome/browser/chromeos/login/ownership_service.h" -#include "chrome/browser/chromeos/user_cros_settings_provider.h" +#include "chrome/browser/chromeos/login/signed_settings_helper.h" #include "chrome/browser/policy/cloud_policy_data_store.h" #include "chrome/browser/policy/enterprise_install_attributes.h" #include "chrome/browser/policy/enterprise_metrics.h" @@ -32,8 +33,7 @@ namespace { // Stores policy, updates the owner key if required and reports the status // through a callback. -class StorePolicyOperation : public chromeos::SignedSettingsHelper::Callback, - public chromeos::OwnerManager::KeyUpdateDelegate { +class StorePolicyOperation : public chromeos::OwnerManager::KeyUpdateDelegate { public: typedef base::Callback<void(chromeos::SignedSettings::ReturnCode)> Callback; @@ -42,16 +42,17 @@ class StorePolicyOperation : public chromeos::SignedSettingsHelper::Callback, const Callback& callback) : signed_settings_helper_(signed_settings_helper), policy_(policy), - callback_(callback) { - signed_settings_helper_->StartStorePolicyOp(policy, this); + callback_(callback), + weak_ptr_factory_(this) { + signed_settings_helper_->StartStorePolicyOp( + policy, + base::Bind(&StorePolicyOperation::OnStorePolicyCompleted, + weak_ptr_factory_.GetWeakPtr())); } virtual ~StorePolicyOperation() { - signed_settings_helper_->CancelCallback(this); } - // SignedSettingsHelper implementation: - virtual void OnStorePolicyCompleted( - chromeos::SignedSettings::ReturnCode code) OVERRIDE { + void OnStorePolicyCompleted(chromeos::SignedSettings::ReturnCode code) { if (code != chromeos::SignedSettings::SUCCESS) { callback_.Run(code); delete this; @@ -68,7 +69,7 @@ class StorePolicyOperation : public chromeos::SignedSettingsHelper::Callback, new_key_data, this); return; } else { - UpdateUserCrosSettings(); + chromeos::CrosSettings::Get()->ReloadProviders(); callback_.Run(chromeos::SignedSettings::SUCCESS); delete this; return; @@ -77,23 +78,19 @@ class StorePolicyOperation : public chromeos::SignedSettingsHelper::Callback, // OwnerManager::KeyUpdateDelegate implementation: virtual void OnKeyUpdated() OVERRIDE { - UpdateUserCrosSettings(); + chromeos::CrosSettings::Get()->ReloadProviders(); callback_.Run(chromeos::SignedSettings::SUCCESS); delete this; } private: - void UpdateUserCrosSettings() { - // TODO(mnissler): Find a better way. This is a hack that updates the - // UserCrosSettingsProvider's cache, since it is unable to notice we've - // updated policy information. - chromeos::UserCrosSettingsProvider().Reload(); - } chromeos::SignedSettingsHelper* signed_settings_helper_; em::PolicyFetchResponse policy_; Callback callback_; + base::WeakPtrFactory<StorePolicyOperation> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(StorePolicyOperation); }; @@ -134,11 +131,12 @@ DevicePolicyCache::DevicePolicyCache( } DevicePolicyCache::~DevicePolicyCache() { - signed_settings_helper_->CancelCallback(this); } void DevicePolicyCache::Load() { - signed_settings_helper_->StartRetrievePolicyOp(this); + signed_settings_helper_->StartRetrievePolicyOp( + base::Bind(&DevicePolicyCache::OnRetrievePolicyCompleted, + weak_ptr_factory_.GetWeakPtr())); } void DevicePolicyCache::SetPolicy(const em::PolicyFetchResponse& policy) { @@ -258,7 +256,9 @@ void DevicePolicyCache::PolicyStoreOpCompleted( } UMA_HISTOGRAM_ENUMERATION(kMetricPolicy, kMetricPolicyStoreSucceeded, kMetricPolicySize); - signed_settings_helper_->StartRetrievePolicyOp(this); + signed_settings_helper_->StartRetrievePolicyOp( + base::Bind(&DevicePolicyCache::OnRetrievePolicyCompleted, + weak_ptr_factory_.GetWeakPtr())); } void DevicePolicyCache::InstallInitialPolicy( diff --git a/chrome/browser/policy/device_policy_cache.h b/chrome/browser/policy/device_policy_cache.h index 63ed1ce..4a2fd11 100644 --- a/chrome/browser/policy/device_policy_cache.h +++ b/chrome/browser/policy/device_policy_cache.h @@ -8,10 +8,13 @@ #include "base/memory/weak_ptr.h" #include "chrome/browser/chromeos/login/signed_settings.h" -#include "chrome/browser/chromeos/login/signed_settings_helper.h" #include "chrome/browser/policy/cloud_policy_cache_base.h" #include "chrome/browser/policy/proto/chrome_device_policy.pb.h" +namespace chromeos { +class SignedSettingsHelper; +} // namespace chromeos + namespace policy { class CloudPolicyDataStore; @@ -22,8 +25,7 @@ namespace em = enterprise_management; // CloudPolicyCacheBase implementation that persists policy information // to ChromeOS' session manager (via SignedSettingsHelper). -class DevicePolicyCache : public CloudPolicyCacheBase, - public chromeos::SignedSettingsHelper::Callback { +class DevicePolicyCache : public CloudPolicyCacheBase { public: DevicePolicyCache(CloudPolicyDataStore* data_store, EnterpriseInstallAttributes* install_attributes); @@ -34,10 +36,8 @@ class DevicePolicyCache : public CloudPolicyCacheBase, virtual void SetPolicy(const em::PolicyFetchResponse& policy) OVERRIDE; virtual void SetUnmanaged() OVERRIDE; - // SignedSettingsHelper::Callback implementation: - virtual void OnRetrievePolicyCompleted( - chromeos::SignedSettings::ReturnCode code, - const em::PolicyFetchResponse& policy) OVERRIDE; + void OnRetrievePolicyCompleted(chromeos::SignedSettings::ReturnCode code, + const em::PolicyFetchResponse& policy); private: friend class DevicePolicyCacheTest; diff --git a/chrome/browser/policy/device_policy_cache_unittest.cc b/chrome/browser/policy/device_policy_cache_unittest.cc index 675af19..f28b99e 100644 --- a/chrome/browser/policy/device_policy_cache_unittest.cc +++ b/chrome/browser/policy/device_policy_cache_unittest.cc @@ -8,6 +8,7 @@ #include "chrome/browser/chromeos/login/mock_signed_settings_helper.h" #include "chrome/browser/policy/cloud_policy_data_store.h" #include "chrome/browser/policy/enterprise_install_attributes.h" +#include "content/test/test_browser_thread.h" #include "policy/configuration_policy_type.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -70,7 +71,10 @@ class DevicePolicyCacheTest : public testing::Test { protected: DevicePolicyCacheTest() : cryptohome_(chromeos::CryptohomeLibrary::GetImpl(true)), - install_attributes_(cryptohome_.get()) {} + install_attributes_(cryptohome_.get()), + message_loop_(MessageLoop::TYPE_UI), + ui_thread_(content::BrowserThread::UI, &message_loop_), + file_thread_(content::BrowserThread::FILE, &message_loop_) {} virtual void SetUp() { data_store_.reset(CloudPolicyDataStore::CreateForUserPolicies()); @@ -80,7 +84,6 @@ class DevicePolicyCacheTest : public testing::Test { } virtual void TearDown() { - EXPECT_CALL(signed_settings_helper_, CancelCallback(_)); cache_.reset(); } @@ -103,6 +106,10 @@ class DevicePolicyCacheTest : public testing::Test { chromeos::MockSignedSettingsHelper signed_settings_helper_; scoped_ptr<DevicePolicyCache> cache_; + MessageLoop message_loop_; + content::TestBrowserThread ui_thread_; + content::TestBrowserThread file_thread_; + private: DISALLOW_COPY_AND_ASSIGN(DevicePolicyCacheTest); }; @@ -147,7 +154,6 @@ TEST_F(DevicePolicyCacheTest, SetPolicy) { EXPECT_CALL(signed_settings_helper_, StartRetrievePolicyOp(_)).WillOnce( MockSignedSettingsHelperRetrievePolicy(SignedSettings::SUCCESS, new_policy)); - EXPECT_CALL(signed_settings_helper_, CancelCallback(_)); cache_->SetPolicy(new_policy); testing::Mock::VerifyAndClearExpectations(&signed_settings_helper_); base::FundamentalValue updated_expected(300); diff --git a/chrome/browser/policy/enterprise_metrics_browsertest.cc b/chrome/browser/policy/enterprise_metrics_browsertest.cc index 853fd8e..71118ea 100644 --- a/chrome/browser/policy/enterprise_metrics_browsertest.cc +++ b/chrome/browser/policy/enterprise_metrics_browsertest.cc @@ -696,9 +696,6 @@ class DevicePolicyCacheTestHelper { install_attributes_.ExpectUsage(); EXPECT_CALL(mock_signed_settings_helper_, StartStorePolicyOp(_, _)) .WillOnce(MockSignedSettingsHelperStorePolicy(code)); - EXPECT_CALL(mock_signed_settings_helper_, CancelCallback(_)) - .Times(1) - .RetiresOnSaturation(); EXPECT_CALL(mock_signed_settings_helper_, StartRetrievePolicyOp(_)).Times(expected_retrieves); } @@ -714,7 +711,6 @@ class DevicePolicyCacheTestHelper { install_attributes_.install_attributes(), &mock_signed_settings_helper_)); data_store_->SetupForTesting("", "id", "user", "gaia_token", false); - EXPECT_CALL(mock_signed_settings_helper_, CancelCallback(_)).Times(1); } chromeos::MockSignedSettingsHelper mock_signed_settings_helper_; diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 4fc9091..4e01282 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc @@ -82,14 +82,13 @@ #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/audio_mixer_alsa.h" #include "chrome/browser/chromeos/customization_document.h" -#include "chrome/browser/chromeos/login/signed_settings_temp_storage.h" +#include "chrome/browser/chromeos/login/signed_settings_cache.h" #include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/preferences.h" #include "chrome/browser/chromeos/proxy_config_service_impl.h" #include "chrome/browser/chromeos/status/input_method_menu.h" #include "chrome/browser/chromeos/status/network_menu_button.h" -#include "chrome/browser/chromeos/user_cros_settings_provider.h" #else #include "chrome/browser/extensions/default_apps.h" #endif @@ -135,11 +134,10 @@ void RegisterLocalState(PrefService* local_state) { #if defined(OS_CHROMEOS) chromeos::AudioMixerAlsa::RegisterPrefs(local_state); chromeos::UserManager::RegisterPrefs(local_state); - chromeos::UserCrosSettingsProvider::RegisterPrefs(local_state); chromeos::WizardController::RegisterPrefs(local_state); chromeos::InputMethodMenu::RegisterPrefs(local_state); chromeos::ServicesCustomizationDocument::RegisterPrefs(local_state); - chromeos::SignedSettingsTempStorage::RegisterPrefs(local_state); + chromeos::signed_settings_cache::RegisterPrefs(local_state); chromeos::NetworkMenuButton::RegisterPrefs(local_state); chromeos::ProxyConfigServiceImpl::RegisterPrefs(local_state); #endif diff --git a/chrome/browser/prefs/pref_value_map.cc b/chrome/browser/prefs/pref_value_map.cc index 3d69cf1..7e876f9 100644 --- a/chrome/browser/prefs/pref_value_map.cc +++ b/chrome/browser/prefs/pref_value_map.cc @@ -91,6 +91,10 @@ bool PrefValueMap::GetBoolean(const std::string& key, return GetValue(key, &stored_value) && stored_value->GetAsBoolean(value); } +void PrefValueMap::SetBoolean(const std::string& key, bool value) { + SetValue(key, Value::CreateBooleanValue(value)); +} + bool PrefValueMap::GetString(const std::string& key, std::string* value) const { const Value* stored_value = NULL; diff --git a/chrome/browser/prefs/pref_value_map.h b/chrome/browser/prefs/pref_value_map.h index f8995ce..291c7b4 100644 --- a/chrome/browser/prefs/pref_value_map.h +++ b/chrome/browser/prefs/pref_value_map.h @@ -51,6 +51,9 @@ class PrefValueMap { // the value was found and of the proper type. bool GetBoolean(const std::string& key, bool* value) const; + // Sets the value for |key| to the boolean |value|. + void SetBoolean(const std::string& key, bool value); + // Gets a string value for |key| and stores it in |value|. Returns true if // the value was found and of the proper type. bool GetString(const std::string& key, std::string* value) const; diff --git a/chrome/browser/ui/webui/options/chromeos/about_page_handler.cc b/chrome/browser/ui/webui/options/chromeos/about_page_handler.cc index 64f12ca..0dcc7bb 100644 --- a/chrome/browser/ui/webui/options/chromeos/about_page_handler.cc +++ b/chrome/browser/ui/webui/options/chromeos/about_page_handler.cc @@ -21,7 +21,6 @@ #include "chrome/browser/chromeos/dbus/update_engine_client.h" #include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/chromeos/login/wizard_controller.h" -#include "chrome/browser/chromeos/user_cros_settings_provider.h" #include "chrome/browser/google/google_util.h" #include "chrome/common/chrome_version_info.h" #include "chrome/common/url_constants.h" diff --git a/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.cc index 41550f5..0eb6c35 100644 --- a/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.cc +++ b/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.cc @@ -15,7 +15,6 @@ #include "chrome/browser/chromeos/cros_settings_names.h" #include "chrome/browser/chromeos/login/authenticator.h" #include "chrome/browser/chromeos/login/user_manager.h" -#include "chrome/browser/chromeos/user_cros_settings_provider.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/policy/browser_policy_connector.h" #include "grit/generated_resources.h" diff --git a/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.h b/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.h index 31ee9f0..ff6c628 100644 --- a/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.h +++ b/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.h @@ -11,8 +11,6 @@ namespace chromeos { -class UserCrosSettingsProvider; - // ChromeOS accounts options page handler. class AccountsOptionsHandler : public OptionsPageUIHandler { public: diff --git a/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc index 5a8807e..7beb5ae 100644 --- a/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc +++ b/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc @@ -44,9 +44,9 @@ base::Value* CreateSettingsValue(base::Value *value, // This function decorates the bare list of emails with some more information // needed by the UI to properly display the Accounts page. base::Value* CreateUsersWhitelist(const base::Value *pref_value) { - const base::ListValue *list_value = + const base::ListValue* list_value = static_cast<const base::ListValue*>(pref_value); - base::ListValue *user_list = new base::ListValue(); + base::ListValue* user_list = new base::ListValue(); const User& self = UserManager::Get()->logged_in_user(); bool is_owner = UserManager::Get()->current_user_is_owner(); @@ -118,8 +118,7 @@ base::Value* CoreChromeOSOptionsHandler::FetchPref( return ::CoreOptionsHandler::FetchPref(pref_name); } - const base::Value* pref_value = - CrosSettings::Get()->GetPref(pref_name); + const base::Value* pref_value = CrosSettings::Get()->GetPref(pref_name); if (!pref_value) return base::Value::CreateNullValue(); @@ -127,11 +126,12 @@ base::Value* CoreChromeOSOptionsHandler::FetchPref( if (pref_value->GetType() == base::Value::TYPE_LIST) { if (pref_name == kAccountsPrefUsers) return CreateUsersWhitelist(pref_value); + // Return a copy because the UI will take ownership of this object. return pref_value->DeepCopy(); } // All other prefs are decorated the same way. return CreateSettingsValue( - pref_value->DeepCopy(), + pref_value->DeepCopy(), // The copy will be owned by the dictionary. g_browser_process->browser_policy_connector()->IsEnterpriseManaged(), !UserManager::Get()->current_user_is_owner()); } @@ -204,7 +204,7 @@ void CoreChromeOSOptionsHandler::NotifySettingsChanged( const std::string* setting_name) { DCHECK(web_ui_); DCHECK(CrosSettings::Get()->IsCrosSettings(*setting_name)); - const base::Value* value = CrosSettings::Get()->GetPref(*setting_name); + const base::Value* value = FetchPref(*setting_name); if (!value) { NOTREACHED(); return; diff --git a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc index 7a315c8..ce6c4e0 100644 --- a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc +++ b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc @@ -32,7 +32,6 @@ #include "chrome/browser/chromeos/proxy_config_service_impl.h" #include "chrome/browser/chromeos/sim_dialog_delegate.h" #include "chrome/browser/chromeos/status/network_menu_icon.h" -#include "chrome/browser/chromeos/user_cros_settings_provider.h" #include "chrome/browser/net/pref_proxy_config_tracker.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" diff --git a/chrome/browser/ui/webui/options/chromeos/stats_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/stats_options_handler.cc index 6502956..046749f 100644 --- a/chrome/browser/ui/webui/options/chromeos/stats_options_handler.cc +++ b/chrome/browser/ui/webui/options/chromeos/stats_options_handler.cc @@ -8,7 +8,6 @@ #include "base/bind_helpers.h" #include "base/utf_string_conversions.h" #include "base/values.h" -#include "chrome/browser/chromeos/user_cros_settings_provider.h" #include "content/browser/user_metrics.h" namespace chromeos { diff --git a/chrome/browser/ui/webui/options/chromeos/system_settings_provider.cc b/chrome/browser/ui/webui/options/chromeos/system_settings_provider.cc index 1d62956..815dc49 100644 --- a/chrome/browser/ui/webui/options/chromeos/system_settings_provider.cc +++ b/chrome/browser/ui/webui/options/chromeos/system_settings_provider.cc @@ -189,7 +189,8 @@ SystemSettingsProvider::SystemSettingsProvider() { icu::UnicodeString(kTimeZones[i], -1, US_INV))); } system::TimezoneSettings::GetInstance()->AddObserver(this); - + timezone_value_.reset(base::Value::CreateStringValue(GetKnownTimezoneID( + system::TimezoneSettings::GetInstance()->GetTimezone()))); } SystemSettingsProvider::~SystemSettingsProvider() { @@ -211,22 +212,20 @@ void SystemSettingsProvider::DoSet(const std::string& path, if (!timezone) return; system::TimezoneSettings::GetInstance()->SetTimezone(*timezone); + timezone_value_.reset( + base::Value::CreateStringValue(GetKnownTimezoneID(*timezone))); } } const base::Value* SystemSettingsProvider::Get(const std::string& path) const { - if (path == kSystemTimezone) { - // TODO(pastarmovj): Cache this in the local_state instead of locally. - system_timezone_.reset(base::Value::CreateStringValue(GetKnownTimezoneID( - system::TimezoneSettings::GetInstance()->GetTimezone()))); - return system_timezone_.get(); - } + if (path == kSystemTimezone) + return timezone_value_.get(); return NULL; } // The timezone is always trusted. bool SystemSettingsProvider::GetTrusted(const std::string& path, - const base::Closure& callback) const { + const base::Closure& callback) { return true; } @@ -234,8 +233,15 @@ bool SystemSettingsProvider::HandlesSetting(const std::string& path) const { return path == kSystemTimezone; } +void SystemSettingsProvider::Reload() { + // TODO(pastarmovj): We can actually cache the timezone here to make returning + // it faster. +} + void SystemSettingsProvider::TimezoneChanged(const icu::TimeZone& timezone) { // Fires system setting change notification. + timezone_value_.reset( + base::Value::CreateStringValue(GetKnownTimezoneID(timezone))); CrosSettings::Get()->FireObservers(kSystemTimezone); } diff --git a/chrome/browser/ui/webui/options/chromeos/system_settings_provider.h b/chrome/browser/ui/webui/options/chromeos/system_settings_provider.h index 4ac725a..feeced2 100644 --- a/chrome/browser/ui/webui/options/chromeos/system_settings_provider.h +++ b/chrome/browser/ui/webui/options/chromeos/system_settings_provider.h @@ -30,8 +30,9 @@ class SystemSettingsProvider : public CrosSettingsProvider, // CrosSettingsProvider overrides. virtual const base::Value* Get(const std::string& path) const OVERRIDE; virtual bool GetTrusted(const std::string& path, - const base::Closure& callback) const OVERRIDE; + const base::Closure& callback) OVERRIDE; virtual bool HandlesSetting(const std::string& path) const OVERRIDE; + virtual void Reload() OVERRIDE; // Overridden from TimezoneSettings::Observer: virtual void TimezoneChanged(const icu::TimeZone& timezone) OVERRIDE; @@ -64,8 +65,8 @@ class SystemSettingsProvider : public CrosSettingsProvider, // Timezones. std::vector<icu::TimeZone*> timezones_; - // TODO(pastarmovj): This will be cached in the local_state PrefStore soon. - mutable scoped_ptr<base::StringValue> system_timezone_; + + scoped_ptr<base::Value> timezone_value_; DISALLOW_COPY_AND_ASSIGN(SystemSettingsProvider); }; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 9ecc2d1..4817e1b 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -640,8 +640,8 @@ 'browser/chromeos/login/signed_settings.h', 'browser/chromeos/login/signed_settings_helper.cc', 'browser/chromeos/login/signed_settings_helper.h', - 'browser/chromeos/login/signed_settings_temp_storage.cc', - 'browser/chromeos/login/signed_settings_temp_storage.h', + 'browser/chromeos/login/signed_settings_cache.cc', + 'browser/chromeos/login/signed_settings_cache.h', 'browser/chromeos/login/take_photo_view.cc', 'browser/chromeos/login/take_photo_view.h', 'browser/chromeos/login/test_attempt_state.cc', @@ -745,6 +745,8 @@ 'browser/chromeos/setting_level_bubble.h', 'browser/chromeos/setting_level_bubble_view.cc', 'browser/chromeos/setting_level_bubble_view.h', + 'browser/chromeos/signed_settings_migration_helper.cc', + 'browser/chromeos/signed_settings_migration_helper.h', 'browser/chromeos/sim_dialog_delegate.cc', 'browser/chromeos/sim_dialog_delegate.h', 'browser/chromeos/sms_observer.cc', @@ -801,8 +803,8 @@ 'browser/chromeos/tab_closeable_state_watcher.h', 'browser/chromeos/upgrade_detector_chromeos.cc', 'browser/chromeos/upgrade_detector_chromeos.h', - 'browser/chromeos/user_cros_settings_provider.cc', - 'browser/chromeos/user_cros_settings_provider.h', + 'browser/chromeos/device_settings_provider.cc', + 'browser/chromeos/device_settings_provider.h', 'browser/chromeos/version_loader.cc', 'browser/chromeos/version_loader.h', 'browser/chromeos/view_ids.h', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 5c76016..6242067 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1279,6 +1279,7 @@ 'browser/chromeos/cros/network_library_unittest.cc', 'browser/chromeos/cros/network_ui_data_unittest.cc', 'browser/chromeos/cros/onc_network_parser_unittest.cc', + 'browser/chromeos/cros_settings_unittest.cc', 'browser/chromeos/customization_document_unittest.cc', 'browser/chromeos/dbus/cros_dbus_service_unittest.cc', 'browser/chromeos/dbus/proxy_resolution_service_provider_unittest.cc', @@ -1314,7 +1315,7 @@ 'browser/chromeos/login/ownership_service_unittest.cc', 'browser/chromeos/login/parallel_authenticator_unittest.cc', 'browser/chromeos/login/signed_settings_helper_unittest.cc', - 'browser/chromeos/login/signed_settings_temp_storage_unittest.cc', + 'browser/chromeos/login/signed_settings_cache_unittest.cc', 'browser/chromeos/login/signed_settings_unittest.cc', 'browser/chromeos/login/wizard_accessibility_handler_unittest.cc', 'browser/chromeos/mobile_config_unittest.cc', diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 08fd85a..54b1c8c 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc @@ -1543,7 +1543,7 @@ const char kAllowCrossOriginAuthPrompt[] = "auth.allow_cross_origin_prompt"; #if defined(OS_CHROMEOS) // Dictionary for transient storage of settings that should go into signed // settings storage before owner has been assigned. -const char kSignedSettingsTempStorage[] = "signed_settings_temp_storage"; +const char kSignedSettingsCache[] = "signed_settings_cache"; // The hardware keyboard layout of the device. This should look like // "xkb:us::eng". diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 538cd81..5787806 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h @@ -589,7 +589,7 @@ extern const char kManagedNotificationsBlockedForUrls[]; extern const char kManagedAutoSelectCertificateForUrls[]; #if defined(OS_CHROMEOS) -extern const char kSignedSettingsTempStorage[]; +extern const char kSignedSettingsCache[]; extern const char kHardwareKeyboardLayout[]; extern const char kCarrierDealPromoShown[]; #endif |