Index: chrome/browser/webdata/autofill_profile_syncable_service.cc |
diff --git a/chrome/browser/webdata/autofill_profile_syncable_service.cc b/chrome/browser/webdata/autofill_profile_syncable_service.cc |
index 60b73b5b522327ea3c75dc94d6e64c98279188f4..32356656f378bdc1ba9e4aa4fbd6b837599358a2 100644 |
--- a/chrome/browser/webdata/autofill_profile_syncable_service.cc |
+++ b/chrome/browser/webdata/autofill_profile_syncable_service.cc |
@@ -319,6 +319,15 @@ bool AutofillProfileSyncableService::OverwriteProfileWithServerData( |
AutofillProfile* profile, |
const std::string& app_locale) { |
bool diff = false; |
+ if (profile->origin() != specifics.origin()) { |
+ bool was_verified = profile->IsVerified(); |
+ profile->set_origin(specifics.origin()); |
+ diff = true; |
+ |
+ // Verified profiles should never be overwritten by unverified ones. |
+ DCHECK(!was_verified || profile->IsVerified()); |
+ } |
+ |
diff = UpdateMultivaluedField(autofill::NAME_FIRST, |
specifics.name_first(), profile) || diff; |
diff = UpdateMultivaluedField(autofill::NAME_MIDDLE, |
@@ -368,6 +377,8 @@ void AutofillProfileSyncableService::WriteAutofillProfile( |
specifics->clear_phone_home_whole_number(); |
specifics->set_guid(profile.guid()); |
+ specifics->set_origin(profile.origin()); |
+ |
std::vector<string16> values; |
profile.GetRawMultiInfo(autofill::NAME_FIRST, &values); |
for (size_t i = 0; i < values.size(); ++i) { |
@@ -435,49 +446,59 @@ AutofillProfileSyncableService::CreateOrUpdateProfile( |
const sync_pb::AutofillProfileSpecifics& autofill_specifics( |
specifics.autofill_profile()); |
- GUIDToProfileMap::iterator it = profile_map->find( |
+ GUIDToProfileMap::iterator existing_profile = profile_map->find( |
autofill_specifics.guid()); |
- if (it != profile_map->end()) { |
- // Some profile that already present is synced. |
+ if (existing_profile != profile_map->end()) { |
+ // The synced profile already exists locally. It might need to be updated. |
if (OverwriteProfileWithServerData( |
- autofill_specifics, it->second, app_locale_)) { |
- bundle->profiles_to_update.push_back(it->second); |
+ autofill_specifics, existing_profile->second, app_locale_)) { |
+ bundle->profiles_to_update.push_back(existing_profile->second); |
} |
- } else { |
- // New profile synced. |
- // TODO(isherman): Read the origin from |autofill_specifics|. |
- AutofillProfile* new_profile( |
- new AutofillProfile(autofill_specifics.guid(), std::string())); |
- OverwriteProfileWithServerData( |
- autofill_specifics, new_profile, app_locale_); |
- |
- // Check if profile appears under a different guid. |
- for (GUIDToProfileMap::iterator i = profile_map->begin(); |
- i != profile_map->end(); ++i) { |
- if (i->second->Compare(*new_profile) == 0) { |
- bundle->profiles_to_delete.push_back(i->second->guid()); |
- DVLOG(2) << "[AUTOFILL SYNC]" |
- << "Found in sync db but with a different guid: " |
- << UTF16ToUTF8(i->second->GetRawInfo(autofill::NAME_FIRST)) |
- << UTF16ToUTF8(i->second->GetRawInfo(autofill::NAME_LAST)) |
- << "New guid " << new_profile->guid() |
- << ". Profile to be deleted " << i->second->guid(); |
- profile_map->erase(i); |
- break; |
- } else if (!i->second->PrimaryValue().empty() && |
- i->second->PrimaryValue() == new_profile->PrimaryValue()) { |
- // Add it to candidates for merge - if there is no profile with this |
- // guid we will merge them. |
- bundle->candidates_to_merge.insert(std::make_pair(i->second->guid(), |
- new_profile)); |
+ return existing_profile; |
+ } |
+ |
+ |
+ // New profile synced. |
+ AutofillProfile* new_profile = new AutofillProfile( |
+ autofill_specifics.guid(), autofill_specifics.origin()); |
+ OverwriteProfileWithServerData(autofill_specifics, new_profile, app_locale_); |
+ |
+ // Check if profile appears under a different guid. |
+ // Unverified profiles should never overwrite verified ones. |
+ for (GUIDToProfileMap::iterator it = profile_map->begin(); |
+ it != profile_map->end(); ++it) { |
+ AutofillProfile* local_profile = it->second; |
+ if (local_profile->Compare(*new_profile) == 0) { |
+ // Ensure that a verified profile can never revert back to an unverified |
+ // one. |
+ if (local_profile->IsVerified() && !new_profile->IsVerified()) { |
+ new_profile->set_origin(local_profile->origin()); |
+ bundle->profiles_to_sync_back.push_back(new_profile); |
} |
+ |
+ bundle->profiles_to_delete.push_back(local_profile->guid()); |
+ DVLOG(2) << "[AUTOFILL SYNC]" |
+ << "Found in sync db but with a different guid: " |
+ << UTF16ToUTF8(local_profile->GetRawInfo(autofill::NAME_FIRST)) |
+ << UTF16ToUTF8(local_profile->GetRawInfo(autofill::NAME_LAST)) |
+ << "New guid " << new_profile->guid() |
+ << ". Profile to be deleted " << local_profile->guid(); |
+ profile_map->erase(it); |
+ break; |
+ } else if (!local_profile->IsVerified() && |
+ !new_profile->IsVerified() && |
+ !local_profile->PrimaryValue().empty() && |
+ local_profile->PrimaryValue() == new_profile->PrimaryValue()) { |
+ // Add it to candidates for merge - if there is no profile with this |
+ // guid we will merge them. |
+ bundle->candidates_to_merge.insert( |
+ std::make_pair(local_profile->guid(), new_profile)); |
} |
- profiles_.push_back(new_profile); |
- it = profile_map->insert(std::make_pair(new_profile->guid(), |
- new_profile)).first; |
- bundle->profiles_to_add.push_back(new_profile); |
} |
- return it; |
+ profiles_.push_back(new_profile); |
+ bundle->profiles_to_add.push_back(new_profile); |
+ return profile_map->insert(std::make_pair(new_profile->guid(), |
+ new_profile)).first; |
} |
void AutofillProfileSyncableService::ActOnChange( |
@@ -582,7 +603,8 @@ bool AutofillProfileSyncableService::MergeProfile( |
AutofillProfile* merge_into, |
const std::string& app_locale) { |
merge_into->OverwriteWithOrAddTo(merge_from, app_locale); |
- return (merge_into->Compare(merge_from) != 0); |
+ return (merge_into->Compare(merge_from) != 0 || |
+ merge_into->origin() != merge_from.origin()); |
} |
AutofillTable* AutofillProfileSyncableService::GetAutofillTable() const { |