Index: chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java |
index 8f050bfe2ae427b1de2c2dd77aaf1c11a37d72bf..f7c6cbcc4dd2f0c7d161d28888e2cad4e1e0da1e 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java |
@@ -363,11 +363,12 @@ public class PaymentRequestImpl |
} |
if (requestShipping) { |
- createShippingSection(profiles); |
+ createShippingSection(Collections.unmodifiableList(profiles)); |
} |
if (requestPayerName || requestPayerPhone || requestPayerEmail) { |
- createContactSection(profiles, requestPayerName, requestPayerPhone, requestPayerEmail); |
+ createContactSection(Collections.unmodifiableList(profiles), requestPayerName, |
+ requestPayerPhone, requestPayerEmail); |
} |
mUI = new PaymentRequestUI(mContext, this, requestShipping, |
@@ -391,11 +392,11 @@ public class PaymentRequestImpl |
requestPayerPhone, requestShipping, requestPayerName); |
} |
- private void createShippingSection(List<AutofillProfile> profiles) { |
+ private void createShippingSection(List<AutofillProfile> unmodifiableProfiles) { |
List<AutofillAddress> addresses = new ArrayList<>(); |
- for (int i = 0; i < profiles.size(); i++) { |
- AutofillProfile profile = profiles.get(i); |
+ for (int i = 0; i < unmodifiableProfiles.size(); i++) { |
+ AutofillProfile profile = unmodifiableProfiles.get(i); |
mAddressEditor.addPhoneNumberIfValid(profile.getPhoneNumber()); |
// Only suggest addresses that have a street address. |
@@ -440,14 +441,16 @@ public class PaymentRequestImpl |
PaymentRequestUI.TYPE_SHIPPING_ADDRESSES, firstCompleteAddressIndex, addresses); |
} |
- private void createContactSection(List<AutofillProfile> profiles, boolean requestName, |
- boolean requestPhone, boolean requestEmail) { |
- Set<String> uniqueContactInfos = new HashSet<>(); |
- mContactEditor = new ContactEditor(requestName, requestPhone, requestEmail); |
+ private void createContactSection(List<AutofillProfile> unmodifiableProfiles, |
+ boolean requestName, boolean requestPhone, boolean requestEmail) { |
List<AutofillContact> contacts = new ArrayList<>(); |
+ List<AutofillContact> uniqueContacts = new ArrayList<>(); |
+ mContactEditor = new ContactEditor(requestName, requestPhone, requestEmail); |
- for (int i = 0; i < profiles.size(); i++) { |
- AutofillProfile profile = profiles.get(i); |
+ // Add the profile's valid request values to the editor's autocomplete list and convert |
+ // relevant profiles to AutofillContacts. |
+ for (int i = 0; i < unmodifiableProfiles.size(); ++i) { |
+ AutofillProfile profile = unmodifiableProfiles.get(i); |
String name = requestName && !TextUtils.isEmpty(profile.getFullName()) |
? profile.getFullName() |
: null; |
@@ -457,44 +460,62 @@ public class PaymentRequestImpl |
String email = requestEmail && !TextUtils.isEmpty(profile.getEmailAddress()) |
? profile.getEmailAddress() |
: null; |
+ |
+ // Add the values to the editor's autocomplete list. |
mContactEditor.addPayerNameIfValid(name); |
mContactEditor.addPhoneNumberIfValid(phone); |
mContactEditor.addEmailAddressIfValid(email); |
+ // Only create a contact if the profile has relevant information for the merchant. |
if (name != null || phone != null || email != null) { |
- // Different profiles can have identical contact info. Do not add the same |
- // contact info to the list twice. |
- String uniqueContactInfo = name + phone + email; |
- if (!uniqueContactInfos.contains(uniqueContactInfo)) { |
- uniqueContactInfos.add(uniqueContactInfo); |
- |
- @ContactEditor.CompletionStatus |
- int completionStatus = |
- mContactEditor.checkContactCompletionStatus(name, phone, email); |
- contacts.add(new AutofillContact( |
- mContext, profile, name, phone, email, completionStatus)); |
- } |
+ contacts.add(new AutofillContact(mContext, profile, name, phone, email, |
+ mContactEditor.checkContactCompletionStatus(name, phone, email), |
+ requestName, requestPhone, requestEmail)); |
} |
} |
- // Suggest complete contact infos first. |
- Collections.sort(contacts, COMPLETENESS_COMPARATOR); |
+ // Order the contacts so the ones that have most of the required information are put first. |
+ // The sort is stable, so contacts with the same relevance score are sorted by frecency. |
+ Collections.sort(contacts, new Comparator<AutofillContact>() { |
+ @Override |
+ public int compare(AutofillContact a, AutofillContact b) { |
+ return b.getRelevanceScore() - a.getRelevanceScore(); |
+ } |
+ }); |
+ |
+ // This algorithm is quadratic, but since the number of contacts is generally very small |
+ // ( < 10) a faster but more complicated algorithm would be overkill. |
+ for (int i = 0; i < contacts.size(); i++) { |
+ AutofillContact contact = contacts.get(i); |
+ |
+ // Different contacts can have identical info. Do not add the same contact info or a |
+ // subset of it twice. It's important that the profiles be sorted by the quantity of |
+ // required info they have. |
+ boolean isNewSuggestion = true; |
+ for (int j = 0; j < uniqueContacts.size(); ++j) { |
+ if (uniqueContacts.get(j).isEqualOrSupersetOf(contact)) { |
+ isNewSuggestion = false; |
+ break; |
+ } |
+ } |
+ if (isNewSuggestion) uniqueContacts.add(contact); |
- // Limit the number of suggestions. |
- contacts = contacts.subList(0, Math.min(contacts.size(), SUGGESTIONS_LIMIT)); |
+ // Limit the number of suggestions. |
+ if (uniqueContacts.size() == SUGGESTIONS_LIMIT) break; |
+ } |
// Log the number of suggested contact infos. |
mJourneyLogger.setNumberOfSuggestionsShown( |
- PaymentRequestJourneyLogger.SECTION_CONTACT_INFO, contacts.size()); |
+ PaymentRequestJourneyLogger.SECTION_CONTACT_INFO, uniqueContacts.size()); |
// Automatically select the first address if it is complete. |
int firstCompleteContactIndex = SectionInformation.NO_SELECTION; |
- if (!contacts.isEmpty() && contacts.get(0).isComplete()) { |
+ if (!uniqueContacts.isEmpty() && uniqueContacts.get(0).isComplete()) { |
firstCompleteContactIndex = 0; |
} |
mContactSection = new SectionInformation( |
- PaymentRequestUI.TYPE_CONTACT_DETAILS, firstCompleteContactIndex, contacts); |
+ PaymentRequestUI.TYPE_CONTACT_DETAILS, firstCompleteContactIndex, uniqueContacts); |
} |
/** |