| 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_provider.h" | 5 #include "chrome/browser/chromeos/settings/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/command_line.h" | 10 #include "base/command_line.h" | 
| 11 #include "base/file_util.h" | 11 #include "base/file_util.h" | 
| 12 #include "base/logging.h" | 12 #include "base/logging.h" | 
| 13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" | 
| 14 #include "base/prefs/pref_service.h" | 14 #include "base/prefs/pref_service.h" | 
| 15 #include "base/string_util.h" | 15 #include "base/string_util.h" | 
| 16 #include "base/threading/thread_restrictions.h" | 16 #include "base/threading/thread_restrictions.h" | 
| 17 #include "base/values.h" | 17 #include "base/values.h" | 
| 18 #include "chrome/browser/browser_process.h" | 18 #include "chrome/browser/browser_process.h" | 
| 19 #include "chrome/browser/chromeos/cros/cros_library.h" | 19 #include "chrome/browser/chromeos/cros/cros_library.h" | 
| 20 #include "chrome/browser/chromeos/cros/network_library.h" | 20 #include "chrome/browser/chromeos/cros/network_library.h" | 
| 21 #include "chrome/browser/chromeos/policy/app_pack_updater.h" |  | 
| 22 #include "chrome/browser/chromeos/settings/cros_settings.h" | 21 #include "chrome/browser/chromeos/settings/cros_settings.h" | 
| 23 #include "chrome/browser/chromeos/settings/cros_settings_names.h" | 22 #include "chrome/browser/chromeos/settings/cros_settings_names.h" | 
| 24 #include "chrome/browser/chromeos/settings/device_settings_cache.h" | 23 #include "chrome/browser/chromeos/settings/device_settings_cache.h" | 
| 25 #include "chrome/browser/policy/browser_policy_connector.h" | 24 #include "chrome/browser/policy/browser_policy_connector.h" | 
| 26 #include "chrome/browser/policy/cloud/cloud_policy_constants.h" | 25 #include "chrome/browser/policy/cloud/cloud_policy_constants.h" | 
| 27 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h" | 26 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h" | 
| 28 #include "chrome/browser/ui/options/options_util.h" | 27 #include "chrome/browser/ui/options/options_util.h" | 
| 29 #include "chrome/common/chrome_switches.h" | 28 #include "chrome/common/chrome_switches.h" | 
| 30 #include "chrome/installer/util/google_update_settings.h" | 29 #include "chrome/installer/util/google_update_settings.h" | 
| 31 | 30 | 
| 32 using google::protobuf::RepeatedPtrField; | 31 using google::protobuf::RepeatedPtrField; | 
| 33 | 32 | 
| 34 namespace em = enterprise_management; | 33 namespace em = enterprise_management; | 
| 35 | 34 | 
| 36 namespace chromeos { | 35 namespace chromeos { | 
| 37 | 36 | 
| 38 namespace { | 37 namespace { | 
| 39 | 38 | 
| 40 // List of settings handled by the DeviceSettingsProvider. | 39 // List of settings handled by the DeviceSettingsProvider. | 
| 41 const char* kKnownSettings[] = { | 40 const char* kKnownSettings[] = { | 
| 42   kAccountsPrefAllowGuest, | 41   kAccountsPrefAllowGuest, | 
| 43   kAccountsPrefAllowNewUser, | 42   kAccountsPrefAllowNewUser, | 
| 44   kAccountsPrefDeviceLocalAccounts, | 43   kAccountsPrefDeviceLocalAccounts, | 
|  | 44   kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled, | 
| 45   kAccountsPrefDeviceLocalAccountAutoLoginDelay, | 45   kAccountsPrefDeviceLocalAccountAutoLoginDelay, | 
| 46   kAccountsPrefDeviceLocalAccountAutoLoginId, | 46   kAccountsPrefDeviceLocalAccountAutoLoginId, | 
| 47   kAccountsPrefEphemeralUsersEnabled, | 47   kAccountsPrefEphemeralUsersEnabled, | 
| 48   kAccountsPrefShowUserNamesOnSignIn, | 48   kAccountsPrefShowUserNamesOnSignIn, | 
| 49   kAccountsPrefUsers, | 49   kAccountsPrefUsers, | 
| 50   kAllowRedeemChromeOsRegistrationOffers, | 50   kAllowRedeemChromeOsRegistrationOffers, | 
| 51   kAppPack, | 51   kAppPack, | 
| 52   kDeviceAttestationEnabled, | 52   kDeviceAttestationEnabled, | 
| 53   kDeviceOwner, | 53   kDeviceOwner, | 
| 54   kIdleLogoutTimeout, | 54   kIdleLogoutTimeout, | 
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 219     em::ShowUserNamesOnSigninProto* show = | 219     em::ShowUserNamesOnSigninProto* show = | 
| 220         device_settings_.mutable_show_user_names(); | 220         device_settings_.mutable_show_user_names(); | 
| 221     bool show_value; | 221     bool show_value; | 
| 222     if (value->GetAsBoolean(&show_value)) | 222     if (value->GetAsBoolean(&show_value)) | 
| 223       show->set_show_user_names(show_value); | 223       show->set_show_user_names(show_value); | 
| 224     else | 224     else | 
| 225       NOTREACHED(); | 225       NOTREACHED(); | 
| 226   } else if (prop == kAccountsPrefDeviceLocalAccounts) { | 226   } else if (prop == kAccountsPrefDeviceLocalAccounts) { | 
| 227     em::DeviceLocalAccountsProto* device_local_accounts = | 227     em::DeviceLocalAccountsProto* device_local_accounts = | 
| 228         device_settings_.mutable_device_local_accounts(); | 228         device_settings_.mutable_device_local_accounts(); | 
| 229     base::ListValue* accounts_list; | 229     device_local_accounts->clear_account(); | 
|  | 230     const base::ListValue* accounts_list = NULL; | 
| 230     if (value->GetAsList(&accounts_list)) { | 231     if (value->GetAsList(&accounts_list)) { | 
| 231       for (base::ListValue::const_iterator entry(accounts_list->begin()); | 232       for (base::ListValue::const_iterator entry(accounts_list->begin()); | 
| 232            entry != accounts_list->end(); ++entry) { | 233            entry != accounts_list->end(); ++entry) { | 
| 233         std::string id; | 234         const base::DictionaryValue* entry_dict = NULL; | 
| 234         if ((*entry)->GetAsString(&id)) | 235         if ((*entry)->GetAsDictionary(&entry_dict)) { | 
| 235           device_local_accounts->add_account()->set_id(id); | 236           em::DeviceLocalAccountInfoProto* account = | 
| 236         else | 237               device_local_accounts->add_account(); | 
|  | 238           std::string account_id; | 
|  | 239           if (entry_dict->GetStringWithoutPathExpansion( | 
|  | 240                   kAccountsPrefDeviceLocalAccountsKeyId, &account_id)) { | 
|  | 241             account->set_account_id(account_id); | 
|  | 242           } | 
|  | 243           int type; | 
|  | 244           if (entry_dict->GetIntegerWithoutPathExpansion( | 
|  | 245                   kAccountsPrefDeviceLocalAccountsKeyType, &type)) { | 
|  | 246             account->set_type( | 
|  | 247                 static_cast<em::DeviceLocalAccountInfoProto::AccountType>( | 
|  | 248                     type)); | 
|  | 249           } | 
|  | 250           std::string kiosk_app_id; | 
|  | 251           if (entry_dict->GetStringWithoutPathExpansion( | 
|  | 252                   kAccountsPrefDeviceLocalAccountsKeyKioskAppId, | 
|  | 253                   &kiosk_app_id)) { | 
|  | 254             account->mutable_kiosk_app()->set_app_id(kiosk_app_id); | 
|  | 255           } | 
|  | 256           std::string kiosk_app_update_url; | 
|  | 257           if (entry_dict->GetStringWithoutPathExpansion( | 
|  | 258                   kAccountsPrefDeviceLocalAccountsKeyKioskAppUpdateURL, | 
|  | 259                   &kiosk_app_update_url)) { | 
|  | 260             account->mutable_kiosk_app()->set_update_url(kiosk_app_update_url); | 
|  | 261           } | 
|  | 262         } else { | 
| 237           NOTREACHED(); | 263           NOTREACHED(); | 
|  | 264         } | 
| 238       } | 265       } | 
| 239     } else { | 266     } else { | 
| 240       NOTREACHED(); | 267       NOTREACHED(); | 
| 241     } | 268     } | 
| 242   } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginId) { | 269   } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginId) { | 
| 243     em::DeviceLocalAccountsProto* device_local_accounts = | 270     em::DeviceLocalAccountsProto* device_local_accounts = | 
| 244         device_settings_.mutable_device_local_accounts(); | 271         device_settings_.mutable_device_local_accounts(); | 
| 245     std::string id; | 272     std::string id; | 
| 246     if (value->GetAsString(&id)) | 273     if (value->GetAsString(&id)) | 
| 247       device_local_accounts->set_auto_login_id(id); | 274       device_local_accounts->set_auto_login_id(id); | 
| 248     else | 275     else | 
| 249       NOTREACHED(); | 276       NOTREACHED(); | 
| 250   } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginDelay) { | 277   } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginDelay) { | 
| 251     em::DeviceLocalAccountsProto* device_local_accounts = | 278     em::DeviceLocalAccountsProto* device_local_accounts = | 
| 252         device_settings_.mutable_device_local_accounts(); | 279         device_settings_.mutable_device_local_accounts(); | 
| 253     int delay; | 280     int delay; | 
| 254     if (value->GetAsInteger(&delay)) | 281     if (value->GetAsInteger(&delay)) | 
| 255       device_local_accounts->set_auto_login_delay(delay); | 282       device_local_accounts->set_auto_login_delay(delay); | 
| 256     else | 283     else | 
| 257       NOTREACHED(); | 284       NOTREACHED(); | 
|  | 285   } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled) { | 
|  | 286     em::DeviceLocalAccountsProto* device_local_accounts = | 
|  | 287         device_settings_.mutable_device_local_accounts(); | 
|  | 288     bool enabled; | 
|  | 289     if (value->GetAsBoolean(&enabled)) | 
|  | 290       device_local_accounts->set_enable_auto_login_bailout(enabled); | 
|  | 291     else | 
|  | 292       NOTREACHED(); | 
| 258   } else if (prop == kSignedDataRoamingEnabled) { | 293   } else if (prop == kSignedDataRoamingEnabled) { | 
| 259     em::DataRoamingEnabledProto* roam = | 294     em::DataRoamingEnabledProto* roam = | 
| 260         device_settings_.mutable_data_roaming_enabled(); | 295         device_settings_.mutable_data_roaming_enabled(); | 
| 261     bool roaming_value = false; | 296     bool roaming_value = false; | 
| 262     if (value->GetAsBoolean(&roaming_value)) | 297     if (value->GetAsBoolean(&roaming_value)) | 
| 263       roam->set_data_roaming_enabled(roaming_value); | 298       roam->set_data_roaming_enabled(roaming_value); | 
| 264     else | 299     else | 
| 265       NOTREACHED(); | 300       NOTREACHED(); | 
| 266     ApplyRoamingSetting(roaming_value); | 301     ApplyRoamingSetting(roaming_value); | 
| 267   } else if (prop == kSettingProxyEverywhere) { | 302   } else if (prop == kSettingProxyEverywhere) { | 
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 426   base::ListValue* list = new base::ListValue(); | 461   base::ListValue* list = new base::ListValue(); | 
| 427   const em::UserWhitelistProto& whitelist_proto = policy.user_whitelist(); | 462   const em::UserWhitelistProto& whitelist_proto = policy.user_whitelist(); | 
| 428   const RepeatedPtrField<std::string>& whitelist = | 463   const RepeatedPtrField<std::string>& whitelist = | 
| 429       whitelist_proto.user_whitelist(); | 464       whitelist_proto.user_whitelist(); | 
| 430   for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin(); | 465   for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin(); | 
| 431        it != whitelist.end(); ++it) { | 466        it != whitelist.end(); ++it) { | 
| 432     list->Append(new base::StringValue(*it)); | 467     list->Append(new base::StringValue(*it)); | 
| 433   } | 468   } | 
| 434   new_values_cache->SetValue(kAccountsPrefUsers, list); | 469   new_values_cache->SetValue(kAccountsPrefUsers, list); | 
| 435 | 470 | 
| 436   base::ListValue* account_list = new base::ListValue(); | 471   scoped_ptr<base::ListValue> account_list(new base::ListValue()); | 
| 437   CommandLine* command_line = CommandLine::ForCurrentProcess(); | 472   CommandLine* command_line = CommandLine::ForCurrentProcess(); | 
| 438   if (!command_line->HasSwitch(switches::kDisableLocalAccounts)) { | 473   if (!command_line->HasSwitch(switches::kDisableLocalAccounts)) { | 
| 439     const em::DeviceLocalAccountsProto device_local_accounts_proto = | 474     const em::DeviceLocalAccountsProto device_local_accounts_proto = | 
| 440         policy.device_local_accounts(); | 475         policy.device_local_accounts(); | 
| 441     const RepeatedPtrField<em::DeviceLocalAccountInfoProto>& accounts = | 476     const RepeatedPtrField<em::DeviceLocalAccountInfoProto>& accounts = | 
| 442         device_local_accounts_proto.account(); | 477         device_local_accounts_proto.account(); | 
| 443     RepeatedPtrField<em::DeviceLocalAccountInfoProto>::const_iterator entry; | 478     RepeatedPtrField<em::DeviceLocalAccountInfoProto>::const_iterator entry; | 
| 444     for (entry = accounts.begin(); entry != accounts.end(); ++entry) { | 479     for (entry = accounts.begin(); entry != accounts.end(); ++entry) { | 
| 445       if (entry->has_id()) | 480       scoped_ptr<base::DictionaryValue> entry_dict(new base::DictionaryValue()); | 
| 446         account_list->AppendString(entry->id()); | 481       if (entry->has_type()) { | 
|  | 482         if (entry->has_account_id()) { | 
|  | 483           entry_dict->SetStringWithoutPathExpansion( | 
|  | 484               kAccountsPrefDeviceLocalAccountsKeyId, entry->account_id()); | 
|  | 485         } | 
|  | 486         entry_dict->SetIntegerWithoutPathExpansion( | 
|  | 487             kAccountsPrefDeviceLocalAccountsKeyType, entry->type()); | 
|  | 488         if (entry->kiosk_app().has_app_id()) { | 
|  | 489           entry_dict->SetStringWithoutPathExpansion( | 
|  | 490               kAccountsPrefDeviceLocalAccountsKeyKioskAppId, | 
|  | 491               entry->kiosk_app().app_id()); | 
|  | 492         } | 
|  | 493         if (entry->kiosk_app().has_update_url()) { | 
|  | 494           entry_dict->SetStringWithoutPathExpansion( | 
|  | 495               kAccountsPrefDeviceLocalAccountsKeyKioskAppUpdateURL, | 
|  | 496               entry->kiosk_app().update_url()); | 
|  | 497         } | 
|  | 498       } else if (entry->has_id()) { | 
|  | 499         // Deprecated public session specification. | 
|  | 500         entry_dict->SetStringWithoutPathExpansion( | 
|  | 501             kAccountsPrefDeviceLocalAccountsKeyId, entry->id()); | 
|  | 502         entry_dict->SetIntegerWithoutPathExpansion( | 
|  | 503             kAccountsPrefDeviceLocalAccountsKeyType, | 
|  | 504             DEVICE_LOCAL_ACCOUNT_TYPE_PUBLIC_SESSION); | 
|  | 505       } | 
|  | 506       account_list->Append(entry_dict.release()); | 
| 447     } | 507     } | 
| 448   } | 508   } | 
| 449   new_values_cache->SetValue(kAccountsPrefDeviceLocalAccounts, account_list); | 509   new_values_cache->SetValue(kAccountsPrefDeviceLocalAccounts, | 
| 450 | 510                              account_list.release()); | 
| 451   if (policy.has_start_up_flags()) { |  | 
| 452     base::ListValue* list = new base::ListValue(); |  | 
| 453     const em::StartUpFlagsProto& flags_proto = policy.start_up_flags(); |  | 
| 454     const RepeatedPtrField<std::string>& flags = flags_proto.flags(); |  | 
| 455     for (RepeatedPtrField<std::string>::const_iterator it = flags.begin(); |  | 
| 456          it != flags.end(); ++it) { |  | 
| 457       list->Append(new base::StringValue(*it)); |  | 
| 458     } |  | 
| 459     new_values_cache->SetValue(kStartUpFlags, list); |  | 
| 460   } |  | 
| 461 | 511 | 
| 462   if (policy.has_device_local_accounts()) { | 512   if (policy.has_device_local_accounts()) { | 
| 463     if (policy.device_local_accounts().has_auto_login_id()) { | 513     if (policy.device_local_accounts().has_auto_login_id()) { | 
| 464       new_values_cache->SetString( | 514       new_values_cache->SetString( | 
| 465           kAccountsPrefDeviceLocalAccountAutoLoginId, | 515           kAccountsPrefDeviceLocalAccountAutoLoginId, | 
| 466           policy.device_local_accounts().auto_login_id()); | 516           policy.device_local_accounts().auto_login_id()); | 
| 467     } | 517     } | 
| 468     if (policy.device_local_accounts().has_auto_login_delay()) { | 518     if (policy.device_local_accounts().has_auto_login_delay()) { | 
| 469       new_values_cache->SetInteger( | 519       new_values_cache->SetInteger( | 
| 470           kAccountsPrefDeviceLocalAccountAutoLoginDelay, | 520           kAccountsPrefDeviceLocalAccountAutoLoginDelay, | 
| 471           policy.device_local_accounts().auto_login_delay()); | 521           policy.device_local_accounts().auto_login_delay()); | 
| 472     } | 522     } | 
| 473   } | 523   } | 
|  | 524 | 
|  | 525   new_values_cache->SetBoolean( | 
|  | 526       kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled, | 
|  | 527       policy.device_local_accounts().enable_auto_login_bailout()); | 
|  | 528 | 
|  | 529   if (policy.has_start_up_flags()) { | 
|  | 530     base::ListValue* list = new base::ListValue(); | 
|  | 531     const em::StartUpFlagsProto& flags_proto = policy.start_up_flags(); | 
|  | 532     const RepeatedPtrField<std::string>& flags = flags_proto.flags(); | 
|  | 533     for (RepeatedPtrField<std::string>::const_iterator it = flags.begin(); | 
|  | 534          it != flags.end(); ++it) { | 
|  | 535       list->Append(new base::StringValue(*it)); | 
|  | 536     } | 
|  | 537     new_values_cache->SetValue(kStartUpFlags, list); | 
|  | 538   } | 
| 474 } | 539 } | 
| 475 | 540 | 
| 476 void DeviceSettingsProvider::DecodeKioskPolicies( | 541 void DeviceSettingsProvider::DecodeKioskPolicies( | 
| 477     const em::ChromeDeviceSettingsProto& policy, | 542     const em::ChromeDeviceSettingsProto& policy, | 
| 478     PrefValueMap* new_values_cache) const { | 543     PrefValueMap* new_values_cache) const { | 
| 479   if (policy.has_forced_logout_timeouts()) { | 544   if (policy.has_forced_logout_timeouts()) { | 
| 480     if (policy.forced_logout_timeouts().has_idle_logout_timeout()) { | 545     if (policy.forced_logout_timeouts().has_idle_logout_timeout()) { | 
| 481       new_values_cache->SetInteger( | 546       new_values_cache->SetInteger( | 
| 482           kIdleLogoutTimeout, | 547           kIdleLogoutTimeout, | 
| 483           policy.forced_logout_timeouts().idle_logout_timeout()); | 548           policy.forced_logout_timeouts().idle_logout_timeout()); | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 505   } | 570   } | 
| 506 | 571 | 
| 507   if (policy.has_app_pack()) { | 572   if (policy.has_app_pack()) { | 
| 508     typedef RepeatedPtrField<em::AppPackEntryProto> proto_type; | 573     typedef RepeatedPtrField<em::AppPackEntryProto> proto_type; | 
| 509     base::ListValue* list = new base::ListValue; | 574     base::ListValue* list = new base::ListValue; | 
| 510     const proto_type& app_pack = policy.app_pack().app_pack(); | 575     const proto_type& app_pack = policy.app_pack().app_pack(); | 
| 511     for (proto_type::const_iterator it = app_pack.begin(); | 576     for (proto_type::const_iterator it = app_pack.begin(); | 
| 512          it != app_pack.end(); ++it) { | 577          it != app_pack.end(); ++it) { | 
| 513       base::DictionaryValue* entry = new base::DictionaryValue; | 578       base::DictionaryValue* entry = new base::DictionaryValue; | 
| 514       if (it->has_extension_id()) { | 579       if (it->has_extension_id()) { | 
| 515         entry->SetString(policy::AppPackUpdater::kExtensionId, | 580         entry->SetStringWithoutPathExpansion(kAppPackKeyExtensionId, | 
| 516                          it->extension_id()); | 581                                              it->extension_id()); | 
| 517       } | 582       } | 
| 518       if (it->has_update_url()) | 583       if (it->has_update_url()) { | 
| 519         entry->SetString(policy::AppPackUpdater::kUpdateUrl, it->update_url()); | 584         entry->SetStringWithoutPathExpansion(kAppPackKeyUpdateUrl, | 
|  | 585                                              it->update_url()); | 
|  | 586       } | 
| 520       list->Append(entry); | 587       list->Append(entry); | 
| 521     } | 588     } | 
| 522     new_values_cache->SetValue(kAppPack, list); | 589     new_values_cache->SetValue(kAppPack, list); | 
| 523   } | 590   } | 
| 524 | 591 | 
| 525   if (policy.has_start_up_urls()) { | 592   if (policy.has_start_up_urls()) { | 
| 526     base::ListValue* list = new base::ListValue(); | 593     base::ListValue* list = new base::ListValue(); | 
| 527     const em::StartUpUrlsProto& urls_proto = policy.start_up_urls(); | 594     const em::StartUpUrlsProto& urls_proto = policy.start_up_urls(); | 
| 528     const RepeatedPtrField<std::string>& urls = urls_proto.start_up_urls(); | 595     const RepeatedPtrField<std::string>& urls = urls_proto.start_up_urls(); | 
| 529     for (RepeatedPtrField<std::string>::const_iterator it = urls.begin(); | 596     for (RepeatedPtrField<std::string>::const_iterator it = urls.begin(); | 
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 872 void DeviceSettingsProvider::AttemptMigration() { | 939 void DeviceSettingsProvider::AttemptMigration() { | 
| 873   if (device_settings_service_->HasPrivateOwnerKey()) { | 940   if (device_settings_service_->HasPrivateOwnerKey()) { | 
| 874     PrefValueMap::const_iterator i; | 941     PrefValueMap::const_iterator i; | 
| 875     for (i = migration_values_.begin(); i != migration_values_.end(); ++i) | 942     for (i = migration_values_.begin(); i != migration_values_.end(); ++i) | 
| 876       DoSet(i->first, *i->second); | 943       DoSet(i->first, *i->second); | 
| 877     migration_values_.Clear(); | 944     migration_values_.Clear(); | 
| 878   } | 945   } | 
| 879 } | 946 } | 
| 880 | 947 | 
| 881 }  // namespace chromeos | 948 }  // namespace chromeos | 
| OLD | NEW | 
|---|