| 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/device_settings_provider.h" | 5 #include "chrome/browser/chromeos/device_settings_provider.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 13 #include "base/threading/thread_restrictions.h" | 13 #include "base/threading/thread_restrictions.h" |
| 14 #include "base/values.h" | 14 #include "base/values.h" |
| 15 #include "chrome/browser/browser_process.h" | 15 #include "chrome/browser/browser_process.h" |
| 16 #include "chrome/browser/chromeos/cros/cros_library.h" | 16 #include "chrome/browser/chromeos/cros/cros_library.h" |
| 17 #include "chrome/browser/chromeos/cros/network_library.h" | 17 #include "chrome/browser/chromeos/cros/network_library.h" |
| 18 #include "chrome/browser/chromeos/cros_settings.h" | 18 #include "chrome/browser/chromeos/cros_settings.h" |
| 19 #include "chrome/browser/chromeos/cros_settings_names.h" | 19 #include "chrome/browser/chromeos/cros_settings_names.h" |
| 20 #include "chrome/browser/chromeos/login/ownership_service.h" | 20 #include "chrome/browser/chromeos/login/ownership_service.h" |
| 21 #include "chrome/browser/chromeos/login/signed_settings_cache.h" | 21 #include "chrome/browser/chromeos/login/signed_settings_cache.h" |
| 22 #include "chrome/browser/chromeos/login/signed_settings_helper.h" | 22 #include "chrome/browser/chromeos/login/signed_settings_helper.h" |
| 23 #include "chrome/browser/chromeos/login/user_manager.h" | 23 #include "chrome/browser/chromeos/login/user_manager.h" |
| 24 #include "chrome/browser/policy/app_pack_updater.h" | 24 #include "chrome/browser/policy/app_pack_updater.h" |
| 25 #include "chrome/browser/policy/proto/chrome_device_policy.pb.h" | |
| 26 #include "chrome/browser/ui/options/options_util.h" | 25 #include "chrome/browser/ui/options/options_util.h" |
| 27 #include "chrome/common/chrome_notification_types.h" | 26 #include "chrome/common/chrome_notification_types.h" |
| 28 #include "chrome/installer/util/google_update_settings.h" | 27 #include "chrome/installer/util/google_update_settings.h" |
| 29 #include "content/public/browser/notification_service.h" | 28 #include "content/public/browser/notification_service.h" |
| 30 | 29 |
| 31 using google::protobuf::RepeatedPtrField; | 30 using google::protobuf::RepeatedPtrField; |
| 32 | 31 |
| 33 namespace em = enterprise_management; | 32 namespace em = enterprise_management; |
| 34 | 33 |
| 35 namespace chromeos { | 34 namespace chromeos { |
| 36 | 35 |
| 37 namespace { | 36 namespace { |
| 38 | 37 |
| 39 // List of settings handled by the DeviceSettingsProvider. | 38 // List of settings handled by the DeviceSettingsProvider. |
| 40 const char* kKnownSettings[] = { | 39 const char* kKnownSettings[] = { |
| 41 kAccountsPrefAllowGuest, | 40 kAccountsPrefAllowGuest, |
| 42 kAccountsPrefAllowNewUser, | 41 kAccountsPrefAllowNewUser, |
| 43 kAccountsPrefEphemeralUsersEnabled, | 42 kAccountsPrefEphemeralUsersEnabled, |
| 44 kAccountsPrefShowUserNamesOnSignIn, | 43 kAccountsPrefShowUserNamesOnSignIn, |
| 45 kAccountsPrefUsers, | 44 kAccountsPrefUsers, |
| 46 kAppPack, | 45 kAppPack, |
| 47 kDeviceOwner, | 46 kDeviceOwner, |
| 47 kIdleLogoutTimeout, |
| 48 kIdleLogoutWarningDuration, |
| 48 kReleaseChannel, | 49 kReleaseChannel, |
| 49 kReportDeviceActivityTimes, | 50 kReportDeviceActivityTimes, |
| 50 kReportDeviceBootMode, | 51 kReportDeviceBootMode, |
| 51 kReportDeviceVersionInfo, | 52 kReportDeviceVersionInfo, |
| 53 kScreenSaverExtensionId, |
| 54 kScreenSaverTimeout, |
| 52 kSettingProxyEverywhere, | 55 kSettingProxyEverywhere, |
| 53 kSignedDataRoamingEnabled, | 56 kSignedDataRoamingEnabled, |
| 54 kStatsReportingPref, | 57 kStatsReportingPref, |
| 55 }; | 58 }; |
| 56 | 59 |
| 57 // Upper bound for number of retries to fetch a signed setting. | 60 // Upper bound for number of retries to fetch a signed setting. |
| 58 static const int kNumRetriesLimit = 9; | 61 static const int kNumRetriesLimit = 9; |
| 59 | 62 |
| 60 // Legacy policy file location. Used to detect migration from pre v12 ChromeOS. | 63 // Legacy policy file location. Used to detect migration from pre v12 ChromeOS. |
| 61 const char kLegacyPolicyFile[] = "/var/lib/whitelist/preferences"; | 64 const char kLegacyPolicyFile[] = "/var/lib/whitelist/preferences"; |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 bool ephemeral_users_enabled_value = false; | 273 bool ephemeral_users_enabled_value = false; |
| 271 if (value->GetAsBoolean(&ephemeral_users_enabled_value)) | 274 if (value->GetAsBoolean(&ephemeral_users_enabled_value)) |
| 272 ephemeral_users_enabled->set_ephemeral_users_enabled( | 275 ephemeral_users_enabled->set_ephemeral_users_enabled( |
| 273 ephemeral_users_enabled_value); | 276 ephemeral_users_enabled_value); |
| 274 else | 277 else |
| 275 NOTREACHED(); | 278 NOTREACHED(); |
| 276 } else { | 279 } else { |
| 277 // The remaining settings don't support Set(), since they are not | 280 // The remaining settings don't support Set(), since they are not |
| 278 // intended to be customizable by the user: | 281 // intended to be customizable by the user: |
| 279 // kAppPack | 282 // kAppPack |
| 283 // kIdleLogoutTimeout, |
| 284 // kIdleLogoutWarningDuration, |
| 280 // kReportDeviceVersionInfo | 285 // kReportDeviceVersionInfo |
| 281 // kReportDeviceActivityTimes | 286 // kReportDeviceActivityTimes |
| 282 // kReportDeviceBootMode | 287 // kReportDeviceBootMode |
| 288 // kScreenSaverExtensionId, |
| 289 // kScreenSaverTimeout, |
| 290 |
| 283 NOTREACHED(); | 291 NOTREACHED(); |
| 284 } | 292 } |
| 285 data.set_policy_value(pol.SerializeAsString()); | 293 data.set_policy_value(pol.SerializeAsString()); |
| 286 // Set the cache to the updated value. | 294 // Set the cache to the updated value. |
| 287 policy_ = data; | 295 policy_ = data; |
| 288 UpdateValuesCache(); | 296 UpdateValuesCache(); |
| 289 | 297 |
| 290 if (!signed_settings_cache::Store(data, g_browser_process->local_state())) | 298 if (!signed_settings_cache::Store(data, g_browser_process->local_state())) |
| 291 LOG(ERROR) << "Couldn't store to the temp storage."; | 299 LOG(ERROR) << "Couldn't store to the temp storage."; |
| 292 | 300 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 315 Reload(); | 323 Reload(); |
| 316 return; | 324 return; |
| 317 } | 325 } |
| 318 // Update the internal caches and set the trusted flag to true so that we | 326 // Update the internal caches and set the trusted flag to true so that we |
| 319 // can pass the trustedness check in the second call to SetInPolicy. | 327 // can pass the trustedness check in the second call to SetInPolicy. |
| 320 OnRetrievePolicyCompleted(code, policy); | 328 OnRetrievePolicyCompleted(code, policy); |
| 321 | 329 |
| 322 SetInPolicy(); | 330 SetInPolicy(); |
| 323 } | 331 } |
| 324 | 332 |
| 325 void DeviceSettingsProvider::UpdateValuesCache() { | 333 void DeviceSettingsProvider::DecodeLoginPolicies( |
| 326 const em::PolicyData data = policy(); | 334 const em::ChromeDeviceSettingsProto& policy, |
| 327 PrefValueMap new_values_cache; | 335 PrefValueMap* new_values_cache) const { |
| 328 | |
| 329 if (data.has_username() && !data.has_request_token()) | |
| 330 new_values_cache.SetString(kDeviceOwner, data.username()); | |
| 331 | |
| 332 em::ChromeDeviceSettingsProto pol; | |
| 333 pol.ParseFromString(data.policy_value()); | |
| 334 | |
| 335 // For all our boolean settings the following is applicable: | 336 // For all our boolean settings the following is applicable: |
| 336 // true is default permissive value and false is safe prohibitive value. | 337 // true is default permissive value and false is safe prohibitive value. |
| 337 // Exceptions: | 338 // Exceptions: |
| 338 // kSignedDataRoamingEnabled has a default value of false. | 339 // kSignedDataRoamingEnabled has a default value of false. |
| 339 // kAccountsPrefEphemeralUsersEnabled has a default value of false. | 340 // kAccountsPrefEphemeralUsersEnabled has a default value of false. |
| 340 if (pol.has_allow_new_users() && | 341 if (policy.has_allow_new_users() && |
| 341 pol.allow_new_users().has_allow_new_users() && | 342 policy.allow_new_users().has_allow_new_users() && |
| 342 pol.allow_new_users().allow_new_users()) { | 343 policy.allow_new_users().allow_new_users()) { |
| 343 // New users allowed, user_whitelist() ignored. | 344 // New users allowed, user_whitelist() ignored. |
| 344 new_values_cache.SetBoolean(kAccountsPrefAllowNewUser, true); | 345 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, true); |
| 345 } else if (!pol.has_user_whitelist()) { | 346 } else if (!policy.has_user_whitelist()) { |
| 346 // If we have the allow_new_users bool, and it is true, we honor that above. | 347 // If we have the allow_new_users bool, and it is true, we honor that above. |
| 347 // In all other cases (don't have it, have it and it is set to false, etc), | 348 // In all other cases (don't have it, have it and it is set to false, etc), |
| 348 // We will honor the user_whitelist() if it is there and populated. | 349 // We will honor the user_whitelist() if it is there and populated. |
| 349 // Otherwise we default to allowing new users. | 350 // Otherwise we default to allowing new users. |
| 350 new_values_cache.SetBoolean(kAccountsPrefAllowNewUser, true); | 351 new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, true); |
| 351 } else { | 352 } else { |
| 352 new_values_cache.SetBoolean( | 353 new_values_cache->SetBoolean( |
| 353 kAccountsPrefAllowNewUser, | 354 kAccountsPrefAllowNewUser, |
| 354 pol.user_whitelist().user_whitelist_size() == 0); | 355 policy.user_whitelist().user_whitelist_size() == 0); |
| 355 } | 356 } |
| 356 | 357 |
| 357 new_values_cache.SetBoolean( | 358 new_values_cache->SetBoolean( |
| 358 kAccountsPrefAllowGuest, | 359 kAccountsPrefAllowGuest, |
| 359 !pol.has_guest_mode_enabled() || | 360 !policy.has_guest_mode_enabled() || |
| 360 !pol.guest_mode_enabled().has_guest_mode_enabled() || | 361 !policy.guest_mode_enabled().has_guest_mode_enabled() || |
| 361 pol.guest_mode_enabled().guest_mode_enabled()); | 362 policy.guest_mode_enabled().guest_mode_enabled()); |
| 362 | 363 |
| 363 new_values_cache.SetBoolean( | 364 new_values_cache->SetBoolean( |
| 364 kAccountsPrefShowUserNamesOnSignIn, | 365 kAccountsPrefShowUserNamesOnSignIn, |
| 365 !pol.has_show_user_names() || | 366 !policy.has_show_user_names() || |
| 366 !pol.show_user_names().has_show_user_names() || | 367 !policy.show_user_names().has_show_user_names() || |
| 367 pol.show_user_names().show_user_names()); | 368 policy.show_user_names().show_user_names()); |
| 368 | 369 |
| 369 new_values_cache.SetBoolean( | 370 new_values_cache->SetBoolean( |
| 370 kSignedDataRoamingEnabled, | |
| 371 pol.has_data_roaming_enabled() && | |
| 372 pol.data_roaming_enabled().has_data_roaming_enabled() && | |
| 373 pol.data_roaming_enabled().data_roaming_enabled()); | |
| 374 | |
| 375 new_values_cache.SetBoolean( | |
| 376 kAccountsPrefEphemeralUsersEnabled, | 371 kAccountsPrefEphemeralUsersEnabled, |
| 377 pol.has_ephemeral_users_enabled() && | 372 policy.has_ephemeral_users_enabled() && |
| 378 pol.ephemeral_users_enabled().has_ephemeral_users_enabled() && | 373 policy.ephemeral_users_enabled().has_ephemeral_users_enabled() && |
| 379 pol.ephemeral_users_enabled().ephemeral_users_enabled()); | 374 policy.ephemeral_users_enabled().ephemeral_users_enabled()); |
| 380 | |
| 381 // TODO(cmasone): NOTIMPLEMENTED() once http://crosbug.com/13052 is fixed. | |
| 382 std::string serialized; | |
| 383 if (pol.has_device_proxy_settings() && | |
| 384 pol.device_proxy_settings().SerializeToString(&serialized)) { | |
| 385 new_values_cache.SetString(kSettingProxyEverywhere, serialized); | |
| 386 } | |
| 387 | |
| 388 if (!pol.has_release_channel() || | |
| 389 !pol.release_channel().has_release_channel()) { | |
| 390 // Default to an invalid channel (will be ignored). | |
| 391 new_values_cache.SetString(kReleaseChannel, ""); | |
| 392 } else { | |
| 393 new_values_cache.SetString(kReleaseChannel, | |
| 394 pol.release_channel().release_channel()); | |
| 395 } | |
| 396 | |
| 397 if (pol.has_metrics_enabled()) { | |
| 398 new_values_cache.SetBoolean(kStatsReportingPref, | |
| 399 pol.metrics_enabled().metrics_enabled()); | |
| 400 } else { | |
| 401 new_values_cache.SetBoolean(kStatsReportingPref, HasOldMetricsFile()); | |
| 402 } | |
| 403 | 375 |
| 404 base::ListValue* list = new base::ListValue(); | 376 base::ListValue* list = new base::ListValue(); |
| 405 const em::UserWhitelistProto& whitelist_proto = pol.user_whitelist(); | 377 const em::UserWhitelistProto& whitelist_proto = policy.user_whitelist(); |
| 406 const RepeatedPtrField<std::string>& whitelist = | 378 const RepeatedPtrField<std::string>& whitelist = |
| 407 whitelist_proto.user_whitelist(); | 379 whitelist_proto.user_whitelist(); |
| 408 for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin(); | 380 for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin(); |
| 409 it != whitelist.end(); ++it) { | 381 it != whitelist.end(); ++it) { |
| 410 list->Append(base::Value::CreateStringValue(*it)); | 382 list->Append(base::Value::CreateStringValue(*it)); |
| 411 } | 383 } |
| 412 new_values_cache.SetValue(kAccountsPrefUsers, list); | 384 new_values_cache->SetValue(kAccountsPrefUsers, list); |
| 385 } |
| 413 | 386 |
| 414 if (pol.has_device_reporting()) { | 387 void DeviceSettingsProvider::DecodeKioskPolicies( |
| 415 if (pol.device_reporting().has_report_version_info()) { | 388 const em::ChromeDeviceSettingsProto& policy, |
| 416 new_values_cache.SetBoolean(kReportDeviceVersionInfo, | 389 PrefValueMap* new_values_cache) const { |
| 417 pol.device_reporting().report_version_info()); | 390 if (policy.has_forced_logout_timeouts()) { |
| 391 if (policy.forced_logout_timeouts().has_idle_logout_timeout()) { |
| 392 new_values_cache->SetInteger( |
| 393 kIdleLogoutTimeout, |
| 394 policy.forced_logout_timeouts().idle_logout_timeout()); |
| 418 } | 395 } |
| 419 // TODO(dubroy): Re-add device activity time policy here when the UI | 396 |
| 420 // to notify the user has been implemented (http://crosbug.com/26252). | 397 if (policy.forced_logout_timeouts().has_idle_logout_warning_duration()) { |
| 421 if (pol.device_reporting().has_report_boot_mode()) { | 398 new_values_cache->SetInteger( |
| 422 new_values_cache.SetBoolean(kReportDeviceBootMode, | 399 kIdleLogoutWarningDuration, |
| 423 pol.device_reporting().report_boot_mode()); | 400 policy.forced_logout_timeouts().idle_logout_warning_duration()); |
| 424 } | 401 } |
| 425 } | 402 } |
| 426 | 403 |
| 427 if (pol.has_app_pack()) { | 404 if (policy.has_login_screen_saver()) { |
| 405 if (policy.login_screen_saver().has_screen_saver_timeout()) { |
| 406 new_values_cache->SetInteger( |
| 407 kScreenSaverTimeout, |
| 408 policy.login_screen_saver().screen_saver_timeout()); |
| 409 } |
| 410 |
| 411 if (policy.login_screen_saver().has_screen_saver_extension_id()) { |
| 412 new_values_cache->SetString( |
| 413 kScreenSaverExtensionId, |
| 414 policy.login_screen_saver().screen_saver_extension_id()); |
| 415 } |
| 416 } |
| 417 |
| 418 if (policy.has_app_pack()) { |
| 428 typedef RepeatedPtrField<em::AppPackEntryProto> proto_type; | 419 typedef RepeatedPtrField<em::AppPackEntryProto> proto_type; |
| 429 base::ListValue* list = new base::ListValue; | 420 base::ListValue* list = new base::ListValue; |
| 430 const proto_type& app_pack = pol.app_pack().app_pack(); | 421 const proto_type& app_pack = policy.app_pack().app_pack(); |
| 431 for (proto_type::const_iterator it = app_pack.begin(); | 422 for (proto_type::const_iterator it = app_pack.begin(); |
| 432 it != app_pack.end(); ++it) { | 423 it != app_pack.end(); ++it) { |
| 433 base::DictionaryValue* entry = new base::DictionaryValue; | 424 base::DictionaryValue* entry = new base::DictionaryValue; |
| 434 if (it->has_extension_id()) { | 425 if (it->has_extension_id()) { |
| 435 entry->SetString(policy::AppPackUpdater::kExtensionId, | 426 entry->SetString(policy::AppPackUpdater::kExtensionId, |
| 436 it->extension_id()); | 427 it->extension_id()); |
| 437 } | 428 } |
| 438 if (it->has_update_url()) | 429 if (it->has_update_url()) |
| 439 entry->SetString(policy::AppPackUpdater::kUpdateUrl, it->update_url()); | 430 entry->SetString(policy::AppPackUpdater::kUpdateUrl, it->update_url()); |
| 440 if (it->has_key_checksum()) { | 431 if (it->has_key_checksum()) { |
| 441 entry->SetString(policy::AppPackUpdater::kKeyChecksum, | 432 entry->SetString(policy::AppPackUpdater::kKeyChecksum, |
| 442 it->key_checksum()); | 433 it->key_checksum()); |
| 443 } | 434 } |
| 444 list->Append(entry); | 435 list->Append(entry); |
| 445 } | 436 } |
| 446 new_values_cache.SetValue(kAppPack, list); | 437 new_values_cache->SetValue(kAppPack, list); |
| 447 } | 438 } |
| 439 } |
| 440 |
| 441 void DeviceSettingsProvider::DecodeNetworkPolicies( |
| 442 const em::ChromeDeviceSettingsProto& policy, |
| 443 PrefValueMap* new_values_cache) const { |
| 444 new_values_cache->SetBoolean( |
| 445 kSignedDataRoamingEnabled, |
| 446 policy.has_data_roaming_enabled() && |
| 447 policy.data_roaming_enabled().has_data_roaming_enabled() && |
| 448 policy.data_roaming_enabled().data_roaming_enabled()); |
| 449 |
| 450 // TODO(cmasone): NOTIMPLEMENTED() once http://crosbug.com/13052 is fixed. |
| 451 std::string serialized; |
| 452 if (policy.has_device_proxy_settings() && |
| 453 policy.device_proxy_settings().SerializeToString(&serialized)) { |
| 454 new_values_cache->SetString(kSettingProxyEverywhere, serialized); |
| 455 } |
| 456 } |
| 457 |
| 458 void DeviceSettingsProvider::DecodeReportingPolicies( |
| 459 const em::ChromeDeviceSettingsProto& policy, |
| 460 PrefValueMap* new_values_cache) const { |
| 461 if (policy.has_device_reporting()) { |
| 462 if (policy.device_reporting().has_report_version_info()) { |
| 463 new_values_cache->SetBoolean( |
| 464 kReportDeviceVersionInfo, |
| 465 policy.device_reporting().report_version_info()); |
| 466 } |
| 467 // TODO(dubroy): Re-add device activity time policy here when the UI |
| 468 // to notify the user has been implemented (http://crosbug.com/26252). |
| 469 if (policy.device_reporting().has_report_boot_mode()) { |
| 470 new_values_cache->SetBoolean( |
| 471 kReportDeviceBootMode, |
| 472 policy.device_reporting().report_boot_mode()); |
| 473 } |
| 474 } |
| 475 } |
| 476 |
| 477 void DeviceSettingsProvider::DecodeGenericPolicies( |
| 478 const em::ChromeDeviceSettingsProto& policy, |
| 479 PrefValueMap* new_values_cache) const { |
| 480 if (policy.has_metrics_enabled()) { |
| 481 new_values_cache->SetBoolean(kStatsReportingPref, |
| 482 policy.metrics_enabled().metrics_enabled()); |
| 483 } else { |
| 484 new_values_cache->SetBoolean(kStatsReportingPref, HasOldMetricsFile()); |
| 485 } |
| 486 |
| 487 if (!policy.has_release_channel() || |
| 488 !policy.release_channel().has_release_channel()) { |
| 489 // Default to an invalid channel (will be ignored). |
| 490 new_values_cache->SetString(kReleaseChannel, ""); |
| 491 } else { |
| 492 new_values_cache->SetString(kReleaseChannel, |
| 493 policy.release_channel().release_channel()); |
| 494 } |
| 495 } |
| 496 |
| 497 void DeviceSettingsProvider::UpdateValuesCache() { |
| 498 const em::PolicyData data = policy(); |
| 499 PrefValueMap new_values_cache; |
| 500 |
| 501 if (data.has_username() && !data.has_request_token()) |
| 502 new_values_cache.SetString(kDeviceOwner, data.username()); |
| 503 |
| 504 em::ChromeDeviceSettingsProto pol; |
| 505 pol.ParseFromString(data.policy_value()); |
| 506 |
| 507 DecodeLoginPolicies(pol, &new_values_cache); |
| 508 DecodeKioskPolicies(pol, &new_values_cache); |
| 509 DecodeNetworkPolicies(pol, &new_values_cache); |
| 510 DecodeReportingPolicies(pol, &new_values_cache); |
| 511 DecodeGenericPolicies(pol, &new_values_cache); |
| 448 | 512 |
| 449 // Collect all notifications but send them only after we have swapped the | 513 // Collect all notifications but send them only after we have swapped the |
| 450 // cache so that if somebody actually reads the cache will be already valid. | 514 // cache so that if somebody actually reads the cache will be already valid. |
| 451 std::vector<std::string> notifications; | 515 std::vector<std::string> notifications; |
| 452 // Go through the new values and verify in the old ones. | 516 // Go through the new values and verify in the old ones. |
| 453 PrefValueMap::iterator iter = new_values_cache.begin(); | 517 PrefValueMap::iterator iter = new_values_cache.begin(); |
| 454 for (; iter != new_values_cache.end(); ++iter) { | 518 for (; iter != new_values_cache.end(); ++iter) { |
| 455 const base::Value* old_value; | 519 const base::Value* old_value; |
| 456 if (!values_cache_.GetValue(iter->first, &old_value) || | 520 if (!values_cache_.GetValue(iter->first, &old_value) || |
| 457 !old_value->Equals(iter->second)) { | 521 !old_value->Equals(iter->second)) { |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 Reload(); | 714 Reload(); |
| 651 return; | 715 return; |
| 652 } | 716 } |
| 653 LOG(ERROR) << "No retries left"; | 717 LOG(ERROR) << "No retries left"; |
| 654 break; | 718 break; |
| 655 } | 719 } |
| 656 } | 720 } |
| 657 } | 721 } |
| 658 | 722 |
| 659 } // namespace chromeos | 723 } // namespace chromeos |
| OLD | NEW |