| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/settings/device_settings_service.h" | 5 #include "chrome/browser/chromeos/settings/device_settings_service.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| 11 #include "base/time/time.h" | 11 #include "base/time/time.h" |
| 12 #include "chrome/browser/chrome_notification_types.h" | 12 #include "chrome/browser/chrome_notification_types.h" |
| 13 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" | |
| 14 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" | 13 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" |
| 15 #include "chrome/browser/chromeos/settings/session_manager_operation.h" | 14 #include "chrome/browser/chromeos/settings/session_manager_operation.h" |
| 16 #include "components/ownership/owner_key_util.h" | 15 #include "components/ownership/owner_key_util.h" |
| 17 #include "components/policy/core/common/cloud/cloud_policy_constants.h" | 16 #include "components/policy/core/common/cloud/cloud_policy_constants.h" |
| 18 #include "content/public/browser/browser_thread.h" | 17 #include "content/public/browser/browser_thread.h" |
| 19 #include "content/public/browser/notification_service.h" | 18 #include "content/public/browser/notification_service.h" |
| 20 #include "content/public/browser/notification_source.h" | 19 #include "content/public/browser/notification_source.h" |
| 21 #include "crypto/rsa_private_key.h" | 20 #include "crypto/rsa_private_key.h" |
| 22 | 21 |
| 23 namespace em = enterprise_management; | 22 namespace em = enterprise_management; |
| 24 | 23 |
| 25 using ownership::OwnerKeyUtil; | 24 using ownership::OwnerKeyUtil; |
| 26 using ownership::PublicKey; | 25 using ownership::PublicKey; |
| 27 | 26 |
| 28 namespace { | 27 namespace { |
| 29 | 28 |
| 30 // Delay between load retries when there was a validation error. | 29 // Delay between load retries when there was a validation error. |
| 31 // NOTE: This code is here to mitigate clock loss on some devices where policy | 30 // NOTE: This code is here to mitigate clock loss on some devices where policy |
| 32 // loads will fail with a validation error caused by RTC clock being reset when | 31 // loads will fail with a validation error caused by RTC clock being reset when |
| 33 // the battery is drained. | 32 // the battery is drained. |
| 34 int kLoadRetryDelayMs = 1000 * 5; | 33 int kLoadRetryDelayMs = 1000 * 5; |
| 35 // Maximal number of retries before we give up. Calculated to allow for 10 min | 34 // Maximal number of retries before we give up. Calculated to allow for 10 min |
| 36 // of retry time. | 35 // of retry time. |
| 37 int kMaxLoadRetries = (1000 * 60 * 10) / kLoadRetryDelayMs; | 36 int kMaxLoadRetries = (1000 * 60 * 10) / kLoadRetryDelayMs; |
| 38 | 37 |
| 38 // Assembles PolicyData based on |settings|, |policy_data| and |
| 39 // |user_id|. |
| 40 scoped_ptr<em::PolicyData> AssemblePolicy( |
| 41 const std::string& user_id, |
| 42 const em::PolicyData* policy_data, |
| 43 const em::ChromeDeviceSettingsProto* settings) { |
| 44 scoped_ptr<em::PolicyData> policy(new em::PolicyData()); |
| 45 if (policy_data) { |
| 46 // Preserve management settings. |
| 47 if (policy_data->has_management_mode()) |
| 48 policy->set_management_mode(policy_data->management_mode()); |
| 49 if (policy_data->has_request_token()) |
| 50 policy->set_request_token(policy_data->request_token()); |
| 51 if (policy_data->has_device_id()) |
| 52 policy->set_device_id(policy_data->device_id()); |
| 53 } else { |
| 54 // If there's no previous policy data, this is the first time the device |
| 55 // setting is set. We set the management mode to NOT_MANAGED initially. |
| 56 policy->set_management_mode(em::PolicyData::NOT_MANAGED); |
| 57 } |
| 58 policy->set_policy_type(policy::dm_protocol::kChromeDevicePolicyType); |
| 59 policy->set_timestamp( |
| 60 (base::Time::Now() - base::Time::UnixEpoch()).InMilliseconds()); |
| 61 policy->set_username(user_id); |
| 62 if (!settings->SerializeToString(policy->mutable_policy_value())) |
| 63 return scoped_ptr<em::PolicyData>(); |
| 64 |
| 65 return policy.Pass(); |
| 66 } |
| 67 |
| 39 // Returns true if it is okay to transfer from the current mode to the new | 68 // Returns true if it is okay to transfer from the current mode to the new |
| 40 // mode. This function should be called in SetManagementMode(). | 69 // mode. This function should be called in SetManagementMode(). |
| 41 bool CheckManagementModeTransition(em::PolicyData::ManagementMode current_mode, | 70 bool CheckManagementModeTransition(em::PolicyData::ManagementMode current_mode, |
| 42 em::PolicyData::ManagementMode new_mode) { | 71 em::PolicyData::ManagementMode new_mode) { |
| 43 // Mode is not changed. | 72 // Mode is not changed. |
| 44 if (current_mode == new_mode) | 73 if (current_mode == new_mode) |
| 45 return true; | 74 return true; |
| 46 | 75 |
| 47 switch (current_mode) { | 76 switch (current_mode) { |
| 48 case em::PolicyData::NOT_MANAGED: | 77 case em::PolicyData::NOT_MANAGED: |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 | 144 |
| 116 session_manager_client_ = session_manager_client; | 145 session_manager_client_ = session_manager_client; |
| 117 owner_key_util_ = owner_key_util; | 146 owner_key_util_ = owner_key_util; |
| 118 | 147 |
| 119 session_manager_client_->AddObserver(this); | 148 session_manager_client_->AddObserver(this); |
| 120 | 149 |
| 121 StartNextOperation(); | 150 StartNextOperation(); |
| 122 } | 151 } |
| 123 | 152 |
| 124 void DeviceSettingsService::UnsetSessionManager() { | 153 void DeviceSettingsService::UnsetSessionManager() { |
| 154 STLDeleteContainerPointers(pending_operations_.begin(), |
| 155 pending_operations_.end()); |
| 125 pending_operations_.clear(); | 156 pending_operations_.clear(); |
| 126 | 157 |
| 127 if (session_manager_client_) | 158 if (session_manager_client_) |
| 128 session_manager_client_->RemoveObserver(this); | 159 session_manager_client_->RemoveObserver(this); |
| 129 session_manager_client_ = NULL; | 160 session_manager_client_ = NULL; |
| 130 owner_key_util_ = NULL; | 161 owner_key_util_ = NULL; |
| 131 } | 162 } |
| 132 | 163 |
| 133 scoped_refptr<PublicKey> DeviceSettingsService::GetPublicKey() { | 164 scoped_refptr<PublicKey> DeviceSettingsService::GetPublicKey() { |
| 134 return public_key_; | 165 return public_key_; |
| 135 } | 166 } |
| 136 | 167 |
| 137 void DeviceSettingsService::Load() { | 168 void DeviceSettingsService::Load() { |
| 138 EnqueueLoad(false); | 169 EnqueueLoad(false); |
| 139 } | 170 } |
| 140 | 171 |
| 141 void DeviceSettingsService::SignAndStore( | 172 void DeviceSettingsService::SignAndStore( |
| 142 scoped_ptr<em::ChromeDeviceSettingsProto> new_settings, | 173 scoped_ptr<em::ChromeDeviceSettingsProto> new_settings, |
| 143 const base::Closure& callback) { | 174 const base::Closure& callback) { |
| 175 if (!owner_settings_service_) { |
| 176 HandleError(STORE_KEY_UNAVAILABLE, callback); |
| 177 return; |
| 178 } |
| 144 scoped_ptr<em::PolicyData> policy = | 179 scoped_ptr<em::PolicyData> policy = |
| 145 OwnerSettingsServiceChromeOS::AssemblePolicy( | 180 AssemblePolicy(GetUsername(), policy_data(), new_settings.get()); |
| 146 GetUsername(), policy_data(), new_settings.get()); | 181 if (!policy) { |
| 147 EnqueueSignAndStore(policy.Pass(), callback); | 182 HandleError(STORE_POLICY_ERROR, callback); |
| 183 return; |
| 184 } |
| 185 |
| 186 owner_settings_service_->SignAndStorePolicyAsync(policy.Pass(), callback); |
| 148 } | 187 } |
| 149 | 188 |
| 150 void DeviceSettingsService::SetManagementSettings( | 189 void DeviceSettingsService::SetManagementSettings( |
| 151 em::PolicyData::ManagementMode management_mode, | 190 em::PolicyData::ManagementMode management_mode, |
| 152 const std::string& request_token, | 191 const std::string& request_token, |
| 153 const std::string& device_id, | 192 const std::string& device_id, |
| 154 const base::Closure& callback) { | 193 const base::Closure& callback) { |
| 155 if (!owner_settings_service_) { | 194 if (!owner_settings_service_) { |
| 156 HandleError(STORE_KEY_UNAVAILABLE, callback); | 195 HandleError(STORE_KEY_UNAVAILABLE, callback); |
| 157 return; | 196 return; |
| 158 } | 197 } |
| 159 | 198 |
| 160 em::PolicyData::ManagementMode current_mode = em::PolicyData::NOT_MANAGED; | 199 em::PolicyData::ManagementMode current_mode = em::PolicyData::NOT_MANAGED; |
| 161 if (policy_data() && policy_data()->has_management_mode()) | 200 if (policy_data() && policy_data()->has_management_mode()) |
| 162 current_mode = policy_data()->management_mode(); | 201 current_mode = policy_data()->management_mode(); |
| 163 | 202 |
| 164 if (!CheckManagementModeTransition(current_mode, management_mode)) { | 203 if (!CheckManagementModeTransition(current_mode, management_mode)) { |
| 165 LOG(ERROR) << "Invalid management mode transition: current mode = " | 204 LOG(ERROR) << "Invalid management mode transition: current mode = " |
| 166 << current_mode << ", new mode = " << management_mode; | 205 << current_mode << ", new mode = " << management_mode; |
| 167 HandleError(DeviceSettingsService::STORE_POLICY_ERROR, callback); | 206 HandleError(DeviceSettingsService::STORE_POLICY_ERROR, callback); |
| 168 return; | 207 return; |
| 169 } | 208 } |
| 170 | 209 |
| 171 scoped_ptr<em::PolicyData> policy = | 210 scoped_ptr<em::PolicyData> policy = |
| 172 OwnerSettingsServiceChromeOS::AssemblePolicy( | 211 AssemblePolicy(GetUsername(), policy_data(), device_settings()); |
| 173 GetUsername(), policy_data(), device_settings()); | |
| 174 if (!policy) { | 212 if (!policy) { |
| 175 HandleError(DeviceSettingsService::STORE_POLICY_ERROR, callback); | 213 HandleError(DeviceSettingsService::STORE_POLICY_ERROR, callback); |
| 176 return; | 214 return; |
| 177 } | 215 } |
| 178 | 216 |
| 179 policy->set_management_mode(management_mode); | 217 policy->set_management_mode(management_mode); |
| 180 policy->set_request_token(request_token); | 218 policy->set_request_token(request_token); |
| 181 policy->set_device_id(device_id); | 219 policy->set_device_id(device_id); |
| 182 | 220 |
| 183 EnqueueSignAndStore(policy.Pass(), callback); | 221 owner_settings_service_->SignAndStorePolicyAsync(policy.Pass(), callback); |
| 184 } | 222 } |
| 185 | 223 |
| 186 void DeviceSettingsService::Store(scoped_ptr<em::PolicyFetchResponse> policy, | 224 void DeviceSettingsService::Store(scoped_ptr<em::PolicyFetchResponse> policy, |
| 187 const base::Closure& callback) { | 225 const base::Closure& callback) { |
| 188 Enqueue(linked_ptr<SessionManagerOperation>(new StoreSettingsOperation( | 226 Enqueue( |
| 189 base::Bind(&DeviceSettingsService::HandleCompletedOperation, | 227 new StoreSettingsOperation( |
| 190 weak_factory_.GetWeakPtr(), | 228 base::Bind(&DeviceSettingsService::HandleCompletedOperation, |
| 191 callback), | 229 weak_factory_.GetWeakPtr(), |
| 192 policy.Pass()))); | 230 callback), |
| 231 policy.Pass())); |
| 193 } | 232 } |
| 194 | 233 |
| 195 DeviceSettingsService::OwnershipStatus | 234 DeviceSettingsService::OwnershipStatus |
| 196 DeviceSettingsService::GetOwnershipStatus() { | 235 DeviceSettingsService::GetOwnershipStatus() { |
| 197 if (public_key_.get()) | 236 if (public_key_.get()) |
| 198 return public_key_->is_loaded() ? OWNERSHIP_TAKEN : OWNERSHIP_NONE; | 237 return public_key_->is_loaded() ? OWNERSHIP_TAKEN : OWNERSHIP_NONE; |
| 199 return OWNERSHIP_UNKNOWN; | 238 return OWNERSHIP_UNKNOWN; |
| 200 } | 239 } |
| 201 | 240 |
| 202 void DeviceSettingsService::GetOwnershipStatusAsync( | 241 void DeviceSettingsService::GetOwnershipStatusAsync( |
| (...skipping 27 matching lines...) Expand all Loading... |
| 230 username_ = username; | 269 username_ = username; |
| 231 owner_settings_service_ = owner_settings_service; | 270 owner_settings_service_ = owner_settings_service; |
| 232 | 271 |
| 233 EnsureReload(true); | 272 EnsureReload(true); |
| 234 } | 273 } |
| 235 | 274 |
| 236 const std::string& DeviceSettingsService::GetUsername() const { | 275 const std::string& DeviceSettingsService::GetUsername() const { |
| 237 return username_; | 276 return username_; |
| 238 } | 277 } |
| 239 | 278 |
| 240 ownership::OwnerSettingsService* | |
| 241 DeviceSettingsService::GetOwnerSettingsService() const { | |
| 242 return owner_settings_service_.get(); | |
| 243 } | |
| 244 | |
| 245 void DeviceSettingsService::AddObserver(Observer* observer) { | 279 void DeviceSettingsService::AddObserver(Observer* observer) { |
| 246 observers_.AddObserver(observer); | 280 observers_.AddObserver(observer); |
| 247 } | 281 } |
| 248 | 282 |
| 249 void DeviceSettingsService::RemoveObserver(Observer* observer) { | 283 void DeviceSettingsService::RemoveObserver(Observer* observer) { |
| 250 observers_.RemoveObserver(observer); | 284 observers_.RemoveObserver(observer); |
| 251 } | 285 } |
| 252 | 286 |
| 253 void DeviceSettingsService::OwnerKeySet(bool success) { | 287 void DeviceSettingsService::OwnerKeySet(bool success) { |
| 254 if (!success) { | 288 if (!success) { |
| 255 LOG(ERROR) << "Owner key change failed."; | 289 LOG(ERROR) << "Owner key change failed."; |
| 256 return; | 290 return; |
| 257 } | 291 } |
| 258 | 292 |
| 259 public_key_ = NULL; | 293 public_key_ = NULL; |
| 260 EnsureReload(true); | 294 EnsureReload(true); |
| 261 } | 295 } |
| 262 | 296 |
| 263 void DeviceSettingsService::PropertyChangeComplete(bool success) { | 297 void DeviceSettingsService::PropertyChangeComplete(bool success) { |
| 264 if (!success) { | 298 if (!success) { |
| 265 LOG(ERROR) << "Policy update failed."; | 299 LOG(ERROR) << "Policy update failed."; |
| 266 return; | 300 return; |
| 267 } | 301 } |
| 268 | 302 |
| 269 EnsureReload(false); | 303 EnsureReload(false); |
| 270 } | 304 } |
| 271 | 305 |
| 272 void DeviceSettingsService::Enqueue( | 306 void DeviceSettingsService::Enqueue(SessionManagerOperation* operation) { |
| 273 const linked_ptr<SessionManagerOperation>& operation) { | |
| 274 pending_operations_.push_back(operation); | 307 pending_operations_.push_back(operation); |
| 275 if (pending_operations_.front().get() == operation.get()) | 308 if (pending_operations_.front() == operation) |
| 276 StartNextOperation(); | 309 StartNextOperation(); |
| 277 } | 310 } |
| 278 | 311 |
| 279 void DeviceSettingsService::EnqueueLoad(bool force_key_load) { | 312 void DeviceSettingsService::EnqueueLoad(bool force_key_load) { |
| 280 linked_ptr<SessionManagerOperation> operation(new LoadSettingsOperation( | 313 SessionManagerOperation* operation = |
| 281 base::Bind(&DeviceSettingsService::HandleCompletedOperation, | 314 new LoadSettingsOperation( |
| 282 weak_factory_.GetWeakPtr(), | 315 base::Bind(&DeviceSettingsService::HandleCompletedOperation, |
| 283 base::Closure()))); | 316 weak_factory_.GetWeakPtr(), |
| 317 base::Closure())); |
| 284 operation->set_force_key_load(force_key_load); | 318 operation->set_force_key_load(force_key_load); |
| 285 operation->set_username(username_); | 319 operation->set_username(username_); |
| 286 operation->set_owner_settings_service(owner_settings_service_); | 320 operation->set_owner_settings_service(owner_settings_service_); |
| 287 Enqueue(operation); | 321 Enqueue(operation); |
| 288 } | 322 } |
| 289 | |
| 290 void DeviceSettingsService::EnqueueSignAndStore( | |
| 291 scoped_ptr<enterprise_management::PolicyData> policy, | |
| 292 const base::Closure& callback) { | |
| 293 linked_ptr<SessionManagerOperation> operation( | |
| 294 new SignAndStoreSettingsOperation( | |
| 295 base::Bind(&DeviceSettingsService::HandleCompletedOperation, | |
| 296 weak_factory_.GetWeakPtr(), | |
| 297 callback), | |
| 298 policy.Pass())); | |
| 299 operation->set_owner_settings_service(owner_settings_service_); | |
| 300 Enqueue(operation); | |
| 301 } | |
| 302 | 323 |
| 303 void DeviceSettingsService::EnsureReload(bool force_key_load) { | 324 void DeviceSettingsService::EnsureReload(bool force_key_load) { |
| 304 if (!pending_operations_.empty()) { | 325 if (!pending_operations_.empty()) { |
| 305 pending_operations_.front()->set_username(username_); | 326 pending_operations_.front()->set_username(username_); |
| 306 pending_operations_.front()->set_owner_settings_service( | 327 pending_operations_.front()->set_owner_settings_service( |
| 307 owner_settings_service_); | 328 owner_settings_service_); |
| 308 pending_operations_.front()->RestartLoad(force_key_load); | 329 pending_operations_.front()->RestartLoad(force_key_load); |
| 309 } else { | 330 } else { |
| 310 EnqueueLoad(force_key_load); | 331 EnqueueLoad(force_key_load); |
| 311 } | 332 } |
| 312 } | 333 } |
| 313 | 334 |
| 314 void DeviceSettingsService::StartNextOperation() { | 335 void DeviceSettingsService::StartNextOperation() { |
| 315 if (!pending_operations_.empty() && session_manager_client_ && | 336 if (!pending_operations_.empty() && |
| 337 session_manager_client_ && |
| 316 owner_key_util_.get()) { | 338 owner_key_util_.get()) { |
| 317 pending_operations_.front()->Start( | 339 pending_operations_.front()->Start( |
| 318 session_manager_client_, owner_key_util_, public_key_); | 340 session_manager_client_, owner_key_util_, public_key_); |
| 319 } | 341 } |
| 320 } | 342 } |
| 321 | 343 |
| 322 void DeviceSettingsService::HandleCompletedOperation( | 344 void DeviceSettingsService::HandleCompletedOperation( |
| 323 const base::Closure& callback, | 345 const base::Closure& callback, |
| 324 SessionManagerOperation* operation, | 346 SessionManagerOperation* operation, |
| 325 Status status) { | 347 Status status) { |
| 326 DCHECK_EQ(operation, pending_operations_.front().get()); | 348 DCHECK_EQ(operation, pending_operations_.front()); |
| 327 store_status_ = status; | 349 store_status_ = status; |
| 328 | 350 |
| 329 OwnershipStatus ownership_status = OWNERSHIP_UNKNOWN; | 351 OwnershipStatus ownership_status = OWNERSHIP_UNKNOWN; |
| 330 scoped_refptr<PublicKey> new_key(operation->public_key()); | 352 scoped_refptr<PublicKey> new_key(operation->public_key()); |
| 331 if (new_key.get()) { | 353 if (new_key.get()) { |
| 332 ownership_status = new_key->is_loaded() ? OWNERSHIP_TAKEN : OWNERSHIP_NONE; | 354 ownership_status = new_key->is_loaded() ? OWNERSHIP_TAKEN : OWNERSHIP_NONE; |
| 333 } else { | 355 } else { |
| 334 NOTREACHED() << "Failed to determine key status."; | 356 NOTREACHED() << "Failed to determine key status."; |
| 335 } | 357 } |
| 336 | 358 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 383 } | 405 } |
| 384 | 406 |
| 385 // The completion callback happens after the notification so clients can | 407 // The completion callback happens after the notification so clients can |
| 386 // filter self-triggered updates. | 408 // filter self-triggered updates. |
| 387 if (!callback.is_null()) | 409 if (!callback.is_null()) |
| 388 callback.Run(); | 410 callback.Run(); |
| 389 | 411 |
| 390 // Only remove the pending operation here, so new operations triggered by any | 412 // Only remove the pending operation here, so new operations triggered by any |
| 391 // of the callbacks above are queued up properly. | 413 // of the callbacks above are queued up properly. |
| 392 pending_operations_.pop_front(); | 414 pending_operations_.pop_front(); |
| 415 delete operation; |
| 393 | 416 |
| 394 StartNextOperation(); | 417 StartNextOperation(); |
| 395 } | 418 } |
| 396 | 419 |
| 397 void DeviceSettingsService::HandleError(Status status, | 420 void DeviceSettingsService::HandleError(Status status, |
| 398 const base::Closure& callback) { | 421 const base::Closure& callback) { |
| 399 store_status_ = status; | 422 store_status_ = status; |
| 400 | 423 |
| 401 LOG(ERROR) << "Session manager operation failed: " << status; | 424 LOG(ERROR) << "Session manager operation failed: " << status; |
| 402 | 425 |
| 403 FOR_EACH_OBSERVER(Observer, observers_, DeviceSettingsUpdated()); | 426 FOR_EACH_OBSERVER(Observer, observers_, DeviceSettingsUpdated()); |
| 404 | 427 |
| 405 // The completion callback happens after the notification so clients can | 428 // The completion callback happens after the notification so clients can |
| 406 // filter self-triggered updates. | 429 // filter self-triggered updates. |
| 407 if (!callback.is_null()) | 430 if (!callback.is_null()) |
| 408 callback.Run(); | 431 callback.Run(); |
| 409 } | 432 } |
| 410 | 433 |
| 434 void DeviceSettingsService::OnSignAndStoreOperationCompleted(Status status) { |
| 435 store_status_ = status; |
| 436 FOR_EACH_OBSERVER(Observer, observers_, DeviceSettingsUpdated()); |
| 437 } |
| 438 |
| 411 ScopedTestDeviceSettingsService::ScopedTestDeviceSettingsService() { | 439 ScopedTestDeviceSettingsService::ScopedTestDeviceSettingsService() { |
| 412 DeviceSettingsService::Initialize(); | 440 DeviceSettingsService::Initialize(); |
| 413 } | 441 } |
| 414 | 442 |
| 415 ScopedTestDeviceSettingsService::~ScopedTestDeviceSettingsService() { | 443 ScopedTestDeviceSettingsService::~ScopedTestDeviceSettingsService() { |
| 416 // Clean pending operations. | 444 // Clean pending operations. |
| 417 DeviceSettingsService::Get()->UnsetSessionManager(); | 445 DeviceSettingsService::Get()->UnsetSessionManager(); |
| 418 DeviceSettingsService::Shutdown(); | 446 DeviceSettingsService::Shutdown(); |
| 419 } | 447 } |
| 420 | 448 |
| 421 } // namespace chromeos | 449 } // namespace chromeos |
| OLD | NEW |