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"
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
;
49 bool IsOwnerInTests(const std::string
& user_id
) {
50 if (user_id
.empty() ||
51 !CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestType
) ||
52 !CrosSettings::IsInitialized()) {
55 const base::Value
* value
= CrosSettings::Get()->GetPref(kDeviceOwner
);
56 if (!value
|| value
->GetType() != base::Value::TYPE_STRING
)
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
)>&
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
,
86 base::Bind(callback
, public_key
, private_key
));
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
)>&
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
,
101 base::Bind(callback
, public_key
, private_key
));
104 public_key
= new PublicKey();
105 public_key
->data().swap(public_key_data
);
106 bool rv
= BrowserThread::PostTask(BrowserThread::IO
,
108 base::Bind(&LoadPrivateKeyByPublicKey
,
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
))
126 scoped_ptr
<crypto::RSAPrivateKey
> key(
127 crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key
));
128 bool is_owner
= key
.get() != NULL
;
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()) {
141 scoped_refptr
<base::TaskRunner
> task_runner
=
142 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
143 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN
);
144 base::PostTaskAndReplyWithResult(
147 base::Bind(&DoesPrivateKeyExistAsyncHelper
, owner_key_util
),
153 OwnerSettingsServiceChromeOS::OwnerSettingsServiceChromeOS(
154 DeviceSettingsService
* device_settings_service
,
156 const scoped_refptr
<OwnerKeyUtil
>& owner_key_util
)
157 : ownership::OwnerSettingsService(owner_key_util
),
158 device_settings_service_(device_settings_service
),
160 waiting_for_profile_creation_(true),
161 waiting_for_tpm_token_(true),
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);
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.
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_
))
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();
237 bool OwnerSettingsServiceChromeOS::CommitTentativeDeviceSettings(
238 scoped_ptr
<enterprise_management::PolicyData
> policy
) {
239 if (!IsOwner() && !IsOwnerInTests(user_id_
))
241 if (policy
->username() != user_id_
) {
242 LOG(ERROR
) << "Username mismatch: " << policy
->username() << " vs. "
246 tentative_settings_
.reset(new em::ChromeDeviceSettingsProto
);
247 CHECK(tentative_settings_
->ParseFromString(policy
->policy_value()));
248 StorePendingChanges();
252 void OwnerSettingsServiceChromeOS::Observe(
254 const content::NotificationSource
& source
,
255 const content::NotificationDetails
& details
) {
256 DCHECK(thread_checker_
.CalledOnValidThread());
257 if (type
!= chrome::NOTIFICATION_PROFILE_CREATED
) {
262 Profile
* profile
= content::Source
<Profile
>(source
).ptr();
263 if (profile
!= profile_
) {
268 waiting_for_profile_creation_
= false;
272 void OwnerSettingsServiceChromeOS::OwnerKeySet(bool success
) {
273 DCHECK(thread_checker_
.CalledOnValidThread());
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;
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(
304 base::Bind(base::IgnoreResult(&crypto::InitializeNSSForChromeOSUser
),
306 ProfileHelper::GetProfilePathByUserIdHash(user_hash
)),
307 base::Bind(&DoesPrivateKeyExistAsync
, owner_key_util
, callback
));
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());
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());
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();
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();
347 if (value
.GetAsBoolean(&allow_value
)) {
348 allow
->set_allow_new_users(allow_value
);
352 } else if (path
== kAccountsPrefAllowGuest
) {
353 em::GuestModeEnabledProto
* guest
= settings
.mutable_guest_mode_enabled();
355 if (value
.GetAsBoolean(&guest_value
))
356 guest
->set_guest_mode_enabled(guest_value
);
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
);
367 } else if (path
== kAccountsPrefShowUserNamesOnSignIn
) {
368 em::ShowUserNamesOnSigninProto
* show
= settings
.mutable_show_user_names();
370 if (value
.GetAsBoolean(&show_value
))
371 show
->set_show_user_names(show_value
);
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();
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
);
393 if (entry_dict
->GetIntegerWithoutPathExpansion(
394 kAccountsPrefDeviceLocalAccountsKeyType
, &type
)) {
396 static_cast<em::DeviceLocalAccountInfoProto::AccountType
>(
399 std::string kiosk_app_id
;
400 if (entry_dict
->GetStringWithoutPathExpansion(
401 kAccountsPrefDeviceLocalAccountsKeyKioskAppId
,
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
);
418 } else if (path
== kAccountsPrefDeviceLocalAccountAutoLoginId
) {
419 em::DeviceLocalAccountsProto
* device_local_accounts
=
420 settings
.mutable_device_local_accounts();
422 if (value
.GetAsString(&id
))
423 device_local_accounts
->set_auto_login_id(id
);
426 } else if (path
== kAccountsPrefDeviceLocalAccountAutoLoginDelay
) {
427 em::DeviceLocalAccountsProto
* device_local_accounts
=
428 settings
.mutable_device_local_accounts();
430 if (value
.GetAsInteger(&delay
))
431 device_local_accounts
->set_auto_login_delay(delay
);
434 } else if (path
== kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled
) {
435 em::DeviceLocalAccountsProto
* device_local_accounts
=
436 settings
.mutable_device_local_accounts();
438 if (value
.GetAsBoolean(&enabled
))
439 device_local_accounts
->set_enable_auto_login_bailout(enabled
);
443 kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline
) {
444 em::DeviceLocalAccountsProto
* device_local_accounts
=
445 settings
.mutable_device_local_accounts();
447 if (value
.GetAsBoolean(&should_prompt
))
448 device_local_accounts
->set_prompt_for_network_when_offline(should_prompt
);
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
);
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
);
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
);
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();
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
);
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
);
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();
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
);
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
);
538 // The remaining settings don't support Set(), since they are not
539 // intended to be customizable by the user:
540 // kAccountsPrefTransferSAMLCookies
542 // kDeviceAttestationEnabled
544 // kIdleLogoutTimeout
545 // kIdleLogoutWarningDuration
546 // kReleaseChannelDelegated
547 // kReportDeviceActivityTimes
548 // kReportDeviceBootMode
549 // kReportDeviceLocation
550 // kReportDeviceVersionInfo
551 // kReportDeviceNetworkInterfaces
552 // kReportDeviceUsers
553 // kScreenSaverExtensionId
554 // kScreenSaverTimeout
555 // kServiceAccountIdentity
557 // kSystemTimezonePolicy
558 // kVariationsRestrictParameter
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_
)
585 scoped_refptr
<base::TaskRunner
> task_runner
=
586 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
587 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN
);
588 task_runner
->PostTask(
590 base::Bind(&LoadPrivateKey
,
592 ProfileHelper::GetUserIdHashFromProfile(profile_
),
596 void OwnerSettingsServiceChromeOS::StorePendingChanges() {
597 if (!has_pending_changes() || store_settings_factory_
.HasWeakPtrs() ||
598 !device_settings_service_
|| user_id_
.empty()) {
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();
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()));
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 */);
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(
650 store_settings_factory_
.InvalidateWeakPtrs();
651 FOR_EACH_OBSERVER(OwnerSettingsService::Observer
, observers_
,
652 OnSignedPolicyStored(success
));
653 StorePendingChanges();
656 } // namespace chromeos