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

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

Issue 2734463004: [Payments] Update server card billing if the address has already converted (Closed)
Patch Set: Addressed comments Created 3 years, 9 months 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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_da ta.h" 48 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_da ta.h"
49 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_fo rmatter.h" 49 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_fo rmatter.h"
50 50
51 namespace autofill { 51 namespace autofill {
52 namespace { 52 namespace {
53 53
54 using ::i18n::addressinput::AddressField; 54 using ::i18n::addressinput::AddressField;
55 using ::i18n::addressinput::GetStreetAddressLinesAsSingleLine; 55 using ::i18n::addressinput::GetStreetAddressLinesAsSingleLine;
56 using ::i18n::addressinput::STREET_ADDRESS; 56 using ::i18n::addressinput::STREET_ADDRESS;
57 57
58 // The length of a local profile GUID.
59 const int LOCAL_GUID_LENGTH = 36;
60
58 template<typename T> 61 template<typename T>
59 class FormGroupMatchesByGUIDFunctor { 62 class FormGroupMatchesByGUIDFunctor {
60 public: 63 public:
61 explicit FormGroupMatchesByGUIDFunctor(const std::string& guid) 64 explicit FormGroupMatchesByGUIDFunctor(const std::string& guid)
62 : guid_(guid) { 65 : guid_(guid) {
63 } 66 }
64 67
65 bool operator()(const T& form_group) { 68 bool operator()(const T& form_group) {
66 return form_group.guid() == guid_; 69 return form_group.guid() == guid_;
67 } 70 }
(...skipping 1171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1239 std::string guid = 1242 std::string guid =
1240 MergeProfile(imported_profile, &web_profiles_, app_locale_, &profiles); 1243 MergeProfile(imported_profile, &web_profiles_, app_locale_, &profiles);
1241 SetProfiles(&profiles); 1244 SetProfiles(&profiles);
1242 return guid; 1245 return guid;
1243 } 1246 }
1244 1247
1245 void PersonalDataManager::NotifyPersonalDataChanged() { 1248 void PersonalDataManager::NotifyPersonalDataChanged() {
1246 for (PersonalDataManagerObserver& observer : observers_) 1249 for (PersonalDataManagerObserver& observer : observers_)
1247 observer.OnPersonalDataChanged(); 1250 observer.OnPersonalDataChanged();
1248 1251
1249 // If new data was synced, try to convert new server profiles. 1252 // If new data was synced, try to convert new server profiles and update
1253 // server cards.
1250 if (has_synced_new_data_) { 1254 if (has_synced_new_data_) {
1251 has_synced_new_data_ = false; 1255 has_synced_new_data_ = false;
1252 ConvertWalletAddressesToLocalProfiles(); 1256 ConvertWalletAddressesAndUpdateWalletCards();
1253 } 1257 }
1254 } 1258 }
1255 1259
1256 std::string PersonalDataManager::SaveImportedCreditCard( 1260 std::string PersonalDataManager::SaveImportedCreditCard(
1257 const CreditCard& imported_card) { 1261 const CreditCard& imported_card) {
1258 DCHECK(!imported_card.number().empty()); 1262 DCHECK(!imported_card.number().empty());
1259 if (is_off_the_record_) 1263 if (is_off_the_record_)
1260 return std::string(); 1264 return std::string();
1261 1265
1262 // Set to true if |imported_card| is merged into the credit card list. 1266 // Set to true if |imported_card| is merged into the credit card list.
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after
1843 // If the card was modified, apply the changes to the database. 1847 // If the card was modified, apply the changes to the database.
1844 if (was_modified) { 1848 if (was_modified) {
1845 if (credit_card->record_type() == CreditCard::LOCAL_CARD) 1849 if (credit_card->record_type() == CreditCard::LOCAL_CARD)
1846 database_->UpdateCreditCard(*credit_card); 1850 database_->UpdateCreditCard(*credit_card);
1847 else 1851 else
1848 database_->UpdateServerCardMetadata(*credit_card); 1852 database_->UpdateServerCardMetadata(*credit_card);
1849 } 1853 }
1850 } 1854 }
1851 } 1855 }
1852 1856
1853 void PersonalDataManager::ConvertWalletAddressesToLocalProfiles() { 1857 void PersonalDataManager::ConvertWalletAddressesAndUpdateWalletCards() {
1854 // Copy the local profiles into a vector<AutofillProfile>. Theses are the 1858 // Copy the local profiles into a vector<AutofillProfile>. Theses are the
1855 // existing profiles. Get them sorted in decreasing order of frecency, so the 1859 // existing profiles. Get them sorted in decreasing order of frecency, so the
1856 // "best" profiles are checked first. Put the verified profiles last so the 1860 // "best" profiles are checked first. Put the verified profiles last so the
1857 // server addresses have a chance to merge into the non-verified local 1861 // server addresses have a chance to merge into the non-verified local
1858 // profiles. 1862 // profiles.
1859 std::vector<AutofillProfile> local_profiles; 1863 std::vector<AutofillProfile> local_profiles;
1860 for (AutofillProfile* existing_profile : GetProfilesToSuggest()) { 1864 for (AutofillProfile* existing_profile : GetProfilesToSuggest()) {
1861 local_profiles.push_back(*existing_profile); 1865 local_profiles.push_back(*existing_profile);
1862 } 1866 }
1863 1867
1868 // Since we are already iterating on all the server profiles to convert Wallet
1869 // addresses and we will need to access them by guid later to update the
1870 // Wallet cards, create a map here.
1871 std::unordered_map<std::string, AutofillProfile*> server_id_profiles_map;
1872
1864 // Create the map used to update credit card's billing addresses after the 1873 // Create the map used to update credit card's billing addresses after the
1865 // convertion/merge. 1874 // convertion/merge.
1866 std::unordered_map<std::string, std::string> guids_merge_map; 1875 std::unordered_map<std::string, std::string> guids_merge_map;
1867 1876
1877 bool has_converted_addresses = ConvertWalletAddressesToLocalProfiles(
1878 &local_profiles, &server_id_profiles_map, &guids_merge_map);
1879 bool should_update_cards = UpdateWalletCardsAlreadyConvertedBillingAddresses(
1880 &local_profiles, &server_id_profiles_map, &guids_merge_map);
1881
1882 if (has_converted_addresses) {
1883 // Save the local profiles to the DB.
1884 SetProfiles(&local_profiles);
1885 }
1886
1887 if (should_update_cards || has_converted_addresses) {
1888 // Update the credit cards billing address relationship.
1889 UpdateCardsBillingAddressReference(guids_merge_map);
1890
1891 // Force a reload of the profiles and cards.
1892 Refresh();
1893 }
1894 }
1895
1896 bool PersonalDataManager::ConvertWalletAddressesToLocalProfiles(
1897 std::vector<AutofillProfile>* local_profiles,
1898 std::unordered_map<std::string, AutofillProfile*>* server_id_profiles_map,
1899 std::unordered_map<std::string, std::string>* guids_merge_map) {
1868 bool has_converted_addresses = false; 1900 bool has_converted_addresses = false;
1869 for (std::unique_ptr<AutofillProfile>& wallet_address : server_profiles_) { 1901 for (std::unique_ptr<AutofillProfile>& wallet_address : server_profiles_) {
1902 // Add the profile to the map.
1903 server_id_profiles_map->insert(
1904 std::make_pair(wallet_address->server_id(), wallet_address.get()));
1905
1870 // If the address has not been converted yet, convert it. 1906 // If the address has not been converted yet, convert it.
1871 if (!wallet_address->has_converted()) { 1907 if (!wallet_address->has_converted()) {
1872 // Try to merge the server address into a similar local profile, or create 1908 // Try to merge the server address into a similar local profile, or create
1873 // a new local profile if no similar profile is found. 1909 // a new local profile if no similar profile is found.
1874 std::string address_guid = 1910 std::string address_guid =
1875 MergeServerAddressesIntoProfiles(*wallet_address, &local_profiles); 1911 MergeServerAddressesIntoProfiles(*wallet_address, local_profiles);
1876 1912
1877 // Update the map to transfer the billing address relationship from the 1913 // Update the map to transfer the billing address relationship from the
1878 // server address to the converted/merged local profile. 1914 // server address to the converted/merged local profile.
1879 guids_merge_map.insert(std::pair<std::string, std::string>( 1915 guids_merge_map->insert(std::pair<std::string, std::string>(
1880 wallet_address->server_id(), address_guid)); 1916 wallet_address->server_id(), address_guid));
1881 1917
1882 // Update the wallet addresses metadata to record the conversion. 1918 // Update the wallet addresses metadata to record the conversion.
1883 wallet_address->set_has_converted(true); 1919 wallet_address->set_has_converted(true);
1884 database_->UpdateServerAddressMetadata(*wallet_address); 1920 database_->UpdateServerAddressMetadata(*wallet_address);
1885 1921
1886 has_converted_addresses = true; 1922 has_converted_addresses = true;
1887 } 1923 }
1888 } 1924 }
1889 1925
1890 if (has_converted_addresses) { 1926 return has_converted_addresses;
1891 // Save the local profiles to the DB. 1927 }
1892 SetProfiles(&local_profiles);
1893 1928
1894 // Update the credit cards billing address relationship. 1929 bool PersonalDataManager::UpdateWalletCardsAlreadyConvertedBillingAddresses(
1895 UpdateCardsBillingAddressReference(guids_merge_map); 1930 std::vector<AutofillProfile>* local_profiles,
1931 std::unordered_map<std::string, AutofillProfile*>* server_id_profiles_map,
1932 std::unordered_map<std::string, std::string>* guids_merge_map) {
1933 // Look for server cards that still refer to server addresses but for which
1934 // there is no mapping. This can happen if it's a new card for which the
1935 // billing address has already been converted. This should be a no-op for most
1936 // situations. Otherwise, it should affect only one Wallet card, sinces users
1937 // do not add a lot of credit cards.
1938 AutofillProfileComparator comparator(app_locale_);
1939 bool should_update_cards = false;
1940 for (std::unique_ptr<CreditCard>& wallet_card : server_credit_cards_) {
1941 std::string billing_address_id = wallet_card->billing_address_id();
1896 1942
1897 // Force a reload of the profiles and cards. 1943 // If billing address refers to a server id and that id is not a key in the
1898 Refresh(); 1944 // guids_merge_map, it means that the card is new but the address was
1945 // already converted. Look for the matching converted profile.
1946 if (!billing_address_id.empty() &&
1947 billing_address_id.length() != LOCAL_GUID_LENGTH &&
1948 guids_merge_map->find(billing_address_id) == guids_merge_map->end()) {
1949 // Get the profile.
1950 auto it = server_id_profiles_map->find(billing_address_id);
1951 DCHECK(it != server_id_profiles_map->end());
Theresa 2017/03/07 21:58:17 I synced this morning and now I'm getting crashes
sebsg 2017/03/07 22:20:11 I am very curious on how it could trigger. Can we
1952 if (it != server_id_profiles_map->end()) {
1953 AutofillProfile* billing_address = it->second;
1954
1955 // Look for a matching local profile (DO NOT MERGE).
1956 bool matching_profile_found = false;
1957 for (auto& local_profile : *local_profiles) {
1958 if (!matching_profile_found &&
1959 comparator.AreMergeable(*billing_address, local_profile)) {
1960 matching_profile_found = true;
1961
1962 // The Wallet address matches this local profile. Add this to the
1963 // merge mapping.
1964 guids_merge_map->insert(std::pair<std::string, std::string>(
1965 billing_address_id, local_profile.guid()));
1966 should_update_cards = true;
1967 }
1968 }
1969 }
1970 }
1899 } 1971 }
1972
1973 return should_update_cards;
1900 } 1974 }
1901 1975
1902 // TODO(crbug.com/687975): Reuse MergeProfiles in this function. 1976 // TODO(crbug.com/687975): Reuse MergeProfiles in this function.
1903 std::string PersonalDataManager::MergeServerAddressesIntoProfiles( 1977 std::string PersonalDataManager::MergeServerAddressesIntoProfiles(
1904 const AutofillProfile& server_address, 1978 const AutofillProfile& server_address,
1905 std::vector<AutofillProfile>* existing_profiles) { 1979 std::vector<AutofillProfile>* existing_profiles) {
1906 // Set to true if |existing_profiles| already contains an equivalent profile. 1980 // Set to true if |existing_profiles| already contains an equivalent profile.
1907 bool matching_profile_found = false; 1981 bool matching_profile_found = false;
1908 std::string guid = server_address.guid(); 1982 std::string guid = server_address.guid();
1909 1983
(...skipping 29 matching lines...) Expand all
1939 existing_profiles->back().SetRawInfo(EMAIL_ADDRESS, email); 2013 existing_profiles->back().SetRawInfo(EMAIL_ADDRESS, email);
1940 2014
1941 AutofillMetrics::LogWalletAddressConversionType( 2015 AutofillMetrics::LogWalletAddressConversionType(
1942 AutofillMetrics::CONVERTED_ADDRESS_ADDED); 2016 AutofillMetrics::CONVERTED_ADDRESS_ADDED);
1943 } 2017 }
1944 2018
1945 return guid; 2019 return guid;
1946 } 2020 }
1947 2021
1948 } // namespace autofill 2022 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698