Updates the mic icon status based on the device's audio state (2nd)
[chromium-blink-merge.git] / chrome / browser / chromeos / ownership / owner_settings_service_chromeos.cc
blobf2b266485a86e94be1f639cba479736e2fecb1c3
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h"
7 #include <string>
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/callback.h"
12 #include "base/command_line.h"
13 #include "base/prefs/pref_service.h"
14 #include "base/threading/thread_checker.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/chromeos/profiles/profile_helper.h"
17 #include "chrome/browser/chromeos/profiles/profile_helper.h"
18 #include "chrome/browser/chromeos/settings/cros_settings.h"
19 #include "chrome/browser/chromeos/settings/device_settings_provider.h"
20 #include "chrome/browser/chromeos/settings/session_manager_operation.h"
21 #include "chrome/browser/profiles/profile.h"
22 #include "chromeos/dbus/dbus_thread_manager.h"
23 #include "chromeos/tpm_token_loader.h"
24 #include "components/ownership/owner_key_util.h"
25 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
26 #include "components/user_manager/user.h"
27 #include "content/public/browser/browser_thread.h"
28 #include "content/public/browser/notification_details.h"
29 #include "content/public/browser/notification_service.h"
30 #include "content/public/browser/notification_source.h"
31 #include "content/public/common/content_switches.h"
32 #include "crypto/nss_util.h"
33 #include "crypto/nss_util_internal.h"
34 #include "crypto/rsa_private_key.h"
35 #include "crypto/scoped_nss_types.h"
36 #include "crypto/signature_creator.h"
38 namespace em = enterprise_management;
40 using content::BrowserThread;
41 using ownership::OwnerKeyUtil;
42 using ownership::PrivateKey;
43 using ownership::PublicKey;
45 namespace chromeos {
47 namespace {
49 bool IsOwnerInTests(const std::string& user_id) {
50 if (user_id.empty() ||
51 !CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestType) ||
52 !CrosSettings::IsInitialized()) {
53 return false;
55 const base::Value* value = CrosSettings::Get()->GetPref(kDeviceOwner);
56 if (!value || value->GetType() != base::Value::TYPE_STRING)
57 return false;
58 return static_cast<const base::StringValue*>(value)->GetString() == user_id;
61 void LoadPrivateKeyByPublicKey(
62 const scoped_refptr<OwnerKeyUtil>& owner_key_util,
63 scoped_refptr<PublicKey> public_key,
64 const std::string& username_hash,
65 const base::Callback<void(const scoped_refptr<PublicKey>& public_key,
66 const scoped_refptr<PrivateKey>& private_key)>&
67 callback) {
68 crypto::EnsureNSSInit();
69 crypto::ScopedPK11Slot public_slot =
70 crypto::GetPublicSlotForChromeOSUser(username_hash);
71 crypto::ScopedPK11Slot private_slot = crypto::GetPrivateSlotForChromeOSUser(
72 username_hash, base::Callback<void(crypto::ScopedPK11Slot)>());
74 // If private slot is already available, this will check it. If not,
75 // we'll get called again later when the TPM Token is ready, and the
76 // slot will be available then.
77 scoped_refptr<PrivateKey> private_key(
78 new PrivateKey(owner_key_util->FindPrivateKeyInSlot(public_key->data(),
79 private_slot.get())));
80 if (!private_key->key()) {
81 private_key = new PrivateKey(owner_key_util->FindPrivateKeyInSlot(
82 public_key->data(), public_slot.get()));
84 BrowserThread::PostTask(BrowserThread::UI,
85 FROM_HERE,
86 base::Bind(callback, public_key, private_key));
89 void LoadPrivateKey(
90 const scoped_refptr<OwnerKeyUtil>& owner_key_util,
91 const std::string username_hash,
92 const base::Callback<void(const scoped_refptr<PublicKey>& public_key,
93 const scoped_refptr<PrivateKey>& private_key)>&
94 callback) {
95 std::vector<uint8> public_key_data;
96 scoped_refptr<PublicKey> public_key;
97 if (!owner_key_util->ImportPublicKey(&public_key_data)) {
98 scoped_refptr<PrivateKey> private_key;
99 BrowserThread::PostTask(BrowserThread::UI,
100 FROM_HERE,
101 base::Bind(callback, public_key, private_key));
102 return;
104 public_key = new PublicKey();
105 public_key->data().swap(public_key_data);
106 bool rv = BrowserThread::PostTask(BrowserThread::IO,
107 FROM_HERE,
108 base::Bind(&LoadPrivateKeyByPublicKey,
109 owner_key_util,
110 public_key,
111 username_hash,
112 callback));
113 if (!rv) {
114 // IO thread doesn't exists in unit tests, but it's safe to use NSS from
115 // BlockingPool in unit tests.
116 LoadPrivateKeyByPublicKey(
117 owner_key_util, public_key, username_hash, callback);
121 bool DoesPrivateKeyExistAsyncHelper(
122 const scoped_refptr<OwnerKeyUtil>& owner_key_util) {
123 std::vector<uint8> public_key;
124 if (!owner_key_util->ImportPublicKey(&public_key))
125 return false;
126 scoped_ptr<crypto::RSAPrivateKey> key(
127 crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key));
128 bool is_owner = key.get() != NULL;
129 return is_owner;
132 // Checks whether NSS slots with private key are mounted or
133 // not. Responds via |callback|.
134 void DoesPrivateKeyExistAsync(
135 const scoped_refptr<OwnerKeyUtil>& owner_key_util,
136 const OwnerSettingsServiceChromeOS::IsOwnerCallback& callback) {
137 if (!owner_key_util.get()) {
138 callback.Run(false);
139 return;
141 scoped_refptr<base::TaskRunner> task_runner =
142 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
143 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
144 base::PostTaskAndReplyWithResult(
145 task_runner.get(),
146 FROM_HERE,
147 base::Bind(&DoesPrivateKeyExistAsyncHelper, owner_key_util),
148 callback);
151 } // namespace
153 OwnerSettingsServiceChromeOS::OwnerSettingsServiceChromeOS(
154 DeviceSettingsService* device_settings_service,
155 Profile* profile,
156 const scoped_refptr<OwnerKeyUtil>& owner_key_util)
157 : ownership::OwnerSettingsService(owner_key_util),
158 device_settings_service_(device_settings_service),
159 profile_(profile),
160 waiting_for_profile_creation_(true),
161 waiting_for_tpm_token_(true),
162 weak_factory_(this),
163 store_settings_factory_(this) {
164 if (TPMTokenLoader::IsInitialized()) {
165 TPMTokenLoader::TPMTokenStatus tpm_token_status =
166 TPMTokenLoader::Get()->IsTPMTokenEnabled(
167 base::Bind(&OwnerSettingsServiceChromeOS::OnTPMTokenReady,
168 weak_factory_.GetWeakPtr()));
169 waiting_for_tpm_token_ =
170 tpm_token_status == TPMTokenLoader::TPM_TOKEN_STATUS_UNDETERMINED;
173 if (DBusThreadManager::IsInitialized() &&
174 DBusThreadManager::Get()->GetSessionManagerClient()) {
175 DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this);
178 if (device_settings_service_)
179 device_settings_service_->AddObserver(this);
181 registrar_.Add(this,
182 chrome::NOTIFICATION_PROFILE_CREATED,
183 content::Source<Profile>(profile_));
186 OwnerSettingsServiceChromeOS::~OwnerSettingsServiceChromeOS() {
187 DCHECK(thread_checker_.CalledOnValidThread());
189 if (device_settings_service_)
190 device_settings_service_->RemoveObserver(this);
192 if (DBusThreadManager::IsInitialized() &&
193 DBusThreadManager::Get()->GetSessionManagerClient()) {
194 DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this);
198 void OwnerSettingsServiceChromeOS::OnTPMTokenReady(
199 bool /* tpm_token_enabled */) {
200 DCHECK(thread_checker_.CalledOnValidThread());
201 waiting_for_tpm_token_ = false;
203 // TPMTokenLoader initializes the TPM and NSS database which is necessary to
204 // determine ownership. Force a reload once we know these are initialized.
205 ReloadKeypair();
208 bool OwnerSettingsServiceChromeOS::HandlesSetting(const std::string& setting) {
209 return DeviceSettingsProvider::IsDeviceSetting(setting);
212 bool OwnerSettingsServiceChromeOS::Set(const std::string& setting,
213 const base::Value& value) {
214 if (!IsOwner() && !IsOwnerInTests(user_id_))
215 return false;
217 pending_changes_.add(setting, make_scoped_ptr(value.DeepCopy()));
219 em::ChromeDeviceSettingsProto settings;
220 if (tentative_settings_.get()) {
221 settings = *tentative_settings_;
222 } else if (device_settings_service_->status() ==
223 DeviceSettingsService::STORE_SUCCESS &&
224 device_settings_service_->device_settings()) {
225 settings = *device_settings_service_->device_settings();
227 UpdateDeviceSettings(setting, value, settings);
228 em::PolicyData policy_data;
229 policy_data.set_username(user_id_);
230 CHECK(settings.SerializeToString(policy_data.mutable_policy_value()));
231 FOR_EACH_OBSERVER(OwnerSettingsService::Observer, observers_,
232 OnTentativeChangesInPolicy(policy_data));
233 StorePendingChanges();
234 return true;
237 bool OwnerSettingsServiceChromeOS::CommitTentativeDeviceSettings(
238 scoped_ptr<enterprise_management::PolicyData> policy) {
239 if (!IsOwner() && !IsOwnerInTests(user_id_))
240 return false;
241 if (policy->username() != user_id_) {
242 LOG(ERROR) << "Username mismatch: " << policy->username() << " vs. "
243 << user_id_;
244 return false;
246 tentative_settings_.reset(new em::ChromeDeviceSettingsProto);
247 CHECK(tentative_settings_->ParseFromString(policy->policy_value()));
248 StorePendingChanges();
249 return true;
252 void OwnerSettingsServiceChromeOS::Observe(
253 int type,
254 const content::NotificationSource& source,
255 const content::NotificationDetails& details) {
256 DCHECK(thread_checker_.CalledOnValidThread());
257 if (type != chrome::NOTIFICATION_PROFILE_CREATED) {
258 NOTREACHED();
259 return;
262 Profile* profile = content::Source<Profile>(source).ptr();
263 if (profile != profile_) {
264 NOTREACHED();
265 return;
268 waiting_for_profile_creation_ = false;
269 ReloadKeypair();
272 void OwnerSettingsServiceChromeOS::OwnerKeySet(bool success) {
273 DCHECK(thread_checker_.CalledOnValidThread());
274 if (success)
275 ReloadKeypair();
278 void OwnerSettingsServiceChromeOS::OwnershipStatusChanged() {
279 DCHECK(thread_checker_.CalledOnValidThread());
280 StorePendingChanges();
283 void OwnerSettingsServiceChromeOS::DeviceSettingsUpdated() {
284 DCHECK(thread_checker_.CalledOnValidThread());
285 StorePendingChanges();
288 void OwnerSettingsServiceChromeOS::OnDeviceSettingsServiceShutdown() {
289 device_settings_service_ = nullptr;
292 // static
293 void OwnerSettingsServiceChromeOS::IsOwnerForSafeModeAsync(
294 const std::string& user_hash,
295 const scoped_refptr<OwnerKeyUtil>& owner_key_util,
296 const IsOwnerCallback& callback) {
297 CHECK(chromeos::LoginState::Get()->IsInSafeMode());
299 // Make sure NSS is initialized and NSS DB is loaded for the user before
300 // searching for the owner key.
301 BrowserThread::PostTaskAndReply(
302 BrowserThread::IO,
303 FROM_HERE,
304 base::Bind(base::IgnoreResult(&crypto::InitializeNSSForChromeOSUser),
305 user_hash,
306 ProfileHelper::GetProfilePathByUserIdHash(user_hash)),
307 base::Bind(&DoesPrivateKeyExistAsync, owner_key_util, callback));
310 // static
311 scoped_ptr<em::PolicyData> OwnerSettingsServiceChromeOS::AssemblePolicy(
312 const std::string& user_id,
313 const em::PolicyData* policy_data,
314 const em::ChromeDeviceSettingsProto* settings) {
315 scoped_ptr<em::PolicyData> policy(new em::PolicyData());
316 if (policy_data) {
317 // Preserve management settings.
318 if (policy_data->has_management_mode())
319 policy->set_management_mode(policy_data->management_mode());
320 if (policy_data->has_request_token())
321 policy->set_request_token(policy_data->request_token());
322 if (policy_data->has_device_id())
323 policy->set_device_id(policy_data->device_id());
324 } else {
325 // If there's no previous policy data, this is the first time the device
326 // setting is set. We set the management mode to LOCAL_OWNER initially.
327 policy->set_management_mode(em::PolicyData::LOCAL_OWNER);
329 policy->set_policy_type(policy::dm_protocol::kChromeDevicePolicyType);
330 policy->set_timestamp(
331 (base::Time::Now() - base::Time::UnixEpoch()).InMilliseconds());
332 policy->set_username(user_id);
333 if (!settings->SerializeToString(policy->mutable_policy_value()))
334 return scoped_ptr<em::PolicyData>();
336 return policy.Pass();
339 // static
340 void OwnerSettingsServiceChromeOS::UpdateDeviceSettings(
341 const std::string& path,
342 const base::Value& value,
343 enterprise_management::ChromeDeviceSettingsProto& settings) {
344 if (path == kAccountsPrefAllowNewUser) {
345 em::AllowNewUsersProto* allow = settings.mutable_allow_new_users();
346 bool allow_value;
347 if (value.GetAsBoolean(&allow_value)) {
348 allow->set_allow_new_users(allow_value);
349 } else {
350 NOTREACHED();
352 } else if (path == kAccountsPrefAllowGuest) {
353 em::GuestModeEnabledProto* guest = settings.mutable_guest_mode_enabled();
354 bool guest_value;
355 if (value.GetAsBoolean(&guest_value))
356 guest->set_guest_mode_enabled(guest_value);
357 else
358 NOTREACHED();
359 } else if (path == kAccountsPrefSupervisedUsersEnabled) {
360 em::SupervisedUsersSettingsProto* supervised =
361 settings.mutable_supervised_users_settings();
362 bool supervised_value;
363 if (value.GetAsBoolean(&supervised_value))
364 supervised->set_supervised_users_enabled(supervised_value);
365 else
366 NOTREACHED();
367 } else if (path == kAccountsPrefShowUserNamesOnSignIn) {
368 em::ShowUserNamesOnSigninProto* show = settings.mutable_show_user_names();
369 bool show_value;
370 if (value.GetAsBoolean(&show_value))
371 show->set_show_user_names(show_value);
372 else
373 NOTREACHED();
374 } else if (path == kAccountsPrefDeviceLocalAccounts) {
375 em::DeviceLocalAccountsProto* device_local_accounts =
376 settings.mutable_device_local_accounts();
377 device_local_accounts->clear_account();
378 const base::ListValue* accounts_list = NULL;
379 if (value.GetAsList(&accounts_list)) {
380 for (base::ListValue::const_iterator entry(accounts_list->begin());
381 entry != accounts_list->end();
382 ++entry) {
383 const base::DictionaryValue* entry_dict = NULL;
384 if ((*entry)->GetAsDictionary(&entry_dict)) {
385 em::DeviceLocalAccountInfoProto* account =
386 device_local_accounts->add_account();
387 std::string account_id;
388 if (entry_dict->GetStringWithoutPathExpansion(
389 kAccountsPrefDeviceLocalAccountsKeyId, &account_id)) {
390 account->set_account_id(account_id);
392 int type;
393 if (entry_dict->GetIntegerWithoutPathExpansion(
394 kAccountsPrefDeviceLocalAccountsKeyType, &type)) {
395 account->set_type(
396 static_cast<em::DeviceLocalAccountInfoProto::AccountType>(
397 type));
399 std::string kiosk_app_id;
400 if (entry_dict->GetStringWithoutPathExpansion(
401 kAccountsPrefDeviceLocalAccountsKeyKioskAppId,
402 &kiosk_app_id)) {
403 account->mutable_kiosk_app()->set_app_id(kiosk_app_id);
405 std::string kiosk_app_update_url;
406 if (entry_dict->GetStringWithoutPathExpansion(
407 kAccountsPrefDeviceLocalAccountsKeyKioskAppUpdateURL,
408 &kiosk_app_update_url)) {
409 account->mutable_kiosk_app()->set_update_url(kiosk_app_update_url);
411 } else {
412 NOTREACHED();
415 } else {
416 NOTREACHED();
418 } else if (path == kAccountsPrefDeviceLocalAccountAutoLoginId) {
419 em::DeviceLocalAccountsProto* device_local_accounts =
420 settings.mutable_device_local_accounts();
421 std::string id;
422 if (value.GetAsString(&id))
423 device_local_accounts->set_auto_login_id(id);
424 else
425 NOTREACHED();
426 } else if (path == kAccountsPrefDeviceLocalAccountAutoLoginDelay) {
427 em::DeviceLocalAccountsProto* device_local_accounts =
428 settings.mutable_device_local_accounts();
429 int delay;
430 if (value.GetAsInteger(&delay))
431 device_local_accounts->set_auto_login_delay(delay);
432 else
433 NOTREACHED();
434 } else if (path == kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled) {
435 em::DeviceLocalAccountsProto* device_local_accounts =
436 settings.mutable_device_local_accounts();
437 bool enabled;
438 if (value.GetAsBoolean(&enabled))
439 device_local_accounts->set_enable_auto_login_bailout(enabled);
440 else
441 NOTREACHED();
442 } else if (path ==
443 kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline) {
444 em::DeviceLocalAccountsProto* device_local_accounts =
445 settings.mutable_device_local_accounts();
446 bool should_prompt;
447 if (value.GetAsBoolean(&should_prompt))
448 device_local_accounts->set_prompt_for_network_when_offline(should_prompt);
449 else
450 NOTREACHED();
451 } else if (path == kSignedDataRoamingEnabled) {
452 em::DataRoamingEnabledProto* roam = settings.mutable_data_roaming_enabled();
453 bool roaming_value = false;
454 if (value.GetAsBoolean(&roaming_value))
455 roam->set_data_roaming_enabled(roaming_value);
456 else
457 NOTREACHED();
458 } else if (path == kReleaseChannel) {
459 em::ReleaseChannelProto* release_channel =
460 settings.mutable_release_channel();
461 std::string channel_value;
462 if (value.GetAsString(&channel_value))
463 release_channel->set_release_channel(channel_value);
464 else
465 NOTREACHED();
466 } else if (path == kStatsReportingPref) {
467 em::MetricsEnabledProto* metrics = settings.mutable_metrics_enabled();
468 bool metrics_value = false;
469 if (value.GetAsBoolean(&metrics_value))
470 metrics->set_metrics_enabled(metrics_value);
471 else
472 NOTREACHED();
473 } else if (path == kAccountsPrefUsers) {
474 em::UserWhitelistProto* whitelist_proto = settings.mutable_user_whitelist();
475 whitelist_proto->clear_user_whitelist();
476 const base::ListValue* users;
477 if (value.GetAsList(&users)) {
478 for (base::ListValue::const_iterator i = users->begin();
479 i != users->end();
480 ++i) {
481 std::string email;
482 if ((*i)->GetAsString(&email))
483 whitelist_proto->add_user_whitelist(email);
486 } else if (path == kAccountsPrefEphemeralUsersEnabled) {
487 em::EphemeralUsersEnabledProto* ephemeral_users_enabled =
488 settings.mutable_ephemeral_users_enabled();
489 bool ephemeral_users_enabled_value = false;
490 if (value.GetAsBoolean(&ephemeral_users_enabled_value)) {
491 ephemeral_users_enabled->set_ephemeral_users_enabled(
492 ephemeral_users_enabled_value);
493 } else {
494 NOTREACHED();
496 } else if (path == kAllowRedeemChromeOsRegistrationOffers) {
497 em::AllowRedeemChromeOsRegistrationOffersProto* allow_redeem_offers =
498 settings.mutable_allow_redeem_offers();
499 bool allow_redeem_offers_value;
500 if (value.GetAsBoolean(&allow_redeem_offers_value)) {
501 allow_redeem_offers->set_allow_redeem_offers(allow_redeem_offers_value);
502 } else {
503 NOTREACHED();
505 } else if (path == kStartUpFlags) {
506 em::StartUpFlagsProto* flags_proto = settings.mutable_start_up_flags();
507 flags_proto->Clear();
508 const base::ListValue* flags;
509 if (value.GetAsList(&flags)) {
510 for (base::ListValue::const_iterator i = flags->begin();
511 i != flags->end();
512 ++i) {
513 std::string flag;
514 if ((*i)->GetAsString(&flag))
515 flags_proto->add_flags(flag);
518 } else if (path == kSystemUse24HourClock) {
519 em::SystemUse24HourClockProto* use_24hour_clock_proto =
520 settings.mutable_use_24hour_clock();
521 use_24hour_clock_proto->Clear();
522 bool use_24hour_clock_value;
523 if (value.GetAsBoolean(&use_24hour_clock_value)) {
524 use_24hour_clock_proto->set_use_24hour_clock(use_24hour_clock_value);
525 } else {
526 NOTREACHED();
528 } else if (path == kAttestationForContentProtectionEnabled) {
529 em::AttestationSettingsProto* attestation_settings =
530 settings.mutable_attestation_settings();
531 bool setting_enabled;
532 if (value.GetAsBoolean(&setting_enabled)) {
533 attestation_settings->set_content_protection_enabled(setting_enabled);
534 } else {
535 NOTREACHED();
537 } else {
538 // The remaining settings don't support Set(), since they are not
539 // intended to be customizable by the user:
540 // kAccountsPrefTransferSAMLCookies
541 // kAppPack
542 // kDeviceAttestationEnabled
543 // kDeviceOwner
544 // kIdleLogoutTimeout
545 // kIdleLogoutWarningDuration
546 // kReleaseChannelDelegated
547 // kReportDeviceActivityTimes
548 // kReportDeviceBootMode
549 // kReportDeviceLocation
550 // kReportDeviceVersionInfo
551 // kReportDeviceNetworkInterfaces
552 // kReportDeviceUsers
553 // kScreenSaverExtensionId
554 // kScreenSaverTimeout
555 // kServiceAccountIdentity
556 // kStartUpUrls
557 // kSystemTimezonePolicy
558 // kVariationsRestrictParameter
559 // kDeviceDisabled
560 // kDeviceDisabledMessage
562 LOG(FATAL) << "Device setting " << path << " is read-only.";
566 void OwnerSettingsServiceChromeOS::OnPostKeypairLoadedActions() {
567 DCHECK(thread_checker_.CalledOnValidThread());
569 const user_manager::User* user =
570 ProfileHelper::Get()->GetUserByProfile(profile_);
571 user_id_ = user ? user->GetUserID() : std::string();
573 const bool is_owner = IsOwner() || IsOwnerInTests(user_id_);
574 if (is_owner && device_settings_service_)
575 device_settings_service_->InitOwner(user_id_, weak_factory_.GetWeakPtr());
578 void OwnerSettingsServiceChromeOS::ReloadKeypairImpl(const base::Callback<
579 void(const scoped_refptr<PublicKey>& public_key,
580 const scoped_refptr<PrivateKey>& private_key)>& callback) {
581 DCHECK(thread_checker_.CalledOnValidThread());
583 if (waiting_for_profile_creation_ || waiting_for_tpm_token_)
584 return;
585 scoped_refptr<base::TaskRunner> task_runner =
586 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
587 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
588 task_runner->PostTask(
589 FROM_HERE,
590 base::Bind(&LoadPrivateKey,
591 owner_key_util_,
592 ProfileHelper::GetUserIdHashFromProfile(profile_),
593 callback));
596 void OwnerSettingsServiceChromeOS::StorePendingChanges() {
597 if (!has_pending_changes() || store_settings_factory_.HasWeakPtrs() ||
598 !device_settings_service_ || user_id_.empty()) {
599 return;
602 em::ChromeDeviceSettingsProto settings;
603 if (tentative_settings_.get()) {
604 settings.Swap(tentative_settings_.get());
605 tentative_settings_.reset();
606 } else if (device_settings_service_->status() ==
607 DeviceSettingsService::STORE_SUCCESS &&
608 device_settings_service_->device_settings()) {
609 settings = *device_settings_service_->device_settings();
610 } else {
611 return;
614 for (const auto& change : pending_changes_)
615 UpdateDeviceSettings(change.first, *change.second, settings);
616 pending_changes_.clear();
618 scoped_ptr<em::PolicyData> policy = AssemblePolicy(
619 user_id_, device_settings_service_->policy_data(), &settings);
620 bool rv = AssembleAndSignPolicyAsync(
621 content::BrowserThread::GetBlockingPool(), policy.Pass(),
622 base::Bind(&OwnerSettingsServiceChromeOS::OnPolicyAssembledAndSigned,
623 store_settings_factory_.GetWeakPtr()));
624 if (!rv)
625 ReportStatusAndContinueStoring(false /* success */);
628 void OwnerSettingsServiceChromeOS::OnPolicyAssembledAndSigned(
629 scoped_ptr<em::PolicyFetchResponse> policy_response) {
630 if (!policy_response.get() || !device_settings_service_) {
631 ReportStatusAndContinueStoring(false /* success */);
632 return;
634 device_settings_service_->Store(
635 policy_response.Pass(),
636 base::Bind(&OwnerSettingsServiceChromeOS::OnSignedPolicyStored,
637 store_settings_factory_.GetWeakPtr(),
638 true /* success */));
641 void OwnerSettingsServiceChromeOS::OnSignedPolicyStored(bool success) {
642 CHECK(device_settings_service_);
643 ReportStatusAndContinueStoring(success &&
644 device_settings_service_->status() !=
645 DeviceSettingsService::STORE_SUCCESS);
648 void OwnerSettingsServiceChromeOS::ReportStatusAndContinueStoring(
649 bool success) {
650 store_settings_factory_.InvalidateWeakPtrs();
651 FOR_EACH_OBSERVER(OwnerSettingsService::Observer, observers_,
652 OnSignedPolicyStored(success));
653 StorePendingChanges();
656 } // namespace chromeos