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