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

Side by Side Diff: chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc

Issue 654263003: Implemented OwnerSettingsService::Set() method. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixes. Created 6 years, 2 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" 5 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
11 #include "base/callback.h" 11 #include "base/callback.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/message_loop/message_loop.h"
13 #include "base/prefs/pref_service.h" 14 #include "base/prefs/pref_service.h"
14 #include "base/threading/thread_checker.h" 15 #include "base/threading/thread_checker.h"
15 #include "chrome/browser/chrome_notification_types.h" 16 #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"
17 #include "chrome/browser/chromeos/settings/cros_settings.h" 18 #include "chrome/browser/chromeos/settings/cros_settings.h"
19 #include "chrome/browser/chromeos/settings/device_settings_provider.h"
18 #include "chrome/browser/chromeos/settings/session_manager_operation.h" 20 #include "chrome/browser/chromeos/settings/session_manager_operation.h"
19 #include "chrome/browser/profiles/profile.h" 21 #include "chrome/browser/profiles/profile.h"
20 #include "chromeos/dbus/dbus_thread_manager.h" 22 #include "chromeos/dbus/dbus_thread_manager.h"
21 #include "chromeos/tpm_token_loader.h" 23 #include "chromeos/tpm_token_loader.h"
22 #include "components/ownership/owner_key_util.h" 24 #include "components/ownership/owner_key_util.h"
23 #include "components/policy/core/common/cloud/cloud_policy_constants.h" 25 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
24 #include "content/public/browser/browser_thread.h" 26 #include "content/public/browser/browser_thread.h"
25 #include "content/public/browser/notification_details.h" 27 #include "content/public/browser/notification_details.h"
26 #include "content/public/browser/notification_service.h" 28 #include "content/public/browser/notification_service.h"
27 #include "content/public/browser/notification_source.h" 29 #include "content/public/browser/notification_source.h"
28 #include "content/public/common/content_switches.h" 30 #include "content/public/common/content_switches.h"
29 #include "crypto/nss_util.h" 31 #include "crypto/nss_util.h"
30 #include "crypto/nss_util_internal.h" 32 #include "crypto/nss_util_internal.h"
31 #include "crypto/rsa_private_key.h" 33 #include "crypto/rsa_private_key.h"
32 #include "crypto/scoped_nss_types.h" 34 #include "crypto/scoped_nss_types.h"
33 #include "crypto/signature_creator.h" 35 #include "crypto/signature_creator.h"
34 36
35 namespace em = enterprise_management; 37 namespace em = enterprise_management;
36 38
37 using content::BrowserThread; 39 using content::BrowserThread;
38 using ownership::OwnerKeyUtil; 40 using ownership::OwnerKeyUtil;
39 using ownership::PrivateKey; 41 using ownership::PrivateKey;
40 using ownership::PublicKey; 42 using ownership::PublicKey;
41 43
42 namespace chromeos { 44 namespace chromeos {
43 45
44 namespace { 46 namespace {
45 47
46 DeviceSettingsService* g_device_settings_service_for_testing = NULL;
47
48 bool IsOwnerInTests(const std::string& user_id) { 48 bool IsOwnerInTests(const std::string& user_id) {
49 if (user_id.empty() || 49 if (user_id.empty() ||
50 !CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestType) || 50 !CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestType) ||
51 !CrosSettings::IsInitialized()) { 51 !CrosSettings::IsInitialized()) {
52 return false; 52 return false;
53 } 53 }
54 const base::Value* value = CrosSettings::Get()->GetPref(kDeviceOwner); 54 const base::Value* value = CrosSettings::Get()->GetPref(kDeviceOwner);
55 if (!value || value->GetType() != base::Value::TYPE_STRING) 55 if (!value || value->GetType() != base::Value::TYPE_STRING)
56 return false; 56 return false;
57 return static_cast<const base::StringValue*>(value)->GetString() == user_id; 57 return static_cast<const base::StringValue*>(value)->GetString() == user_id;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 scoped_refptr<base::TaskRunner> task_runner = 129 scoped_refptr<base::TaskRunner> task_runner =
130 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( 130 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
131 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); 131 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
132 base::PostTaskAndReplyWithResult( 132 base::PostTaskAndReplyWithResult(
133 task_runner.get(), 133 task_runner.get(),
134 FROM_HERE, 134 FROM_HERE,
135 base::Bind(&DoesPrivateKeyExistAsyncHelper, owner_key_util), 135 base::Bind(&DoesPrivateKeyExistAsyncHelper, owner_key_util),
136 callback); 136 callback);
137 } 137 }
138 138
139 DeviceSettingsService* GetDeviceSettingsService() {
140 if (g_device_settings_service_for_testing)
141 return g_device_settings_service_for_testing;
142 return DeviceSettingsService::IsInitialized() ? DeviceSettingsService::Get()
143 : NULL;
144 }
145
146 } // namespace 139 } // namespace
147 140
141 class OwnerSettingsServiceChromeOS::ProcessingLoopAutoBlocker {
142 public:
143 explicit ProcessingLoopAutoBlocker(
144 DeviceSettingsService* device_settings_service)
145 : device_settings_service_(device_settings_service) {
146 device_settings_service_->EnableProcessingLoop(false /* enabled */);
147 }
148
149 ~ProcessingLoopAutoBlocker() {
150 device_settings_service_->EnableProcessingLoop(true /* enabled */);
151 }
152
153 private:
154 DeviceSettingsService* device_settings_service_;
155
156 DISALLOW_COPY_AND_ASSIGN(ProcessingLoopAutoBlocker);
157 };
158
159 OwnerSettingsServiceChromeOS::SetRequest::SetRequest(
160 const std::string& setting,
161 linked_ptr<base::Value> value)
162 : setting(setting), value(value) {
163 }
164
165 OwnerSettingsServiceChromeOS::SetRequest::~SetRequest() {
166 }
167
148 OwnerSettingsServiceChromeOS::OwnerSettingsServiceChromeOS( 168 OwnerSettingsServiceChromeOS::OwnerSettingsServiceChromeOS(
169 DeviceSettingsService* device_settings_service,
149 Profile* profile, 170 Profile* profile,
150 const scoped_refptr<OwnerKeyUtil>& owner_key_util) 171 const scoped_refptr<OwnerKeyUtil>& owner_key_util)
151 : ownership::OwnerSettingsService(owner_key_util), 172 : ownership::OwnerSettingsService(owner_key_util),
173 device_settings_service_(device_settings_service),
152 profile_(profile), 174 profile_(profile),
153 waiting_for_profile_creation_(true), 175 waiting_for_profile_creation_(true),
154 waiting_for_tpm_token_(true), 176 waiting_for_tpm_token_(true),
155 weak_factory_(this) { 177 weak_factory_(this),
178 set_requests_callback_factory_(this) {
156 if (TPMTokenLoader::IsInitialized()) { 179 if (TPMTokenLoader::IsInitialized()) {
157 TPMTokenLoader::TPMTokenStatus tpm_token_status = 180 TPMTokenLoader::TPMTokenStatus tpm_token_status =
158 TPMTokenLoader::Get()->IsTPMTokenEnabled( 181 TPMTokenLoader::Get()->IsTPMTokenEnabled(
159 base::Bind(&OwnerSettingsServiceChromeOS::OnTPMTokenReady, 182 base::Bind(&OwnerSettingsServiceChromeOS::OnTPMTokenReady,
160 weak_factory_.GetWeakPtr())); 183 weak_factory_.GetWeakPtr()));
161 waiting_for_tpm_token_ = 184 waiting_for_tpm_token_ =
162 tpm_token_status == TPMTokenLoader::TPM_TOKEN_STATUS_UNDETERMINED; 185 tpm_token_status == TPMTokenLoader::TPM_TOKEN_STATUS_UNDETERMINED;
163 } 186 }
164 187
165 if (DBusThreadManager::IsInitialized() && 188 if (DBusThreadManager::IsInitialized() &&
166 DBusThreadManager::Get()->GetSessionManagerClient()) { 189 DBusThreadManager::Get()->GetSessionManagerClient()) {
167 DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this); 190 DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this);
168 } 191 }
169 192
193 device_settings_service_->AddObserver(this);
194
170 registrar_.Add(this, 195 registrar_.Add(this,
171 chrome::NOTIFICATION_PROFILE_CREATED, 196 chrome::NOTIFICATION_PROFILE_CREATED,
172 content::Source<Profile>(profile_)); 197 content::Source<Profile>(profile_));
173 } 198 }
174 199
175 OwnerSettingsServiceChromeOS::~OwnerSettingsServiceChromeOS() { 200 OwnerSettingsServiceChromeOS::~OwnerSettingsServiceChromeOS() {
176 DCHECK(thread_checker_.CalledOnValidThread()); 201 DCHECK(thread_checker_.CalledOnValidThread());
177 if (DBusThreadManager::IsInitialized() && 202 if (DBusThreadManager::IsInitialized() &&
178 DBusThreadManager::Get()->GetSessionManagerClient()) { 203 DBusThreadManager::Get()->GetSessionManagerClient()) {
179 DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this); 204 DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this);
180 } 205 }
206
207 device_settings_service_->RemoveObserver(this);
181 } 208 }
182 209
183 void OwnerSettingsServiceChromeOS::OnTPMTokenReady( 210 void OwnerSettingsServiceChromeOS::OnTPMTokenReady(
184 bool /* tpm_token_enabled */) { 211 bool /* tpm_token_enabled */) {
185 DCHECK(thread_checker_.CalledOnValidThread()); 212 DCHECK(thread_checker_.CalledOnValidThread());
186 waiting_for_tpm_token_ = false; 213 waiting_for_tpm_token_ = false;
187 214
188 // TPMTokenLoader initializes the TPM and NSS database which is necessary to 215 // TPMTokenLoader initializes the TPM and NSS database which is necessary to
189 // determine ownership. Force a reload once we know these are initialized. 216 // determine ownership. Force a reload once we know these are initialized.
190 ReloadKeypair(); 217 ReloadKeypair();
191 } 218 }
192 219
193 void OwnerSettingsServiceChromeOS::SignAndStorePolicyAsync( 220 bool OwnerSettingsServiceChromeOS::HandlesSetting(const std::string& setting) {
194 scoped_ptr<em::PolicyData> policy, 221 return DeviceSettingsProvider::IsDeviceSetting(setting);
195 const base::Closure& callback) { 222 }
196 DCHECK(thread_checker_.CalledOnValidThread()); 223
197 SignAndStoreSettingsOperation* operation = new SignAndStoreSettingsOperation( 224 void OwnerSettingsServiceChromeOS::Set(const std::string& setting,
198 base::Bind(&OwnerSettingsServiceChromeOS::HandleCompletedOperation, 225 const base::Value& value) {
199 weak_factory_.GetWeakPtr(), 226 if (!IsOwner() && !IsOwnerInTests(user_id_))
200 callback), 227 return;
201 policy.Pass()); 228 set_requests_.push(
Mattias Nissler (ping if slow) 2014/10/20 12:41:30 It just occurred to me that instead of keeping a q
ygorshenin1 2014/10/20 13:35:16 But we always can call DeviceSettingsService::Stor
Mattias Nissler (ping if slow) 2014/10/20 13:46:49 DeviceSettingsService doesn't impose any restricti
ygorshenin1 2014/10/20 13:49:06 Sure, thanks for the explanation!
202 operation->set_owner_settings_service(weak_factory_.GetWeakPtr()); 229 SetRequest(setting, linked_ptr<base::Value>(value.DeepCopy())));
203 pending_operations_.push_back(operation); 230 ProcessNextSetRequest();
204 if (pending_operations_.front() == operation)
205 StartNextOperation();
206 } 231 }
207 232
208 void OwnerSettingsServiceChromeOS::Observe( 233 void OwnerSettingsServiceChromeOS::Observe(
209 int type, 234 int type,
210 const content::NotificationSource& source, 235 const content::NotificationSource& source,
211 const content::NotificationDetails& details) { 236 const content::NotificationDetails& details) {
212 DCHECK(thread_checker_.CalledOnValidThread()); 237 DCHECK(thread_checker_.CalledOnValidThread());
213 if (type != chrome::NOTIFICATION_PROFILE_CREATED) { 238 if (type != chrome::NOTIFICATION_PROFILE_CREATED) {
214 NOTREACHED(); 239 NOTREACHED();
215 return; 240 return;
216 } 241 }
217 242
218 Profile* profile = content::Source<Profile>(source).ptr(); 243 Profile* profile = content::Source<Profile>(source).ptr();
219 if (profile != profile_) { 244 if (profile != profile_) {
220 NOTREACHED(); 245 NOTREACHED();
221 return; 246 return;
222 } 247 }
223 248
224 waiting_for_profile_creation_ = false; 249 waiting_for_profile_creation_ = false;
225 ReloadKeypair(); 250 ReloadKeypair();
226 } 251 }
227 252
228 void OwnerSettingsServiceChromeOS::OwnerKeySet(bool success) { 253 void OwnerSettingsServiceChromeOS::OwnerKeySet(bool success) {
229 DCHECK(thread_checker_.CalledOnValidThread()); 254 DCHECK(thread_checker_.CalledOnValidThread());
230 if (success) 255 if (success)
231 ReloadKeypair(); 256 ReloadKeypair();
232 } 257 }
233 258
259 void OwnerSettingsServiceChromeOS::OwnershipStatusChanged() {
260 DCHECK(thread_checker_.CalledOnValidThread());
261 ProcessNextSetRequestAsync();
262 }
263
264 void OwnerSettingsServiceChromeOS::DeviceSettingsUpdated() {
265 DCHECK(thread_checker_.CalledOnValidThread());
266 ProcessNextSetRequestAsync();
267 }
268
234 // static 269 // static
235 void OwnerSettingsServiceChromeOS::IsOwnerForSafeModeAsync( 270 void OwnerSettingsServiceChromeOS::IsOwnerForSafeModeAsync(
236 const std::string& user_hash, 271 const std::string& user_hash,
237 const scoped_refptr<OwnerKeyUtil>& owner_key_util, 272 const scoped_refptr<OwnerKeyUtil>& owner_key_util,
238 const IsOwnerCallback& callback) { 273 const IsOwnerCallback& callback) {
239 CHECK(chromeos::LoginState::Get()->IsInSafeMode()); 274 CHECK(chromeos::LoginState::Get()->IsInSafeMode());
240 275
241 // Make sure NSS is initialized and NSS DB is loaded for the user before 276 // Make sure NSS is initialized and NSS DB is loaded for the user before
242 // searching for the owner key. 277 // searching for the owner key.
243 BrowserThread::PostTaskAndReply( 278 BrowserThread::PostTaskAndReply(
244 BrowserThread::IO, 279 BrowserThread::IO,
245 FROM_HERE, 280 FROM_HERE,
246 base::Bind(base::IgnoreResult(&crypto::InitializeNSSForChromeOSUser), 281 base::Bind(base::IgnoreResult(&crypto::InitializeNSSForChromeOSUser),
247 user_hash, 282 user_hash,
248 ProfileHelper::GetProfilePathByUserIdHash(user_hash)), 283 ProfileHelper::GetProfilePathByUserIdHash(user_hash)),
249 base::Bind(&DoesPrivateKeyExistAsync, owner_key_util, callback)); 284 base::Bind(&DoesPrivateKeyExistAsync, owner_key_util, callback));
250 } 285 }
251 286
252 // static 287 void OwnerSettingsServiceChromeOS::AddObserver(Observer* observer) {
253 void OwnerSettingsServiceChromeOS::SetDeviceSettingsServiceForTesting( 288 if (observer)
254 DeviceSettingsService* device_settings_service) { 289 observers_.AddObserver(observer);
255 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 290 }
256 g_device_settings_service_for_testing = device_settings_service; 291
292 void OwnerSettingsServiceChromeOS::RemoveObserver(Observer* observer) {
293 observers_.RemoveObserver(observer);
257 } 294 }
258 295
259 void OwnerSettingsServiceChromeOS::OnPostKeypairLoadedActions() { 296 void OwnerSettingsServiceChromeOS::OnPostKeypairLoadedActions() {
260 DCHECK(thread_checker_.CalledOnValidThread()); 297 DCHECK(thread_checker_.CalledOnValidThread());
261 298
262 user_id_ = profile_->GetProfileName(); 299 user_id_ = profile_->GetProfileName();
263 const bool is_owner = IsOwner() || IsOwnerInTests(user_id_); 300 const bool is_owner = IsOwner() || IsOwnerInTests(user_id_);
264 if (is_owner && GetDeviceSettingsService()) 301 if (is_owner)
265 GetDeviceSettingsService()->InitOwner(user_id_, weak_factory_.GetWeakPtr()); 302 device_settings_service_->InitOwner(user_id_, weak_factory_.GetWeakPtr());
266 } 303 }
267 304
268 void OwnerSettingsServiceChromeOS::ReloadKeypairImpl(const base::Callback< 305 void OwnerSettingsServiceChromeOS::ReloadKeypairImpl(const base::Callback<
269 void(const scoped_refptr<PublicKey>& public_key, 306 void(const scoped_refptr<PublicKey>& public_key,
270 const scoped_refptr<PrivateKey>& private_key)>& callback) { 307 const scoped_refptr<PrivateKey>& private_key)>& callback) {
271 DCHECK(thread_checker_.CalledOnValidThread()); 308 DCHECK(thread_checker_.CalledOnValidThread());
272 309
273 if (waiting_for_profile_creation_ || waiting_for_tpm_token_) 310 if (waiting_for_profile_creation_ || waiting_for_tpm_token_)
274 return; 311 return;
275 scoped_refptr<base::TaskRunner> task_runner = 312 scoped_refptr<base::TaskRunner> task_runner =
276 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( 313 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
277 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); 314 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
278 task_runner->PostTask( 315 task_runner->PostTask(
279 FROM_HERE, 316 FROM_HERE,
280 base::Bind(&LoadPrivateKey, 317 base::Bind(&LoadPrivateKey,
281 owner_key_util_, 318 owner_key_util_,
282 ProfileHelper::GetUserIdHashFromProfile(profile_), 319 ProfileHelper::GetUserIdHashFromProfile(profile_),
283 callback)); 320 callback));
284 } 321 }
285 322
286 void OwnerSettingsServiceChromeOS::StartNextOperation() { 323 void OwnerSettingsServiceChromeOS::ProcessNextSetRequestAsync() {
287 DeviceSettingsService* service = GetDeviceSettingsService(); 324 DCHECK(thread_checker_.CalledOnValidThread());
288 if (!pending_operations_.empty() && service && 325 base::MessageLoop::current()->PostTask(
289 service->session_manager_client()) { 326 FROM_HERE,
290 pending_operations_.front()->Start( 327 base::Bind(&OwnerSettingsServiceChromeOS::ProcessNextSetRequest,
291 service->session_manager_client(), owner_key_util_, public_key_); 328 weak_factory_.GetWeakPtr()));
292 }
293 } 329 }
294 330
295 void OwnerSettingsServiceChromeOS::HandleCompletedOperation( 331 void OwnerSettingsServiceChromeOS::ProcessNextSetRequest() {
296 const base::Closure& callback, 332 DCHECK(thread_checker_.CalledOnValidThread());
297 SessionManagerOperation* operation, 333 if (set_requests_.empty() || set_requests_callback_factory_.HasWeakPtrs() ||
298 DeviceSettingsService::Status status) { 334 device_settings_service_->HasPendingOperations()) {
299 DCHECK_EQ(operation, pending_operations_.front()); 335 return;
300
301 DeviceSettingsService* service = GetDeviceSettingsService();
302 if (status == DeviceSettingsService::STORE_SUCCESS) {
303 service->set_policy_data(operation->policy_data().Pass());
304 service->set_device_settings(operation->device_settings().Pass());
305 } 336 }
306 337
307 if ((operation->public_key().get() && !public_key_.get()) || 338 scoped_ptr<ProcessingLoopAutoBlocker> lock(
308 (operation->public_key().get() && public_key_.get() && 339 new ProcessingLoopAutoBlocker(device_settings_service_));
309 operation->public_key()->data() != public_key_->data())) { 340
310 // Public part changed so we need to reload private part too. 341 // TODO (ygorshenin@): notify somehow DeviceSettingsProvider about tentative
311 ReloadKeypair(); 342 // change.
312 content::NotificationService::current()->Notify( 343 // crbug.com/230018
Mattias Nissler (ping if slow) 2014/10/20 12:41:30 Shouldn't this already happen in Set()?
ygorshenin1 2014/10/22 09:20:11 Done.
313 chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED, 344 SetRequest request = set_requests_.front();
314 content::Source<OwnerSettingsServiceChromeOS>(this), 345 set_requests_.pop();
315 content::NotificationService::NoDetails()); 346
347 em::ChromeDeviceSettingsProto new_settings(
348 *device_settings_service_->device_settings());
349 DeviceSettingsService::UpdateDeviceSettings(request.setting, *request.value,
350 new_settings);
351 scoped_ptr<em::PolicyData> new_policy = DeviceSettingsService::AssemblePolicy(
352 user_id_, device_settings_service_->policy_data(), &new_settings);
353 bool rv = AssembleAndSignPolicyAsync(
354 content::BrowserThread::GetBlockingPool(),
355 new_policy.Pass(),
356 base::Bind(&OwnerSettingsServiceChromeOS::OnPolicyAssembledAndSigned,
357 set_requests_callback_factory_.GetWeakPtr(),
358 Passed(&lock)));
359 if (!rv)
360 HandleError();
361 }
362
363 void OwnerSettingsServiceChromeOS::OnPolicyAssembledAndSigned(
364 scoped_ptr<ProcessingLoopAutoBlocker> blocker,
365 scoped_ptr<em::PolicyFetchResponse> policy_response) {
366 blocker.reset();
367 if (!policy_response.get()) {
368 HandleError();
369 return;
316 } 370 }
317 service->OnSignAndStoreOperationCompleted(status); 371 device_settings_service_->Store(
318 if (!callback.is_null()) 372 policy_response.Pass(),
319 callback.Run(); 373 base::Bind(&OwnerSettingsServiceChromeOS::OnSignedPolicyStored,
374 weak_factory_.GetWeakPtr()));
375 }
320 376
321 pending_operations_.pop_front(); 377 void OwnerSettingsServiceChromeOS::OnSignedPolicyStored() {
322 delete operation; 378 FOR_EACH_OBSERVER(Observer, observers_, OnSetCompleted(true));
323 StartNextOperation(); 379 ProcessNextSetRequestAsync();
380 }
381
382 void OwnerSettingsServiceChromeOS::HandleError() {
383 FOR_EACH_OBSERVER(Observer, observers_, OnSetCompleted(false));
384 ProcessNextSetRequestAsync();
324 } 385 }
325 386
326 } // namespace chromeos 387 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698