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

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

Issue 2658843004: [Autofill] Convert wallet addresses to local autofill profiles. (Closed)
Patch Set: Addressed Mathp's comments Created 3 years, 10 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 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 367
368 switch (result->GetType()) { 368 switch (result->GetType()) {
369 case AUTOFILL_PROFILES_RESULT: 369 case AUTOFILL_PROFILES_RESULT:
370 if (h == pending_profiles_query_) { 370 if (h == pending_profiles_query_) {
371 ReceiveLoadedDbValues(h, result.get(), &pending_profiles_query_, 371 ReceiveLoadedDbValues(h, result.get(), &pending_profiles_query_,
372 &web_profiles_); 372 &web_profiles_);
373 LogProfileCount(); // This only logs local profiles. 373 LogProfileCount(); // This only logs local profiles.
374 } else { 374 } else {
375 ReceiveLoadedDbValues(h, result.get(), &pending_server_profiles_query_, 375 ReceiveLoadedDbValues(h, result.get(), &pending_server_profiles_query_,
376 &server_profiles_); 376 &server_profiles_);
377
378 if (!server_profiles_.empty()) {
379 std::string account_id = signin_manager_->GetAuthenticatedAccountId();
380 base::string16 email =
381 base::UTF8ToUTF16(
382 account_tracker_->GetAccountInfo(account_id).email);
383
384 // User may have signed out during the fulfillment of the web data
385 // request, in which case there is no point updating
386 // |server_profiles_| as it will be cleared.
387 if (!email.empty()) {
388 for (auto& profile : server_profiles_)
389 profile->SetRawInfo(EMAIL_ADDRESS, email);
390 }
391 }
392 } 377 }
393 break; 378 break;
394 case AUTOFILL_CREDITCARDS_RESULT: 379 case AUTOFILL_CREDITCARDS_RESULT:
395 if (h == pending_creditcards_query_) { 380 if (h == pending_creditcards_query_) {
396 ReceiveLoadedDbValues(h, result.get(), &pending_creditcards_query_, 381 ReceiveLoadedDbValues(h, result.get(), &pending_creditcards_query_,
397 &local_credit_cards_); 382 &local_credit_cards_);
398 LogLocalCreditCardCount(); 383 LogLocalCreditCardCount();
399 } else { 384 } else {
400 ReceiveLoadedDbValues(h, result.get(), 385 ReceiveLoadedDbValues(h, result.get(),
401 &pending_server_creditcards_query_, 386 &pending_server_creditcards_query_,
(...skipping 15 matching lines...) Expand all
417 if (pending_profiles_query_ == 0 && 402 if (pending_profiles_query_ == 0 &&
418 pending_creditcards_query_ == 0 && 403 pending_creditcards_query_ == 0 &&
419 pending_server_profiles_query_ == 0 && 404 pending_server_profiles_query_ == 0 &&
420 pending_server_creditcards_query_ == 0) { 405 pending_server_creditcards_query_ == 0) {
421 is_data_loaded_ = true; 406 is_data_loaded_ = true;
422 NotifyPersonalDataChanged(); 407 NotifyPersonalDataChanged();
423 } 408 }
424 } 409 }
425 410
426 void PersonalDataManager::AutofillMultipleChanged() { 411 void PersonalDataManager::AutofillMultipleChanged() {
412 has_synced_new_data = true;
427 Refresh(); 413 Refresh();
428 } 414 }
429 415
430 void PersonalDataManager::SyncStarted(syncer::ModelType model_type) { 416 void PersonalDataManager::SyncStarted(syncer::ModelType model_type) {
431 if (model_type == syncer::AUTOFILL_PROFILE && 417 if (model_type == syncer::AUTOFILL_PROFILE &&
432 is_autofill_profile_cleanup_pending_) { 418 is_autofill_profile_cleanup_pending_) {
433 // This runs as a one-time fix, tracked in syncable prefs. If it has already 419 // This runs as a one-time fix, tracked in syncable prefs. If it has already
434 // run, it is a NOP (other than checking the pref). 420 // run, it is a NOP (other than checking the pref).
435 ApplyProfileUseDatesFix(); 421 ApplyProfileUseDatesFix();
436 422
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 return GetProfiles(false); 732 return GetProfiles(false);
747 } 733 }
748 734
749 std::vector<AutofillProfile*> PersonalDataManager::web_profiles() const { 735 std::vector<AutofillProfile*> PersonalDataManager::web_profiles() const {
750 std::vector<AutofillProfile*> result; 736 std::vector<AutofillProfile*> result;
751 for (const auto& profile : web_profiles_) 737 for (const auto& profile : web_profiles_)
752 result.push_back(profile.get()); 738 result.push_back(profile.get());
753 return result; 739 return result;
754 } 740 }
755 741
742 std::vector<AutofillProfile*> PersonalDataManager::server_profiles() const {
Roger McFarlane (Chromium) 2017/02/02 15:32:23 why not just return a const ref to server_profiles
sebsg 2017/02/02 15:46:16 Done.
743 std::vector<AutofillProfile*> result;
744 for (const auto& profile : server_profiles_)
745 result.push_back(profile.get());
746 return result;
747 }
748
756 std::vector<CreditCard*> PersonalDataManager::GetLocalCreditCards() const { 749 std::vector<CreditCard*> PersonalDataManager::GetLocalCreditCards() const {
757 std::vector<CreditCard*> result; 750 std::vector<CreditCard*> result;
758 for (const auto& card : local_credit_cards_) 751 for (const auto& card : local_credit_cards_)
759 result.push_back(card.get()); 752 result.push_back(card.get());
760 return result; 753 return result;
761 } 754 }
762 755
763 const std::vector<CreditCard*>& PersonalDataManager::GetCreditCards() const { 756 const std::vector<CreditCard*>& PersonalDataManager::GetCreditCards() const {
764 credit_cards_.clear(); 757 credit_cards_.clear();
765 for (const auto& card : local_credit_cards_) 758 for (const auto& card : local_credit_cards_)
766 credit_cards_.push_back(card.get()); 759 credit_cards_.push_back(card.get());
767 if (pref_service_->GetBoolean(prefs::kAutofillWalletImportEnabled)) { 760 if (pref_service_->GetBoolean(prefs::kAutofillWalletImportEnabled)) {
768 for (const auto& card : server_credit_cards_) 761 for (const auto& card : server_credit_cards_)
769 credit_cards_.push_back(card.get()); 762 credit_cards_.push_back(card.get());
770 } 763 }
771 return credit_cards_; 764 return credit_cards_;
772 } 765 }
773 766
774 bool PersonalDataManager::HasServerData() const {
775 return !server_credit_cards_.empty() || !server_profiles_.empty();
776 }
777
778 void PersonalDataManager::Refresh() { 767 void PersonalDataManager::Refresh() {
779 LoadProfiles(); 768 LoadProfiles();
780 LoadCreditCards(); 769 LoadCreditCards();
781 } 770 }
782 771
783 const std::vector<AutofillProfile*> PersonalDataManager::GetProfilesToSuggest() 772 const std::vector<AutofillProfile*> PersonalDataManager::GetProfilesToSuggest()
784 const { 773 const {
785 std::vector<AutofillProfile*> profiles = GetProfiles(true); 774 std::vector<AutofillProfile*> profiles = GetProfiles(true);
786 775
787 // Rank the suggestions by frecency (see AutofillDataModel for details). 776 // Rank the suggestions by frecency (see AutofillDataModel for details).
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 database_->CancelRequest(*handle); 1222 database_->CancelRequest(*handle);
1234 } 1223 }
1235 *handle = 0; 1224 *handle = 0;
1236 } 1225 }
1237 1226
1238 std::string PersonalDataManager::SaveImportedProfile( 1227 std::string PersonalDataManager::SaveImportedProfile(
1239 const AutofillProfile& imported_profile) { 1228 const AutofillProfile& imported_profile) {
1240 if (is_off_the_record_) 1229 if (is_off_the_record_)
1241 return std::string(); 1230 return std::string();
1242 1231
1243 // Don't save a web profile if the data in the profile is a subset of a
1244 // server profile, but do record the fact that it was used.
1245 for (const auto& profile : server_profiles_) {
1246 if (imported_profile.IsSubsetOf(*profile, app_locale_)) {
1247 RecordUseOf(*profile);
1248 return profile->guid();
1249 }
1250 }
1251
1252 std::vector<AutofillProfile> profiles; 1232 std::vector<AutofillProfile> profiles;
1253 std::string guid = 1233 std::string guid =
1254 MergeProfile(imported_profile, &web_profiles_, app_locale_, &profiles); 1234 MergeProfile(imported_profile, &web_profiles_, app_locale_, &profiles);
1255 SetProfiles(&profiles); 1235 SetProfiles(&profiles);
1256 return guid; 1236 return guid;
1257 } 1237 }
1258 1238
1259 void PersonalDataManager::NotifyPersonalDataChanged() { 1239 void PersonalDataManager::NotifyPersonalDataChanged() {
1260 for (PersonalDataManagerObserver& observer : observers_) 1240 for (PersonalDataManagerObserver& observer : observers_)
1261 observer.OnPersonalDataChanged(); 1241 observer.OnPersonalDataChanged();
1242
1243 // If new data was synced, try to convert new server profiles.
1244 if (has_synced_new_data) {
1245 has_synced_new_data = false;
1246 ConvertWalletAddressesToLocalProfiles();
1247 }
1262 } 1248 }
1263 1249
1264 std::string PersonalDataManager::SaveImportedCreditCard( 1250 std::string PersonalDataManager::SaveImportedCreditCard(
1265 const CreditCard& imported_card) { 1251 const CreditCard& imported_card) {
1266 DCHECK(!imported_card.number().empty()); 1252 DCHECK(!imported_card.number().empty());
1267 if (is_off_the_record_) 1253 if (is_off_the_record_)
1268 return std::string(); 1254 return std::string();
1269 1255
1270 // Set to true if |imported_card| is merged into the credit card list. 1256 // Set to true if |imported_card| is merged into the credit card list.
1271 bool merged = false; 1257 bool merged = false;
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
1569 1555
1570 imported_credit_card->reset(new CreditCard(candidate_credit_card)); 1556 imported_credit_card->reset(new CreditCard(candidate_credit_card));
1571 return true; 1557 return true;
1572 } 1558 }
1573 1559
1574 const std::vector<AutofillProfile*>& PersonalDataManager::GetProfiles( 1560 const std::vector<AutofillProfile*>& PersonalDataManager::GetProfiles(
1575 bool record_metrics) const { 1561 bool record_metrics) const {
1576 profiles_.clear(); 1562 profiles_.clear();
1577 for (const auto& profile : web_profiles_) 1563 for (const auto& profile : web_profiles_)
1578 profiles_.push_back(profile.get()); 1564 profiles_.push_back(profile.get());
1579 if (pref_service_->GetBoolean(prefs::kAutofillWalletImportEnabled)) {
1580 for (const auto& profile : server_profiles_)
1581 profiles_.push_back(profile.get());
1582 }
1583 return profiles_; 1565 return profiles_;
1584 } 1566 }
1585 1567
1586 std::vector<Suggestion> PersonalDataManager::GetSuggestionsForCards( 1568 std::vector<Suggestion> PersonalDataManager::GetSuggestionsForCards(
1587 const AutofillType& type, 1569 const AutofillType& type,
1588 const base::string16& field_contents, 1570 const base::string16& field_contents,
1589 const std::vector<CreditCard*>& cards_to_suggest) const { 1571 const std::vector<CreditCard*>& cards_to_suggest) const {
1590 std::vector<Suggestion> suggestions; 1572 std::vector<Suggestion> suggestions;
1591 base::string16 field_contents_lower = base::i18n::ToLower(field_contents); 1573 base::string16 field_contents_lower = base::i18n::ToLower(field_contents);
1592 for (const CreditCard* credit_card : cards_to_suggest) { 1574 for (const CreditCard* credit_card : cards_to_suggest) {
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
1850 // If the card was modified, apply the changes to the database. 1832 // If the card was modified, apply the changes to the database.
1851 if (was_modified) { 1833 if (was_modified) {
1852 if (credit_card->record_type() == CreditCard::LOCAL_CARD) 1834 if (credit_card->record_type() == CreditCard::LOCAL_CARD)
1853 database_->UpdateCreditCard(*credit_card); 1835 database_->UpdateCreditCard(*credit_card);
1854 else 1836 else
1855 database_->UpdateServerCardMetadata(*credit_card); 1837 database_->UpdateServerCardMetadata(*credit_card);
1856 } 1838 }
1857 } 1839 }
1858 } 1840 }
1859 1841
1842 void PersonalDataManager::ConvertWalletAddressesToLocalProfiles() {
1843 // Copy the local profiles into a vector<AutofillProfile>. Theses are the
1844 // existing profiles. Get them sorted in decreasing order of frecency, so the
1845 // "best" profiles are checked first. Put the verified profiles last so the
1846 // server addresses have a chance to merge into the non-verified local
1847 // profiles.
1848 std::vector<AutofillProfile> local_profiles;
1849 for (AutofillProfile* existing_profile : GetProfilesToSuggest()) {
1850 local_profiles.push_back(*existing_profile);
1851 }
1852
1853 // Create the map used to update credit card's billing addresses after the
1854 // convertion/merge.
1855 std::unordered_map<std::string, std::string> guids_merge_map;
1856
1857 bool has_converted_addresses = false;
1858 for (std::unique_ptr<AutofillProfile>& wallet_address : server_profiles_) {
1859 // If the address has not been converted yet, convert it.
1860 if (!wallet_address->has_converted()) {
1861 // Try to merge the server address into a similar local profile, or create
1862 // a new local profile if no similar profile is found.
1863 std::string address_guid =
1864 MergeServerAddressesIntoProfiles(*wallet_address, &local_profiles);
1865
1866 // Update the map to transfer the billing address relationship from the
1867 // server address to the converted/merged local profile.
1868 guids_merge_map.insert(std::pair<std::string, std::string>(
1869 wallet_address->server_id(), address_guid));
1870
1871 // Update the wallet addresses metadata to record the conversion.
1872 wallet_address->set_has_converted(true);
1873 database_->UpdateServerAddressMetadata(*wallet_address);
1874
1875 has_converted_addresses = true;
1876 }
1877 }
1878
1879 if (has_converted_addresses) {
1880 // Save the local profiles to the DB.
1881 SetProfiles(&local_profiles);
1882
1883 // Update the credit cards billing address relationship.
1884 UpdateCardsBillingAddressReference(guids_merge_map);
1885
1886 // Force a reload of the profiles and cards.
1887 Refresh();
1888 }
1889 }
1890
1891 // TODO(crbug.com/687975): Reuse MergeProfiles in this function.
1892 std::string PersonalDataManager::MergeServerAddressesIntoProfiles(
1893 const AutofillProfile& server_address,
1894 std::vector<AutofillProfile>* existing_profiles) {
1895 // Set to true if |existing_profiles| already contains an equivalent profile.
1896 bool matching_profile_found = false;
1897 std::string guid = server_address.guid();
1898
1899 // If there is already a local profile that is very similar, merge in any
1900 // missing values. Only merge with the first match.
1901 AutofillProfileComparator comparator(app_locale_);
1902 for (auto& local_profile : *existing_profiles) {
1903 if (!matching_profile_found &&
1904 comparator.AreMergeable(server_address, local_profile) &&
1905 local_profile.SaveAdditionalInfo(server_address, app_locale_)) {
1906 matching_profile_found = true;
1907 local_profile.set_modification_date(AutofillClock::Now());
1908 guid = local_profile.guid();
1909 AutofillMetrics::LogWalletAddressConversionType(
1910 AutofillMetrics::CONVERTED_ADDRESS_MERGED);
1911 }
1912 }
1913
1914 // If the server address was not merged with a local profile, add it to the
1915 // list.
1916 if (!matching_profile_found) {
1917 existing_profiles->push_back(server_address);
1918 // Set the profile as being local.
1919 existing_profiles->back().set_record_type(AutofillProfile::LOCAL_PROFILE);
1920 existing_profiles->back().set_modification_date(AutofillClock::Now());
1921 AutofillMetrics::LogWalletAddressConversionType(
1922 AutofillMetrics::CONVERTED_ADDRESS_ADDED);
1923 }
1924
1925 return guid;
1926 }
1927
1860 } // namespace autofill 1928 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698