Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |