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

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

Issue 10832035: Switch from SignedSettings to DeviceSettingsService. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: More test fixing... Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/device_settings_provider.cc
diff --git a/chrome/browser/chromeos/device_settings_provider.cc b/chrome/browser/chromeos/device_settings_provider.cc
index 27fb09ddf644d9485f68c1e3828bd8be33b150a0..a8a8a19bc1b1e96c1fba39ff774c8ca7b3176e97 100644
--- a/chrome/browser/chromeos/device_settings_provider.cc
+++ b/chrome/browser/chromeos/device_settings_provider.cc
@@ -18,16 +18,12 @@
#include "chrome/browser/chromeos/cros_settings.h"
#include "chrome/browser/chromeos/cros_settings_names.h"
#include "chrome/browser/chromeos/login/signed_settings_cache.h"
-#include "chrome/browser/chromeos/login/signed_settings_helper.h"
-#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/policy/app_pack_updater.h"
#include "chrome/browser/policy/browser_policy_connector.h"
#include "chrome/browser/policy/cloud_policy_constants.h"
-#include "chrome/browser/policy/proto/chrome_device_policy.pb.h"
+#include "chrome/browser/policy/proto/device_management_backend.pb.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/notification_service.h"
using google::protobuf::RepeatedPtrField;
@@ -63,9 +59,6 @@ const char* kKnownSettings[] = {
kStatsReportingPref,
};
-// Upper bound for number of retries to fetch a signed setting.
-static const int kNumRetriesLimit = 9;
-
// Legacy policy file location. Used to detect migration from pre v12 ChromeOS.
const char kLegacyPolicyFile[] = "/var/lib/whitelist/preferences";
@@ -87,43 +80,31 @@ bool HasOldMetricsFile() {
DeviceSettingsProvider::DeviceSettingsProvider(
const NotifyObserversCallback& notify_cb,
- SignedSettingsHelper* signed_settings_helper)
+ DeviceSettingsService* device_settings_service)
: CrosSettingsProvider(notify_cb),
- signed_settings_helper_(signed_settings_helper),
- ownership_status_(OwnershipService::GetSharedInstance()->GetStatus(true)),
+ device_settings_service_(device_settings_service),
migration_helper_(new SignedSettingsMigrationHelper()),
- retries_left_(kNumRetriesLimit),
- trusted_status_(TEMPORARILY_UNTRUSTED) {
- // 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();
-}
+ trusted_status_(TEMPORARILY_UNTRUSTED),
+ ownership_status_(device_settings_service_->GetOwnershipStatus(false)),
pastarmovj 2012/07/30 13:55:02 Have you checked if kiosk mode is fine with the po
Mattias Nissler (ping if slow) 2012/08/02 12:01:52 KioskModeSettings has a proper PrepareTrustedValue
+ ALLOW_THIS_IN_INITIALIZER_LIST(store_callback_factory_(this)) {
+ device_settings_service_->AddObserver(this);
-DeviceSettingsProvider::~DeviceSettingsProvider() {
-}
-
-void DeviceSettingsProvider::Reload() {
- // While fetching we can't trust the cache anymore.
- trusted_status_ = TEMPORARILY_UNTRUSTED;
- if (ownership_status_ == OwnershipService::OWNERSHIP_NONE) {
+ if (!UpdateFromService()) {
+ // Make sure we have at least the cache data immediately.
RetrieveCachedData();
- } else {
- // Retrieve the real data.
- signed_settings_helper_->StartRetrievePolicyOp(
- base::Bind(&DeviceSettingsProvider::OnRetrievePolicyCompleted,
- base::Unretained(this)));
}
}
+DeviceSettingsProvider::~DeviceSettingsProvider() {
+ device_settings_service_->RemoveObserver(this);
+}
+
void DeviceSettingsProvider::DoSet(const std::string& path,
const base::Value& in_value) {
- if (!UserManager::Get()->IsCurrentUserOwner() &&
- ownership_status_ != OwnershipService::OWNERSHIP_NONE) {
+ // Make sure that either the current user is the device owner or the
+ // device doesn't have an owner yet.
+ if (!(device_settings_service_->HasPrivateOwnerKey() ||
+ ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)) {
LOG(WARNING) << "Changing settings from non-owner, setting=" << path;
// Revert UI change.
@@ -133,43 +114,53 @@ void DeviceSettingsProvider::DoSet(const std::string& path,
if (IsControlledSetting(path)) {
pending_changes_.push_back(PendingQueueElement(path, in_value.DeepCopy()));
- if (pending_changes_.size() == 1)
+ if (!store_callback_factory_.HasWeakPtrs())
SetInPolicy();
} 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) {
- // Reload the policy blob once the owner key has been loaded or updated.
- ownership_status_ = OwnershipService::OWNERSHIP_TAKEN;
- Reload();
+void DeviceSettingsProvider::OwnershipStatusChanged() {
+ DeviceSettingsService::OwnershipStatus new_ownership_status =
+ device_settings_service_->GetOwnershipStatus(false);
+
+ // If the device just became owned, write the settings accumulated in the
+ // cache to device settings proper. It is important that writing only happens
+ // in this case, as during normal operation, the contents of the cache should
+ // never overwrite actual device settings.
+ if (new_ownership_status == DeviceSettingsService::OWNERSHIP_TAKEN &&
+ ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE &&
+ device_settings_service_->HasPrivateOwnerKey()) {
+
+ // There shouldn't be any pending writes, since the cache writes are all
+ // immediate.
+ DCHECK(!store_callback_factory_.HasWeakPtrs());
+
+ // Kick off a fresh write.
+ StoreDeviceSettings();
}
+
+ migration_helper_->MigrateValues();
+
+ ownership_status_ = new_ownership_status;
}
-const em::PolicyData DeviceSettingsProvider::policy() const {
- return policy_;
+void DeviceSettingsProvider::DeviceSettingsUpdated() {
+ if (!store_callback_factory_.HasWeakPtrs())
+ UpdateFromService();
}
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());
+ em::PolicyData policy_data;
+ em::ChromeDeviceSettingsProto device_settings;
+ if (!signed_settings_cache::Retrieve(&policy_data,
+ g_browser_process->local_state()) ||
+ !device_settings_.ParseFromString(policy_data.policy_value())) {
+ VLOG(1) << "Can't retrieve temp store, possibly not created yet.";
}
- policy_ = policy;
- UpdateValuesCache();
+ UpdateValuesCache(policy_data, device_settings_);
}
void DeviceSettingsProvider::SetInPolicy() {
@@ -178,62 +169,40 @@ void DeviceSettingsProvider::SetInPolicy() {
return;
}
- const std::string& prop = pending_changes_[0].first;
- base::Value* value = pending_changes_[0].second;
- 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);
- // In this case the |value_cache_| takes the ownership of |value|.
- values_cache_.SetValue(prop, value);
- NotifyObservers(prop);
- // We can't trust this value anymore until we reload the real username.
- trusted_status_ = TEMPORARILY_UNTRUSTED;
- pending_changes_.erase(pending_changes_.begin());
- if (!pending_changes_.empty())
- SetInPolicy();
- } else {
- NOTREACHED();
- }
- return;
- }
+ std::string prop(pending_changes_.front().first);
+ scoped_ptr<base::Value> value(pending_changes_.front().second);
+ pending_changes_.pop_front();
- if (RequestTrustedEntity() != TRUSTED) {
- // Otherwise we should first reload and apply on top of that.
- signed_settings_helper_->StartRetrievePolicyOp(
- base::Bind(&DeviceSettingsProvider::FinishSetInPolicy,
- base::Unretained(this)));
- return;
- }
+ DCHECK_EQ(TRUSTED, RequestTrustedEntity());
trusted_status_ = TEMPORARILY_UNTRUSTED;
- em::PolicyData data = policy();
- em::ChromeDeviceSettingsProto pol;
- pol.ParseFromString(data.policy_value());
if (prop == kAccountsPrefAllowNewUser) {
- em::AllowNewUsersProto* allow = pol.mutable_allow_new_users();
+ em::AllowNewUsersProto* allow =
+ device_settings_.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();
+ em::GuestModeEnabledProto* guest =
+ device_settings_.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();
+ em::ShowUserNamesOnSigninProto* show =
+ device_settings_.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();
+ em::DataRoamingEnabledProto* roam =
+ device_settings_.mutable_data_roaming_enabled();
bool roaming_value = false;
if (value->GetAsBoolean(&roaming_value))
roam->set_data_roaming_enabled(roaming_value);
@@ -245,20 +214,23 @@ void DeviceSettingsProvider::SetInPolicy() {
std::string proxy_value;
if (value->GetAsString(&proxy_value)) {
bool success =
- pol.mutable_device_proxy_settings()->ParseFromString(proxy_value);
+ device_settings_.mutable_device_proxy_settings()->ParseFromString(
+ proxy_value);
DCHECK(success);
} else {
NOTREACHED();
}
} else if (prop == kReleaseChannel) {
- em::ReleaseChannelProto* release_channel = pol.mutable_release_channel();
+ em::ReleaseChannelProto* release_channel =
+ device_settings_.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();
+ em::MetricsEnabledProto* metrics =
+ device_settings_.mutable_metrics_enabled();
bool metrics_value = false;
if (value->GetAsBoolean(&metrics_value))
metrics->set_metrics_enabled(metrics_value);
@@ -266,7 +238,8 @@ void DeviceSettingsProvider::SetInPolicy() {
NOTREACHED();
ApplyMetricsSetting(false, metrics_value);
} else if (prop == kAccountsPrefUsers) {
- em::UserWhitelistProto* whitelist_proto = pol.mutable_user_whitelist();
+ em::UserWhitelistProto* whitelist_proto =
+ device_settings_.mutable_user_whitelist();
whitelist_proto->clear_user_whitelist();
base::ListValue& users = static_cast<base::ListValue&>(*value);
for (base::ListValue::const_iterator i = users.begin();
@@ -277,17 +250,19 @@ void DeviceSettingsProvider::SetInPolicy() {
}
} else if (prop == kAccountsPrefEphemeralUsersEnabled) {
em::EphemeralUsersEnabledProto* ephemeral_users_enabled =
- pol.mutable_ephemeral_users_enabled();
+ device_settings_.mutable_ephemeral_users_enabled();
bool ephemeral_users_enabled_value = false;
- if (value->GetAsBoolean(&ephemeral_users_enabled_value))
+ if (value->GetAsBoolean(&ephemeral_users_enabled_value)) {
ephemeral_users_enabled->set_ephemeral_users_enabled(
ephemeral_users_enabled_value);
- else
+ } else {
NOTREACHED();
+ }
} else {
// The remaining settings don't support Set(), since they are not
// intended to be customizable by the user:
// kAppPack
+ // kDeviceOwner
// kIdleLogoutTimeout
// kIdleLogoutWarningDuration
// kReleaseChannelDelegated
@@ -299,48 +274,29 @@ void DeviceSettingsProvider::SetInPolicy() {
// kScreenSaverTimeout
// kStartUpUrls
- NOTREACHED();
+ LOG(FATAL) << "Device setting " << prop << " is read-only.";
}
- data.set_policy_value(pol.SerializeAsString());
+
+ em::PolicyData data;
+ data.set_username(device_settings_service_->GetUsername());
+ CHECK(device_settings_.SerializeToString(data.mutable_policy_value()));
+
// Set the cache to the updated value.
- policy_ = data;
- UpdateValuesCache();
+ UpdateValuesCache(data, device_settings_);
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());
- signed_settings_helper_->StartStorePolicyOp(
- policy_envelope,
- base::Bind(&DeviceSettingsProvider::OnStorePolicyCompleted,
- base::Unretained(this)));
+ if (ownership_status_ == DeviceSettingsService::OWNERSHIP_TAKEN) {
+ StoreDeviceSettings();
} else {
// OnStorePolicyCompleted won't get called in this case so proceed with any
// pending operations immediately.
- delete pending_changes_[0].second;
- pending_changes_.erase(pending_changes_.begin());
if (!pending_changes_.empty())
SetInPolicy();
}
}
-void DeviceSettingsProvider::FinishSetInPolicy(
- SignedSettings::ReturnCode code,
- const em::PolicyFetchResponse& policy) {
- if (code != SignedSettings::SUCCESS) {
- LOG(ERROR) << "Can't serialize to policy error code: " << code;
- Reload();
- return;
- }
- // Update the internal caches and set the trusted flag to true so that we
- // can pass the trustedness check in the second call to SetInPolicy.
- OnRetrievePolicyCompleted(code, policy);
-
- SetInPolicy();
-}
-
void DeviceSettingsProvider::DecodeLoginPolicies(
const em::ChromeDeviceSettingsProto& policy,
PrefValueMap* new_values_cache) const {
@@ -528,21 +484,19 @@ void DeviceSettingsProvider::DecodeGenericPolicies(
policy.release_channel().release_channel_delegated());
}
-void DeviceSettingsProvider::UpdateValuesCache() {
- const em::PolicyData data = policy();
+void DeviceSettingsProvider::UpdateValuesCache(
+ const em::PolicyData& policy_data,
+ const em::ChromeDeviceSettingsProto& settings) {
PrefValueMap new_values_cache;
- if (data.has_username() && !data.has_request_token())
- new_values_cache.SetString(kDeviceOwner, data.username());
-
- em::ChromeDeviceSettingsProto pol;
- pol.ParseFromString(data.policy_value());
+ if (policy_data.has_username() && !policy_data.has_request_token())
+ new_values_cache.SetString(kDeviceOwner, policy_data.username());
- DecodeLoginPolicies(pol, &new_values_cache);
- DecodeKioskPolicies(pol, &new_values_cache);
- DecodeNetworkPolicies(pol, &new_values_cache);
- DecodeReportingPolicies(pol, &new_values_cache);
- DecodeGenericPolicies(pol, &new_values_cache);
+ DecodeLoginPolicies(settings, &new_values_cache);
+ DecodeKioskPolicies(settings, &new_values_cache);
+ DecodeNetworkPolicies(settings, &new_values_cache);
+ DecodeReportingPolicies(settings, &new_values_cache);
+ DecodeGenericPolicies(settings, &new_values_cache);
// Collect all notifications but send them only after we have swapped the
// cache so that if somebody actually reads the cache will be already valid.
@@ -604,25 +558,26 @@ void DeviceSettingsProvider::ApplyRoamingSetting(bool new_value) const {
}
}
-void DeviceSettingsProvider::ApplySideEffects() const {
- const em::PolicyData data = policy();
- em::ChromeDeviceSettingsProto pol;
- pol.ParseFromString(data.policy_value());
+void DeviceSettingsProvider::ApplySideEffects(
+ const em::ChromeDeviceSettingsProto& settings) const {
// First migrate metrics settings as needed.
- if (pol.has_metrics_enabled())
- ApplyMetricsSetting(false, pol.metrics_enabled().metrics_enabled());
+ if (settings.has_metrics_enabled())
+ ApplyMetricsSetting(false, settings.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);
+ ApplyRoamingSetting(
+ settings.has_data_roaming_enabled() ?
+ settings.data_roaming_enabled().data_roaming_enabled() :
+ false);
}
bool DeviceSettingsProvider::MitigateMissingPolicy() {
// First check if the device has been owned already and if not exit
// immediately.
if (g_browser_process->browser_policy_connector()->GetDeviceMode() !=
- policy::DEVICE_MODE_CONSUMER) {
+ policy::DEVICE_MODE_CONSUMER) {
return false;
}
@@ -643,8 +598,8 @@ bool DeviceSettingsProvider::MitigateMissingPolicy() {
// Any value not in this list will be left to the default which is fine as
// we repopulate the whitelist with the owner and all other existing users
// every time the owner enables whitelist filtering on the UI.
- migration_helper_->AddMigrationValue(
- kAccountsPrefAllowNewUser, base::Value::CreateBooleanValue(true));
+ migration_helper_->AddMigrationValue(kAccountsPrefAllowNewUser,
+ base::Value::CreateBooleanValue(true));
migration_helper_->MigrateValues();
return true;
}
@@ -675,74 +630,82 @@ bool DeviceSettingsProvider::HandlesSetting(const std::string& path) const {
DeviceSettingsProvider::TrustedStatus
DeviceSettingsProvider::RequestTrustedEntity() {
- if (ownership_status_ == OwnershipService::OWNERSHIP_NONE)
+ if (ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)
return TRUSTED;
return trusted_status_;
}
-void DeviceSettingsProvider::OnStorePolicyCompleted(
- SignedSettings::ReturnCode code) {
- // In any case reload the policy cache to now.
- if (code != SignedSettings::SUCCESS)
- Reload();
- else
- trusted_status_ = TRUSTED;
-
- // Clear the finished task and proceed with any other stores that could be
- // pending by now.
- delete pending_changes_[0].second;
- pending_changes_.erase(pending_changes_.begin());
- if (!pending_changes_.empty())
- SetInPolicy();
+void DeviceSettingsProvider::OnStorePolicyCompleted() {
+ // Re-sync the cache from the service.
+ UpdateFromService();
+
+ // If the backend is in healthy state, trigger the next change.
+ if (trusted_status_ == TRUSTED) {
+ if (!pending_changes_.empty())
+ SetInPolicy();
+ }
}
-void DeviceSettingsProvider::OnRetrievePolicyCompleted(
- SignedSettings::ReturnCode code,
- const em::PolicyFetchResponse& policy_data) {
- VLOG(1) << "OnRetrievePolicyCompleted. Error code: " << code
- << ", trusted status : " << trusted_status_
- << ", ownership status : " << ownership_status_;
- 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_status_ = TRUSTED;
- // TODO(pastarmovj): Make those side effects responsibility of the
- // respective subsystems.
- ApplySideEffects();
+bool DeviceSettingsProvider::UpdateFromService() {
+ bool settings_loaded = false;
+ switch (device_settings_service_->status()) {
+ case DeviceSettingsService::STORE_SUCCESS: {
+ const em::PolicyData* policy_data =
+ device_settings_service_->policy_data();
+ const em::ChromeDeviceSettingsProto* device_settings =
+ device_settings_service_->device_settings();
+ if (policy_data && device_settings) {
+ UpdateValuesCache(*policy_data, *device_settings);
+ trusted_status_ = TRUSTED;
+
+ // TODO(pastarmovj): Make those side effects responsibility of the
+ // respective subsystems.
+ ApplySideEffects(*device_settings);
+
+ settings_loaded = true;
+ } else {
+ // Initial policy load is still pending.
+ trusted_status_ = TEMPORARILY_UNTRUSTED;
+ }
break;
}
- case SignedSettings::NOT_FOUND:
+ case DeviceSettingsService::STORE_NO_POLICY:
if (MitigateMissingPolicy())
break;
- case SignedSettings::KEY_UNAVAILABLE: {
- if (ownership_status_ != OwnershipService::OWNERSHIP_TAKEN)
- NOTREACHED() << "No policies present yet, will use the temp storage.";
+ // fall through.
+ case DeviceSettingsService::STORE_KEY_UNAVAILABLE:
+ VLOG(1) << "No policies present yet, will use the temp storage.";
trusted_status_ = PERMANENTLY_UNTRUSTED;
break;
- }
- case SignedSettings::BAD_SIGNATURE:
- case SignedSettings::OPERATION_FAILED: {
- LOG(ERROR) << "Failed to retrieve cros policies. Reason:" << code;
- if (retries_left_ > 0) {
- trusted_status_ = TEMPORARILY_UNTRUSTED;
- retries_left_ -= 1;
- Reload();
- return;
- }
- LOG(ERROR) << "No retries left";
+ case DeviceSettingsService::STORE_POLICY_ERROR:
+ case DeviceSettingsService::STORE_VALIDATION_ERROR:
+ case DeviceSettingsService::STORE_INVALID_POLICY:
+ case DeviceSettingsService::STORE_OPERATION_FAILED:
+ LOG(ERROR) << "Failed to retrieve cros policies. Reason:"
+ << device_settings_service_->status();
trusted_status_ = PERMANENTLY_UNTRUSTED;
break;
- }
}
+
// Notify the observers we are done.
std::vector<base::Closure> callbacks;
callbacks.swap(callbacks_);
for (size_t i = 0; i < callbacks.size(); ++i)
callbacks[i].Run();
+
+ return settings_loaded;
+}
+
+void DeviceSettingsProvider::StoreDeviceSettings() {
+ // Mute all previous callbacks to guarantee the |pending_changes_| queue is
+ // processed serially.
+ store_callback_factory_.InvalidateWeakPtrs();
+
+ device_settings_service_->SignAndStore(
+ scoped_ptr<em::ChromeDeviceSettingsProto>(
+ new em::ChromeDeviceSettingsProto(device_settings_)),
+ base::Bind(&DeviceSettingsProvider::OnStorePolicyCompleted,
+ store_callback_factory_.GetWeakPtr()));
}
} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698