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

Side by Side Diff: components/autofill/core/browser/personal_data_manager.cc

Issue 2533303007: [Autofill] Transfer cards' billing address id when deduping profiles. (Closed)
Patch Set: Created 4 years 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "components/autofill/core/browser/personal_data_manager.h" 5 #include "components/autofill/core/browser/personal_data_manager.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <list> 10 #include <list>
(...skipping 993 matching lines...) Expand 10 before | Expand all | Expand 10 after
1004 if (a->IsVerified() != b->IsVerified()) 1004 if (a->IsVerified() != b->IsVerified())
1005 return !a->IsVerified(); 1005 return !a->IsVerified();
1006 return a->CompareFrecency(b.get(), comparison_time); 1006 return a->CompareFrecency(b.get(), comparison_time);
1007 }); 1007 });
1008 1008
1009 // Set to true if |existing_profiles| already contains an equivalent profile. 1009 // Set to true if |existing_profiles| already contains an equivalent profile.
1010 bool matching_profile_found = false; 1010 bool matching_profile_found = false;
1011 std::string guid = new_profile.guid(); 1011 std::string guid = new_profile.guid();
1012 1012
1013 // If we have already saved this address, merge in any missing values. 1013 // If we have already saved this address, merge in any missing values.
1014 // Only merge with the first match. 1014 // Only merge with the first match. Merging the new profile into the existing
1015 // one preserves the validity of credit card's billing address reference.
1015 AutofillProfileComparator comparator(app_locale); 1016 AutofillProfileComparator comparator(app_locale);
1016 for (const auto& existing_profile : *existing_profiles) { 1017 for (const auto& existing_profile : *existing_profiles) {
1017 if (!matching_profile_found && 1018 if (!matching_profile_found &&
1018 comparator.AreMergeable(new_profile, *existing_profile) && 1019 comparator.AreMergeable(new_profile, *existing_profile) &&
1019 existing_profile->SaveAdditionalInfo(new_profile, app_locale)) { 1020 existing_profile->SaveAdditionalInfo(new_profile, app_locale)) {
1020 // Unverified profiles should always be updated with the newer data, 1021 // Unverified profiles should always be updated with the newer data,
1021 // whereas verified profiles should only ever be overwritten by verified 1022 // whereas verified profiles should only ever be overwritten by verified
1022 // data. If an automatically aggregated profile would overwrite a 1023 // data. If an automatically aggregated profile would overwrite a
1023 // verified profile, just drop it. 1024 // verified profile, just drop it.
1024 matching_profile_found = true; 1025 matching_profile_found = true;
(...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after
1696 current_major_version) { 1697 current_major_version) {
1697 DVLOG(1) 1698 DVLOG(1)
1698 << "Autofill profile de-duplication already performed for this version"; 1699 << "Autofill profile de-duplication already performed for this version";
1699 return false; 1700 return false;
1700 } 1701 }
1701 1702
1702 DVLOG(1) << "Starting autofill profile de-duplication."; 1703 DVLOG(1) << "Starting autofill profile de-duplication.";
1703 std::unordered_set<AutofillProfile*> profiles_to_delete; 1704 std::unordered_set<AutofillProfile*> profiles_to_delete;
1704 profiles_to_delete.reserve(web_profiles_.size()); 1705 profiles_to_delete.reserve(web_profiles_.size());
1705 1706
1706 DedupeProfiles(&web_profiles_, &profiles_to_delete); 1707 // Create the map used to update credit card's billing addresses after the
1708 // dedupe.
1709 std::unordered_map<std::string, std::string> guids_merge_map;
1707 1710
1708 // Apply the changes to the database. 1711 DedupeProfiles(&web_profiles_, &profiles_to_delete, &guids_merge_map);
1712
1713 // Apply the profile changes to the database.
1709 for (const auto& profile : web_profiles_) { 1714 for (const auto& profile : web_profiles_) {
1710 // If the profile was set to be deleted, remove it from the database. 1715 // If the profile was set to be deleted, remove it from the database.
1711 if (profiles_to_delete.count(profile.get())) { 1716 if (profiles_to_delete.count(profile.get())) {
1712 database_->RemoveAutofillProfile(profile->guid()); 1717 database_->RemoveAutofillProfile(profile->guid());
1713 } else { 1718 } else {
1714 // Otherwise, update the profile in the database. 1719 // Otherwise, update the profile in the database.
1715 database_->UpdateAutofillProfile(*profile); 1720 database_->UpdateAutofillProfile(*profile);
1716 } 1721 }
1717 } 1722 }
1718 1723
1724 UpdateCardsBillingAddressReference(guids_merge_map);
1725
1719 // Set the pref to the current major version. 1726 // Set the pref to the current major version.
1720 pref_service_->SetInteger(prefs::kAutofillLastVersionDeduped, 1727 pref_service_->SetInteger(prefs::kAutofillLastVersionDeduped,
1721 current_major_version); 1728 current_major_version);
1722 1729
1723 // Refresh the local cache and send notifications to observers. 1730 // Refresh the local cache and send notifications to observers.
1724 Refresh(); 1731 Refresh();
1725 1732
1726 return true; 1733 return true;
1727 } 1734 }
1728 1735
1729 void PersonalDataManager::DedupeProfiles( 1736 void PersonalDataManager::DedupeProfiles(
1730 std::vector<std::unique_ptr<AutofillProfile>>* existing_profiles, 1737 std::vector<std::unique_ptr<AutofillProfile>>* existing_profiles,
1731 std::unordered_set<AutofillProfile*>* profiles_to_delete) { 1738 std::unordered_set<AutofillProfile*>* profiles_to_delete,
1739 std::unordered_map<std::string, std::string>* guids_merge_map) {
1732 AutofillMetrics::LogNumberOfProfilesConsideredForDedupe( 1740 AutofillMetrics::LogNumberOfProfilesConsideredForDedupe(
1733 existing_profiles->size()); 1741 existing_profiles->size());
1734 1742
1735 // Sort the profiles by frecency with all the verified profiles at the end. 1743 // Sort the profiles by frecency with all the verified profiles at the end.
1736 // That way the most relevant profiles will get merged into the less relevant 1744 // That way the most relevant profiles will get merged into the less relevant
1737 // profiles, which keeps the syntax of the most relevant profiles data. 1745 // profiles, which keeps the syntax of the most relevant profiles data.
1738 // Verified profiles are put at the end because they do not merge into other 1746 // Verified profiles are put at the end because they do not merge into other
1739 // profiles, so the loop can be stopped when we reach those. However they need 1747 // profiles, so the loop can be stopped when we reach those. However they need
1740 // to be in the vector because an unverified profile trying to merge into a 1748 // to be in the vector because an unverified profile trying to merge into a
1741 // similar verified profile will be discarded. 1749 // similar verified profile will be discarded.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1775 // Move on if the profiles are not mergeable. 1783 // Move on if the profiles are not mergeable.
1776 if (!comparator.AreMergeable(*existing_profile, *profile_to_merge)) 1784 if (!comparator.AreMergeable(*existing_profile, *profile_to_merge))
1777 continue; 1785 continue;
1778 1786
1779 // The profiles are found to be mergeable. Attempt to update the existing 1787 // The profiles are found to be mergeable. Attempt to update the existing
1780 // profile. This returns true if the merge was successful, or if the 1788 // profile. This returns true if the merge was successful, or if the
1781 // merge would have been successful but the existing profile IsVerified() 1789 // merge would have been successful but the existing profile IsVerified()
1782 // and will not accept updates from profile_to_merge. 1790 // and will not accept updates from profile_to_merge.
1783 if (existing_profile->SaveAdditionalInfo(*profile_to_merge, 1791 if (existing_profile->SaveAdditionalInfo(*profile_to_merge,
1784 app_locale_)) { 1792 app_locale_)) {
1793 // Keep track of the merges to update cards billing address references.
Mathieu 2016/12/02 21:12:39 Make the comment more specific to the reader: Keep
sebsg 2016/12/02 21:46:34 Done.
1794 guids_merge_map->insert(std::pair<std::string, std::string>(
1795 profile_to_merge->guid(), existing_profile->guid()));
1796
1785 // Since |profile_to_merge| was a duplicate of |existing_profile| 1797 // Since |profile_to_merge| was a duplicate of |existing_profile|
1786 // and was merged successfully, it can now be deleted. 1798 // and was merged successfully, it can now be deleted.
1787 profiles_to_delete->insert(profile_to_merge); 1799 profiles_to_delete->insert(profile_to_merge);
1788 1800
1789 // Now try to merge the new resulting profile with the rest of the 1801 // Now try to merge the new resulting profile with the rest of the
1790 // existing profiles. 1802 // existing profiles.
1791 profile_to_merge = existing_profile; 1803 profile_to_merge = existing_profile;
1792 1804
1793 // Verified profiles do not get merged. Save some time by not 1805 // Verified profiles do not get merged. Save some time by not
1794 // trying. 1806 // trying.
1795 if (profile_to_merge->IsVerified()) 1807 if (profile_to_merge->IsVerified())
1796 break; 1808 break;
1797 } 1809 }
1798 } 1810 }
1799 } 1811 }
1800 AutofillMetrics::LogNumberOfProfilesRemovedDuringDedupe( 1812 AutofillMetrics::LogNumberOfProfilesRemovedDuringDedupe(
1801 profiles_to_delete->size()); 1813 profiles_to_delete->size());
1802 } 1814 }
1803 1815
1816 void PersonalDataManager::UpdateCardsBillingAddressReference(
1817 const std::unordered_map<std::string, std::string>& guids_merge_map) {
1818 for (auto& credit_card : local_credit_cards_) {
Mathieu 2016/12/02 21:12:39 The ASCII art that you have in the test would be u
sebsg 2016/12/02 21:46:34 Done.
1819 bool was_modified = false;
Mathieu 2016/12/02 21:12:39 nit: bring closer to the while loop
sebsg 2016/12/02 21:46:34 Done.
1820
1821 // If the billing address profile associated with the card has been merged,
1822 // replace it by the id of the profile in which it was merged. Repeat the
1823 // process until the billing address has not been merged into another one.
1824 while (guids_merge_map.count(credit_card->billing_address_id())) {
Mathieu 2016/12/02 21:12:39 what if there is no billing_address_id? Should we
Roger McFarlane (Chromium) 2016/12/02 21:23:05 the count() and the at() both do a map lookup. May
sebsg 2016/12/02 21:46:34 Sure, I thought the other way was more readable, b
sebsg 2016/12/02 21:46:34 Done.
1825 was_modified = true;
1826 credit_card->set_billing_address_id(
1827 guids_merge_map.at(credit_card->billing_address_id()));
Mathieu 2016/12/02 21:12:39 what about guids_merge_map[credit_card->billing_ad
sebsg 2016/12/02 21:46:33 In this use case they would be equivalent, but I c
1828 }
1829
1830 // If the card was modified, apply the changes to the database.
1831 if (was_modified) {
1832 database_->UpdateCreditCard(*credit_card);
1833 }
1834 }
1835 }
1836
1804 } // namespace autofill 1837 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698