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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: components/autofill/core/browser/personal_data_manager.cc
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc
index dad0d3890f6d7ace1e82c42b2eaf4faf6ff815c1..eec7b345424ccbaf6aaa8412bbe25bd91561ba44 100644
--- a/components/autofill/core/browser/personal_data_manager.cc
+++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -373,21 +373,6 @@ void PersonalDataManager::OnWebDataServiceRequestDone(
} else {
ReceiveLoadedDbValues(h, result.get(), &pending_server_profiles_query_,
&server_profiles_);
-
- if (!server_profiles_.empty()) {
- std::string account_id = signin_manager_->GetAuthenticatedAccountId();
- base::string16 email =
- base::UTF8ToUTF16(
- account_tracker_->GetAccountInfo(account_id).email);
-
- // User may have signed out during the fulfillment of the web data
- // request, in which case there is no point updating
- // |server_profiles_| as it will be cleared.
- if (!email.empty()) {
- for (auto& profile : server_profiles_)
- profile->SetRawInfo(EMAIL_ADDRESS, email);
- }
- }
}
break;
case AUTOFILL_CREDITCARDS_RESULT:
@@ -423,6 +408,7 @@ void PersonalDataManager::OnWebDataServiceRequestDone(
}
void PersonalDataManager::AutofillMultipleChanged() {
+ has_synced_new_data_ = true;
Refresh();
}
@@ -752,6 +738,13 @@ std::vector<AutofillProfile*> PersonalDataManager::web_profiles() const {
return result;
}
+std::vector<AutofillProfile*> PersonalDataManager::GetServerProfiles() const {
+ std::vector<AutofillProfile*> result;
+ for (const auto& profile : server_profiles_)
+ result.push_back(profile.get());
+ return result;
+}
+
std::vector<CreditCard*> PersonalDataManager::GetLocalCreditCards() const {
std::vector<CreditCard*> result;
for (const auto& card : local_credit_cards_)
@@ -770,10 +763,6 @@ const std::vector<CreditCard*>& PersonalDataManager::GetCreditCards() const {
return credit_cards_;
}
-bool PersonalDataManager::HasServerData() const {
- return !server_credit_cards_.empty() || !server_profiles_.empty();
-}
-
void PersonalDataManager::Refresh() {
LoadProfiles();
LoadCreditCards();
@@ -1239,15 +1228,6 @@ std::string PersonalDataManager::SaveImportedProfile(
if (is_off_the_record_)
return std::string();
- // Don't save a web profile if the data in the profile is a subset of a
- // server profile, but do record the fact that it was used.
- for (const auto& profile : server_profiles_) {
- if (imported_profile.IsSubsetOf(*profile, app_locale_)) {
- RecordUseOf(*profile);
- return profile->guid();
- }
- }
-
std::vector<AutofillProfile> profiles;
std::string guid =
MergeProfile(imported_profile, &web_profiles_, app_locale_, &profiles);
@@ -1258,6 +1238,12 @@ std::string PersonalDataManager::SaveImportedProfile(
void PersonalDataManager::NotifyPersonalDataChanged() {
for (PersonalDataManagerObserver& observer : observers_)
observer.OnPersonalDataChanged();
+
+ // If new data was synced, try to convert new server profiles.
+ if (has_synced_new_data_) {
+ has_synced_new_data_ = false;
+ ConvertWalletAddressesToLocalProfiles();
+ }
}
std::string PersonalDataManager::SaveImportedCreditCard(
@@ -1575,10 +1561,6 @@ const std::vector<AutofillProfile*>& PersonalDataManager::GetProfiles(
profiles_.clear();
for (const auto& profile : web_profiles_)
profiles_.push_back(profile.get());
- if (pref_service_->GetBoolean(prefs::kAutofillWalletImportEnabled)) {
- for (const auto& profile : server_profiles_)
- profiles_.push_back(profile.get());
- }
return profiles_;
}
@@ -1855,4 +1837,90 @@ void PersonalDataManager::UpdateCardsBillingAddressReference(
}
}
+void PersonalDataManager::ConvertWalletAddressesToLocalProfiles() {
+ // Copy the local profiles into a vector<AutofillProfile>. Theses are the
+ // existing profiles. Get them sorted in decreasing order of frecency, so the
+ // "best" profiles are checked first. Put the verified profiles last so the
+ // server addresses have a chance to merge into the non-verified local
+ // profiles.
+ std::vector<AutofillProfile> local_profiles;
+ for (AutofillProfile* existing_profile : GetProfilesToSuggest()) {
+ local_profiles.push_back(*existing_profile);
+ }
+
+ // Create the map used to update credit card's billing addresses after the
+ // convertion/merge.
+ std::unordered_map<std::string, std::string> guids_merge_map;
+
+ bool has_converted_addresses = false;
+ for (std::unique_ptr<AutofillProfile>& wallet_address : server_profiles_) {
+ // If the address has not been converted yet, convert it.
+ if (!wallet_address->has_converted()) {
+ // Try to merge the server address into a similar local profile, or create
+ // a new local profile if no similar profile is found.
+ std::string address_guid =
+ MergeServerAddressesIntoProfiles(*wallet_address, &local_profiles);
+
+ // Update the map to transfer the billing address relationship from the
+ // server address to the converted/merged local profile.
+ guids_merge_map.insert(std::pair<std::string, std::string>(
+ wallet_address->server_id(), address_guid));
+
+ // Update the wallet addresses metadata to record the conversion.
+ wallet_address->set_has_converted(true);
+ database_->UpdateServerAddressMetadata(*wallet_address);
+
+ has_converted_addresses = true;
+ }
+ }
+
+ if (has_converted_addresses) {
+ // Save the local profiles to the DB.
+ SetProfiles(&local_profiles);
+
+ // Update the credit cards billing address relationship.
+ UpdateCardsBillingAddressReference(guids_merge_map);
+
+ // Force a reload of the profiles and cards.
+ Refresh();
+ }
+}
+
+// TODO(crbug.com/687975): Reuse MergeProfiles in this function.
+std::string PersonalDataManager::MergeServerAddressesIntoProfiles(
+ const AutofillProfile& server_address,
+ std::vector<AutofillProfile>* existing_profiles) {
+ // Set to true if |existing_profiles| already contains an equivalent profile.
+ bool matching_profile_found = false;
+ std::string guid = server_address.guid();
+
+ // If there is already a local profile that is very similar, merge in any
+ // missing values. Only merge with the first match.
+ AutofillProfileComparator comparator(app_locale_);
+ for (auto& local_profile : *existing_profiles) {
+ if (!matching_profile_found &&
+ comparator.AreMergeable(server_address, local_profile) &&
+ local_profile.SaveAdditionalInfo(server_address, app_locale_)) {
+ matching_profile_found = true;
+ local_profile.set_modification_date(AutofillClock::Now());
+ guid = local_profile.guid();
+ AutofillMetrics::LogWalletAddressConversionType(
+ AutofillMetrics::CONVERTED_ADDRESS_MERGED);
+ }
+ }
+
+ // If the server address was not merged with a local profile, add it to the
+ // list.
+ if (!matching_profile_found) {
+ existing_profiles->push_back(server_address);
+ // Set the profile as being local.
+ existing_profiles->back().set_record_type(AutofillProfile::LOCAL_PROFILE);
+ existing_profiles->back().set_modification_date(AutofillClock::Now());
+ AutofillMetrics::LogWalletAddressConversionType(
+ AutofillMetrics::CONVERTED_ADDRESS_ADDED);
+ }
+
+ return guid;
+}
+
} // namespace autofill

Powered by Google App Engine
This is Rietveld 408576698