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

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

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

Powered by Google App Engine
This is Rietveld 408576698