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

Unified Diff: components/autofill/core/browser/autofill_profile_comparator.cc

Issue 2493253002: [autofill] Add address comparison/merge logic for dependent locality and sorting codes (Closed)
Patch Set: fix try bots (redux) Created 4 years, 1 month 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/autofill_profile_comparator.cc
diff --git a/components/autofill/core/browser/autofill_profile_comparator.cc b/components/autofill/core/browser/autofill_profile_comparator.cc
index cfbd6a1008b87a0c6f8641f6a99544bed064ab5a..c3e8709549b5c35931ddfb481c676167c9812f76 100644
--- a/components/autofill/core/browser/autofill_profile_comparator.cc
+++ b/components/autofill/core/browser/autofill_profile_comparator.cc
@@ -316,7 +316,7 @@ bool AutofillProfileComparator::MergeCompanyNames(
switch (result) {
case DIFFERENT_TOKENS:
default:
- NOTREACHED();
+ NOTREACHED() << "Unexpected mismatch: '" << c1 << "' vs '" << c2 << "'";
return false;
case S1_CONTAINS_S2:
best = &c1;
@@ -501,13 +501,72 @@ bool AutofillProfileComparator::MergeAddresses(const AutofillProfile& p1,
break;
case DIFFERENT_TOKENS:
default:
- // The addresses aren't mergeable and we shouldn't be doing any of
+ // The cities aren't mergeable and we shouldn't be doing any of
// this.
- NOTREACHED();
+ NOTREACHED() << "Unexpected mismatch: '" << city1 << "' vs '" << city2
+ << "'";
return false;
}
}
+ // One of the dependend localities is empty or one of the localities has a
+ // subset of tokens from the other. Pick the locality name with more tokens;
+ // this is usually the most explicit one.
+ const AutofillType kDependentLocality(ADDRESS_HOME_DEPENDENT_LOCALITY);
+ const base::string16& locality1 = p1.GetInfo(kDependentLocality, app_locale_);
+ const base::string16& locality2 = p2.GetInfo(kDependentLocality, app_locale_);
+ if (locality1.empty()) {
+ address->SetInfo(kDependentLocality, locality2, app_locale_);
+ } else if (locality2.empty()) {
+ address->SetInfo(kDependentLocality, locality1, app_locale_);
+ } else {
+ // Prefer the one with more tokens, making sure to apply address
+ // normalization and rewriting before doing the comparison.
+ CompareTokensResult result =
+ CompareTokens(rewriter.Rewrite(NormalizeForComparison(locality1)),
+ rewriter.Rewrite(NormalizeForComparison(locality2)));
+ switch (result) {
+ case SAME_TOKENS:
+ // They have the same set of unique tokens. Let's pick the more recently
+ // used one.
+ address->SetInfo(
+ kDependentLocality,
+ (p2.use_date() > p1.use_date() ? locality2 : locality1),
+ app_locale_);
+ break;
+ case S1_CONTAINS_S2:
+ // locality1 has more unique tokens than locality2.
+ address->SetInfo(kDependentLocality, locality1, app_locale_);
+ break;
+ case S2_CONTAINS_S1:
+ // locality2 has more unique tokens than locality1.
+ address->SetInfo(kDependentLocality, locality2, app_locale_);
+ break;
+ case DIFFERENT_TOKENS:
+ default:
+ // The localities aren't mergeable and we shouldn't be doing any of
+ // this.
+ NOTREACHED() << "Unexpected mismatch: '" << locality1 << "' vs '"
+ << locality2 << "'";
+ return false;
+ }
+ }
+
+ // One of the sorting codes is empty, they are the same, or one is a substring
+ // of the other. We prefer the most recently used sorting code.
+ const AutofillType kSortingCode(ADDRESS_HOME_SORTING_CODE);
+ const base::string16& sorting1 = p1.GetInfo(kSortingCode, app_locale_);
+ const base::string16& sorting2 = p2.GetInfo(kSortingCode, app_locale_);
+ if (sorting1.empty()) {
+ address->SetInfo(kSortingCode, sorting2, app_locale_);
+ } else if (sorting2.empty()) {
+ address->SetInfo(kSortingCode, sorting1, app_locale_);
+ } else {
+ address->SetInfo(kSortingCode,
+ (p2.use_date() > p1.use_date() ? sorting2 : sorting1),
+ app_locale_);
+ }
+
// One of the addresses is empty or one of the addresses has a subset of
// tokens from the other. Prefer the more verbosely expressed one.
const AutofillType kStreetAddress(ADDRESS_HOME_STREET_ADDRESS);
@@ -548,13 +607,14 @@ bool AutofillProfileComparator::MergeAddresses(const AutofillProfile& p1,
break;
case S2_CONTAINS_S1:
// address2 has more unique tokens than address1.
- address->SetInfo(kStreetAddress, address1, app_locale_);
+ address->SetInfo(kStreetAddress, address2, app_locale_);
Roger McFarlane (Chromium) 2016/11/21 18:39:51 Latent copy-paste bug. Should have been address2 h
sebsg 2016/11/21 18:48:44 Good catch :)
break;
case DIFFERENT_TOKENS:
default:
// The addresses aren't mergeable and we shouldn't be doing any of
// this.
- NOTREACHED();
+ NOTREACHED() << "Unexpected mismatch: '" << address1 << "' vs '"
+ << address2 << "'";
return false;
}
}
@@ -771,17 +831,17 @@ bool AutofillProfileComparator::HaveMergeablePhoneNumbers(
// Parse and compare the phone numbers.
PhoneNumberUtil* phone_util = PhoneNumberUtil::GetInstance();
switch (phone_util->IsNumberMatchWithTwoStrings(phone_1, phone_2)) {
- case PhoneNumberUtil::INVALID_NUMBER:
- case PhoneNumberUtil::NO_MATCH:
- return false;
case PhoneNumberUtil::SHORT_NSN_MATCH:
case PhoneNumberUtil::NSN_MATCH:
case PhoneNumberUtil::EXACT_MATCH:
return true;
+ case PhoneNumberUtil::INVALID_NUMBER:
+ case PhoneNumberUtil::NO_MATCH:
+ return false;
+ default:
+ NOTREACHED();
+ return false;
}
-
- NOTREACHED();
- return false;
}
bool AutofillProfileComparator::HaveMergeableAddresses(
@@ -797,10 +857,6 @@ bool AutofillProfileComparator::HaveMergeableAddresses(
return false;
}
- // TODO(rogerm): Lookup the normalization rules for the (common) country of
- // the address. The rules should be applied post NormalizeForComparison to
- // the state, city, and address bag of words comparisons.
-
// Zip
// ----
// If the addresses are definitely not in the same zip/area code then we're
@@ -816,6 +872,8 @@ bool AutofillProfileComparator::HaveMergeableAddresses(
return false;
}
+ // Use the token rewrite rules for the (common) country of the address to
+ // transform equivalent substrings to a representative token for comparison.
AddressRewriter rewriter =
AddressRewriter::ForCountryCode(country1.empty() ? country2 : country1);
@@ -845,14 +903,44 @@ bool AutofillProfileComparator::HaveMergeableAddresses(
// TODO(rogerm): If the match is between non-empty zip codes then we can infer
// that the two city strings are intended to have the same meaning. This
// handles the cases where we have a city vs one of its suburbs.
- const base::string16& city1 = rewriter.Rewrite(NormalizeForComparison(
- p1.GetInfo(AutofillType(ADDRESS_HOME_CITY), app_locale_)));
- const base::string16& city2 = rewriter.Rewrite(NormalizeForComparison(
- p2.GetInfo(AutofillType(ADDRESS_HOME_CITY), app_locale_)));
+ const AutofillType kCity(ADDRESS_HOME_CITY);
+ const base::string16& city1 =
+ rewriter.Rewrite(NormalizeForComparison(p1.GetInfo(kCity, app_locale_)));
+ const base::string16& city2 =
+ rewriter.Rewrite(NormalizeForComparison(p2.GetInfo(kCity, app_locale_)));
if (CompareTokens(city1, city2) == DIFFERENT_TOKENS) {
return false;
}
+ // Dependent Locality
+ // -------------------
+ // Heuristic: Dependent Localities are mergeable if one is a (possibly empty)
+ // bag of words subset of the other.
+ const AutofillType kDependentLocality(ADDRESS_HOME_DEPENDENT_LOCALITY);
+ const base::string16& locality1 = rewriter.Rewrite(
+ NormalizeForComparison(p1.GetInfo(kDependentLocality, app_locale_)));
+ const base::string16& locality2 = rewriter.Rewrite(
+ NormalizeForComparison(p2.GetInfo(kDependentLocality, app_locale_)));
+ if (CompareTokens(locality1, locality2) == DIFFERENT_TOKENS) {
+ return false;
+ }
+
+ // Sorting Code
+ // -------------
+ // Heuristic: Sorting codes are mergeable if one is empty or one is a
+ // substring of the other, post normalization and whitespace removed. This
+ // is similar to postal/zip codes.
+ const AutofillType kSortingCode(ADDRESS_HOME_SORTING_CODE);
+ const base::string16& sorting1 = NormalizeForComparison(
+ p1.GetInfo(kSortingCode, app_locale_), DISCARD_WHITESPACE);
+ const base::string16& sorting2 = NormalizeForComparison(
+ p2.GetInfo(kSortingCode, app_locale_), DISCARD_WHITESPACE);
+ if (!sorting1.empty() && !sorting2.empty() &&
+ sorting1.find(sorting2) == base::string16::npos &&
+ sorting2.find(sorting1) == base::string16::npos) {
+ return false;
+ }
+
// Address
// --------
// Heuristic: Street addresses are mergeable if one is a (possibly empty) bag

Powered by Google App Engine
This is Rietveld 408576698