Commit ed56d990 authored by sandromaggi's avatar sandromaggi Committed by Commit Bot

[Autofill Assistant] Split profiles into usage cases.

Previously the source for contacts and shipping addresses was the same
sorted list of profiles. There may be cases where we want to sort them
differently, which is enabled by splitting the list in two.
On view we transform the profiles into either Contacts or Addresses.

Note: This change breaks the default selection based on the account's
address. This is moved to native in crrev/c/1954393 and has not been
recreated here.

Bug: b/144005336
Change-Id: I1e8e085f1de2fc7710969e778078495b3b54704b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1961197
Commit-Queue: Sandro Maggi <sandromaggi@google.com>
Reviewed-by: default avatarClemens Arbesser <arbesser@google.com>
Cr-Commit-Position: refs/heads/master@{#726331}
parent ab02ae58
...@@ -5,15 +5,11 @@ ...@@ -5,15 +5,11 @@
package org.chromium.chrome.browser.autofill_assistant.user_data; package org.chromium.chrome.browser.autofill_assistant.user_data;
import android.app.Activity; import android.app.Activity;
import android.content.Context;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.annotation.Nullable;
import org.chromium.base.task.PostTask; import org.chromium.base.task.PostTask;
import org.chromium.chrome.browser.ChromeVersionInfo; import org.chromium.chrome.browser.ChromeVersionInfo;
import org.chromium.chrome.browser.autofill.PersonalDataManager;
import org.chromium.chrome.browser.autofill_assistant.user_data.additional_sections.AssistantAdditionalSectionContainer; import org.chromium.chrome.browser.autofill_assistant.user_data.additional_sections.AssistantAdditionalSectionContainer;
import org.chromium.chrome.browser.payments.AddressEditor; import org.chromium.chrome.browser.payments.AddressEditor;
import org.chromium.chrome.browser.payments.AutofillAddress; import org.chromium.chrome.browser.payments.AutofillAddress;
...@@ -93,10 +89,6 @@ class AssistantCollectUserDataBinder ...@@ -93,10 +89,6 @@ class AssistantCollectUserDataBinder
mDividerTag = dividerTag; mDividerTag = dividerTag;
mActivity = activity; mActivity = activity;
} }
public Context getContext() {
return mActivity;
}
} }
@Override @Override
...@@ -215,38 +207,35 @@ class AssistantCollectUserDataBinder ...@@ -215,38 +207,35 @@ class AssistantCollectUserDataBinder
*/ */
private boolean updateSectionContents( private boolean updateSectionContents(
AssistantCollectUserDataModel model, PropertyKey propertyKey, ViewHolder view) { AssistantCollectUserDataModel model, PropertyKey propertyKey, ViewHolder view) {
if (propertyKey == AssistantCollectUserDataModel.AVAILABLE_AUTOFILL_PAYMENT_METHODS if (propertyKey == AssistantCollectUserDataModel.AVAILABLE_PAYMENT_INSTRUMENTS
|| propertyKey == AssistantCollectUserDataModel.WEB_CONTENTS) { || propertyKey == AssistantCollectUserDataModel.WEB_CONTENTS) {
WebContents webContents = model.get(AssistantCollectUserDataModel.WEB_CONTENTS); if (model.get(AssistantCollectUserDataModel.REQUEST_PAYMENT)) {
List<AssistantCollectUserDataModel.PaymentTuple> paymentTuples = List<AutofillPaymentInstrument> paymentInstruments;
model.get(AssistantCollectUserDataModel.AVAILABLE_AUTOFILL_PAYMENT_METHODS); if (model.get(AssistantCollectUserDataModel.WEB_CONTENTS) == null) {
paymentInstruments = Collections.emptyList();
List<AutofillPaymentInstrument> availablePaymentMethods;
if (webContents != null && paymentTuples != null) {
availablePaymentMethods =
getPaymentInstrumentsFromPaymentTuples(webContents, paymentTuples);
} else { } else {
availablePaymentMethods = Collections.emptyList(); paymentInstruments =
model.get(AssistantCollectUserDataModel.AVAILABLE_PAYMENT_INSTRUMENTS);
} }
view.mPaymentMethodSection.onAvailablePaymentMethodsChanged(availablePaymentMethods); view.mPaymentMethodSection.onAvailablePaymentMethodsChanged(paymentInstruments);
return true;
} else if (propertyKey == AssistantCollectUserDataModel.AVAILABLE_PROFILES) {
List<PersonalDataManager.AutofillProfile> autofillProfiles =
model.get(AssistantCollectUserDataModel.AVAILABLE_PROFILES);
if (autofillProfiles == null) {
autofillProfiles = Collections.emptyList();
} }
return true;
} else if (propertyKey == AssistantCollectUserDataModel.AVAILABLE_CONTACTS) {
if (shouldShowContactDetails(model)) { if (shouldShowContactDetails(model)) {
view.mContactDetailsSection.onProfilesChanged(autofillProfiles, view.mContactDetailsSection.onContactsChanged(
model.get(AssistantCollectUserDataModel.REQUEST_EMAIL), model.get(AssistantCollectUserDataModel.AVAILABLE_CONTACTS));
model.get(AssistantCollectUserDataModel.REQUEST_NAME),
model.get(AssistantCollectUserDataModel.REQUEST_PHONE));
}
if (model.get(AssistantCollectUserDataModel.REQUEST_PAYMENT)) {
view.mPaymentMethodSection.onProfilesChanged(autofillProfiles);
} }
return true;
} else if (propertyKey == AssistantCollectUserDataModel.AVAILABLE_SHIPPING_ADDRESSES) {
if (model.get(AssistantCollectUserDataModel.REQUEST_SHIPPING_ADDRESS)) { if (model.get(AssistantCollectUserDataModel.REQUEST_SHIPPING_ADDRESS)) {
view.mShippingAddressSection.onProfilesChanged(autofillProfiles); view.mShippingAddressSection.onAddressesChanged(
model.get(AssistantCollectUserDataModel.AVAILABLE_SHIPPING_ADDRESSES));
}
return true;
} else if (propertyKey == AssistantCollectUserDataModel.AVAILABLE_BILLING_ADDRESSES) {
if (model.get(AssistantCollectUserDataModel.REQUEST_PAYMENT)) {
view.mPaymentMethodSection.onAddressesChanged(
model.get(AssistantCollectUserDataModel.AVAILABLE_BILLING_ADDRESSES));
} }
return true; return true;
} else if (propertyKey == AssistantCollectUserDataModel.REQUIRE_BILLING_POSTAL_CODE } else if (propertyKey == AssistantCollectUserDataModel.REQUIRE_BILLING_POSTAL_CODE
...@@ -372,10 +361,10 @@ class AssistantCollectUserDataBinder ...@@ -372,10 +361,10 @@ class AssistantCollectUserDataBinder
*/ */
private boolean updateSectionSelectedItem( private boolean updateSectionSelectedItem(
AssistantCollectUserDataModel model, PropertyKey propertyKey, ViewHolder view) { AssistantCollectUserDataModel model, PropertyKey propertyKey, ViewHolder view) {
if (propertyKey == AssistantCollectUserDataModel.SHIPPING_ADDRESS) { if (propertyKey == AssistantCollectUserDataModel.SELECTED_SHIPPING_ADDRESS) {
if (model.get(AssistantCollectUserDataModel.REQUEST_SHIPPING_ADDRESS)) { if (model.get(AssistantCollectUserDataModel.REQUEST_SHIPPING_ADDRESS)) {
AutofillAddress shippingAddress = getAddressFromProfile(view.getContext(), AutofillAddress shippingAddress =
model.get(AssistantCollectUserDataModel.SHIPPING_ADDRESS)); model.get(AssistantCollectUserDataModel.SELECTED_SHIPPING_ADDRESS);
if (shippingAddress != null) { if (shippingAddress != null) {
view.mShippingAddressSection.addOrUpdateItem( view.mShippingAddressSection.addOrUpdateItem(
shippingAddress, /* select= */ true); shippingAddress, /* select= */ true);
...@@ -383,11 +372,10 @@ class AssistantCollectUserDataBinder ...@@ -383,11 +372,10 @@ class AssistantCollectUserDataBinder
// No need to reset selection if null, this will be handled by setItems(). // No need to reset selection if null, this will be handled by setItems().
} }
return true; return true;
} else if (propertyKey == AssistantCollectUserDataModel.PAYMENT_METHOD) { } else if (propertyKey == AssistantCollectUserDataModel.SELECTED_PAYMENT_INSTRUMENT) {
if (model.get(AssistantCollectUserDataModel.REQUEST_PAYMENT)) { if (model.get(AssistantCollectUserDataModel.REQUEST_PAYMENT)) {
AutofillPaymentInstrument paymentInstrument = getPaymentInstrumentFromPaymentTuple( AutofillPaymentInstrument paymentInstrument =
model.get(AssistantCollectUserDataModel.WEB_CONTENTS), model.get(AssistantCollectUserDataModel.SELECTED_PAYMENT_INSTRUMENT);
model.get(AssistantCollectUserDataModel.PAYMENT_METHOD));
if (paymentInstrument != null) { if (paymentInstrument != null) {
view.mPaymentMethodSection.addOrUpdateItem( view.mPaymentMethodSection.addOrUpdateItem(
paymentInstrument, /* select= */ true); paymentInstrument, /* select= */ true);
...@@ -395,13 +383,10 @@ class AssistantCollectUserDataBinder ...@@ -395,13 +383,10 @@ class AssistantCollectUserDataBinder
// No need to reset selection if null, this will be handled by setItems(). // No need to reset selection if null, this will be handled by setItems().
} }
return true; return true;
} else if (propertyKey == AssistantCollectUserDataModel.CONTACT_DETAILS) { } else if (propertyKey == AssistantCollectUserDataModel.SELECTED_CONTACT_DETAILS) {
if (shouldShowContactDetails(model)) { if (shouldShowContactDetails(model)) {
AutofillContact contact = getContactFromProfile(view.getContext(), AutofillContact contact =
model.get(AssistantCollectUserDataModel.CONTACT_DETAILS), model.get(AssistantCollectUserDataModel.SELECTED_CONTACT_DETAILS);
model.get(AssistantCollectUserDataModel.REQUEST_NAME),
model.get(AssistantCollectUserDataModel.REQUEST_PHONE),
model.get(AssistantCollectUserDataModel.REQUEST_EMAIL));
if (contact != null) { if (contact != null) {
view.mContactDetailsSection.addOrUpdateItem(contact, /* select= */ true); view.mContactDetailsSection.addOrUpdateItem(contact, /* select= */ true);
} }
...@@ -612,55 +597,4 @@ class AssistantCollectUserDataBinder ...@@ -612,55 +597,4 @@ class AssistantCollectUserDataBinder
return methodData; return methodData;
} }
private List<AutofillPaymentInstrument> getPaymentInstrumentsFromPaymentTuples(
WebContents webContents,
List<AssistantCollectUserDataModel.PaymentTuple> paymentTuples) {
List<AutofillPaymentInstrument> paymentInstruments = new ArrayList<>(paymentTuples.size());
for (AssistantCollectUserDataModel.PaymentTuple tuple : paymentTuples) {
paymentInstruments.add(new AutofillPaymentInstrument(webContents, tuple.getCreditCard(),
tuple.getBillingAddress(), MethodStrings.BASIC_CARD,
/* matchesMerchantCardTypeExactly= */ true));
}
return paymentInstruments;
}
@Nullable
private AutofillAddress getAddressFromProfile(
Context context, @Nullable PersonalDataManager.AutofillProfile profile) {
if (profile == null) {
return null;
}
return new AutofillAddress(context, profile);
}
@Nullable
private AutofillContact getContactFromProfile(Context context,
@Nullable PersonalDataManager.AutofillProfile profile, boolean requestName,
boolean requestPhone, boolean requestEmail) {
if (profile == null) {
return null;
}
ContactEditor editor = new ContactEditor(requestName, requestPhone, requestEmail, false);
String name = profile.getFullName();
String phone = profile.getPhoneNumber();
String email = profile.getEmailAddress();
return new AutofillContact(context, profile, name, phone, email,
editor.checkContactCompletionStatus(name, phone, email), requestName, requestPhone,
requestEmail);
}
@Nullable
private AutofillPaymentInstrument getPaymentInstrumentFromPaymentTuple(
@Nullable WebContents webContents,
@Nullable AssistantCollectUserDataModel.PaymentTuple paymentTuple) {
if (webContents == null || paymentTuple == null) {
return null;
}
return new AutofillPaymentInstrument(webContents, paymentTuple.getCreditCard(),
paymentTuple.getBillingAddress(), MethodStrings.BASIC_CARD,
/* matchesMerchantCardTypeExactly= */ true);
}
} }
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
package org.chromium.chrome.browser.autofill_assistant.user_data; package org.chromium.chrome.browser.autofill_assistant.user_data;
import android.content.Context;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.view.View; import android.view.View;
import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.CalledByNative;
...@@ -16,11 +18,17 @@ import org.chromium.chrome.browser.autofill_assistant.user_data.additional_secti ...@@ -16,11 +18,17 @@ import org.chromium.chrome.browser.autofill_assistant.user_data.additional_secti
import org.chromium.chrome.browser.autofill_assistant.user_data.additional_sections.AssistantTextInputSection; import org.chromium.chrome.browser.autofill_assistant.user_data.additional_sections.AssistantTextInputSection;
import org.chromium.chrome.browser.autofill_assistant.user_data.additional_sections.AssistantTextInputSection.TextInputFactory; import org.chromium.chrome.browser.autofill_assistant.user_data.additional_sections.AssistantTextInputSection.TextInputFactory;
import org.chromium.chrome.browser.autofill_assistant.user_data.additional_sections.AssistantTextInputType; import org.chromium.chrome.browser.autofill_assistant.user_data.additional_sections.AssistantTextInputType;
import org.chromium.chrome.browser.payments.AutofillAddress;
import org.chromium.chrome.browser.payments.AutofillContact;
import org.chromium.chrome.browser.payments.AutofillPaymentInstrument;
import org.chromium.chrome.browser.payments.ContactEditor;
import org.chromium.components.payments.MethodStrings;
import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContents;
import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
/** /**
...@@ -30,31 +38,6 @@ import java.util.List; ...@@ -30,31 +38,6 @@ import java.util.List;
public class AssistantCollectUserDataModel extends PropertyModel { public class AssistantCollectUserDataModel extends PropertyModel {
// TODO(crbug.com/806868): Add |setSelectedLogin|. // TODO(crbug.com/806868): Add |setSelectedLogin|.
/**
* This class holds a the credit card and billing address information required to create an
* {@code AutofillPaymentInstrument}.
*/
public static class PaymentTuple {
private final PersonalDataManager.CreditCard mCreditCard;
@Nullable
private final PersonalDataManager.AutofillProfile mBillingAddress;
public PaymentTuple(PersonalDataManager.CreditCard creditCard,
@Nullable PersonalDataManager.AutofillProfile billingAddress) {
mCreditCard = creditCard;
mBillingAddress = billingAddress;
}
public PersonalDataManager.CreditCard getCreditCard() {
return mCreditCard;
}
@Nullable
public PersonalDataManager.AutofillProfile getBillingAddress() {
return mBillingAddress;
}
}
public static final WritableObjectPropertyKey<AssistantCollectUserDataDelegate> DELEGATE = public static final WritableObjectPropertyKey<AssistantCollectUserDataDelegate> DELEGATE =
new WritableObjectPropertyKey<>(); new WritableObjectPropertyKey<>();
...@@ -65,16 +48,16 @@ public class AssistantCollectUserDataModel extends PropertyModel { ...@@ -65,16 +48,16 @@ public class AssistantCollectUserDataModel extends PropertyModel {
public static final WritableBooleanPropertyKey VISIBLE = new WritableBooleanPropertyKey(); public static final WritableBooleanPropertyKey VISIBLE = new WritableBooleanPropertyKey();
/** The chosen shipping address. */ /** The chosen shipping address. */
public static final WritableObjectPropertyKey<PersonalDataManager.AutofillProfile> public static final WritableObjectPropertyKey<AutofillAddress> SELECTED_SHIPPING_ADDRESS =
SHIPPING_ADDRESS = new WritableObjectPropertyKey<>(); new WritableObjectPropertyKey<>();
/** The chosen payment method (including billing address). */ /** The chosen payment method (including billing address). */
public static final WritableObjectPropertyKey<AssistantCollectUserDataModel.PaymentTuple> public static final WritableObjectPropertyKey<AutofillPaymentInstrument>
PAYMENT_METHOD = new WritableObjectPropertyKey<>(); SELECTED_PAYMENT_INSTRUMENT = new WritableObjectPropertyKey<>();
/** The chosen contact details. */ /** The chosen contact details. */
public static final WritableObjectPropertyKey<PersonalDataManager.AutofillProfile> public static final WritableObjectPropertyKey<AutofillContact> SELECTED_CONTACT_DETAILS =
CONTACT_DETAILS = new WritableObjectPropertyKey<>(); new WritableObjectPropertyKey<>();
/** The login section title. */ /** The login section title. */
public static final WritableObjectPropertyKey<String> LOGIN_SECTION_TITLE = public static final WritableObjectPropertyKey<String> LOGIN_SECTION_TITLE =
...@@ -101,11 +84,17 @@ public class AssistantCollectUserDataModel extends PropertyModel { ...@@ -101,11 +84,17 @@ public class AssistantCollectUserDataModel extends PropertyModel {
public static final WritableBooleanPropertyKey REQUEST_LOGIN_CHOICE = public static final WritableBooleanPropertyKey REQUEST_LOGIN_CHOICE =
new WritableBooleanPropertyKey(); new WritableBooleanPropertyKey();
public static final WritableObjectPropertyKey<List<PersonalDataManager.AutofillProfile>> public static final WritableObjectPropertyKey<List<AutofillAddress>>
AVAILABLE_PROFILES = new WritableObjectPropertyKey<>(); AVAILABLE_BILLING_ADDRESSES = new WritableObjectPropertyKey<>();
public static final WritableObjectPropertyKey<List<AutofillContact>> AVAILABLE_CONTACTS =
new WritableObjectPropertyKey<>();
public static final WritableObjectPropertyKey<List<AutofillAddress>>
AVAILABLE_SHIPPING_ADDRESSES = new WritableObjectPropertyKey<>();
public static final WritableObjectPropertyKey<List<AssistantCollectUserDataModel.PaymentTuple>> public static final WritableObjectPropertyKey<List<AutofillPaymentInstrument>>
AVAILABLE_AUTOFILL_PAYMENT_METHODS = new WritableObjectPropertyKey<>(); AVAILABLE_PAYMENT_INSTRUMENTS = new WritableObjectPropertyKey<>();
public static final WritableObjectPropertyKey<List<String>> SUPPORTED_BASIC_CARD_NETWORKS = public static final WritableObjectPropertyKey<List<String>> SUPPORTED_BASIC_CARD_NETWORKS =
new WritableObjectPropertyKey<>(); new WritableObjectPropertyKey<>();
...@@ -155,11 +144,12 @@ public class AssistantCollectUserDataModel extends PropertyModel { ...@@ -155,11 +144,12 @@ public class AssistantCollectUserDataModel extends PropertyModel {
new WritableObjectPropertyKey<>(); new WritableObjectPropertyKey<>();
public AssistantCollectUserDataModel() { public AssistantCollectUserDataModel() {
super(DELEGATE, WEB_CONTENTS, VISIBLE, SHIPPING_ADDRESS, PAYMENT_METHOD, CONTACT_DETAILS, super(DELEGATE, WEB_CONTENTS, VISIBLE, SELECTED_SHIPPING_ADDRESS,
LOGIN_SECTION_TITLE, SELECTED_LOGIN, TERMS_STATUS, REQUEST_NAME, REQUEST_EMAIL, SELECTED_PAYMENT_INSTRUMENT, SELECTED_CONTACT_DETAILS, LOGIN_SECTION_TITLE,
REQUEST_PHONE, REQUEST_SHIPPING_ADDRESS, REQUEST_PAYMENT, SELECTED_LOGIN, TERMS_STATUS, REQUEST_NAME, REQUEST_EMAIL, REQUEST_PHONE,
ACCEPT_TERMS_AND_CONDITIONS_TEXT, SHOW_TERMS_AS_CHECKBOX, REQUEST_LOGIN_CHOICE, REQUEST_SHIPPING_ADDRESS, REQUEST_PAYMENT, ACCEPT_TERMS_AND_CONDITIONS_TEXT,
AVAILABLE_PROFILES, AVAILABLE_AUTOFILL_PAYMENT_METHODS, SHOW_TERMS_AS_CHECKBOX, REQUEST_LOGIN_CHOICE, AVAILABLE_BILLING_ADDRESSES,
AVAILABLE_CONTACTS, AVAILABLE_SHIPPING_ADDRESSES, AVAILABLE_PAYMENT_INSTRUMENTS,
SUPPORTED_BASIC_CARD_NETWORKS, AVAILABLE_LOGINS, EXPANDED_SECTION, SUPPORTED_BASIC_CARD_NETWORKS, AVAILABLE_LOGINS, EXPANDED_SECTION,
REQUIRE_BILLING_POSTAL_CODE, BILLING_POSTAL_CODE_MISSING_TEXT, REQUEST_DATE_RANGE, REQUIRE_BILLING_POSTAL_CODE, BILLING_POSTAL_CODE_MISSING_TEXT, REQUEST_DATE_RANGE,
DATE_RANGE_START, DATE_RANGE_START_LABEL, DATE_RANGE_END, DATE_RANGE_END_LABEL, DATE_RANGE_START, DATE_RANGE_START_LABEL, DATE_RANGE_END, DATE_RANGE_END_LABEL,
...@@ -181,8 +171,12 @@ public class AssistantCollectUserDataModel extends PropertyModel { ...@@ -181,8 +171,12 @@ public class AssistantCollectUserDataModel extends PropertyModel {
set(REQUIRE_BILLING_POSTAL_CODE, false); set(REQUIRE_BILLING_POSTAL_CODE, false);
set(DATE_RANGE_START_LABEL, ""); set(DATE_RANGE_START_LABEL, "");
set(DATE_RANGE_END_LABEL, ""); set(DATE_RANGE_END_LABEL, "");
set(PREPENDED_SECTIONS, new ArrayList<>()); set(PREPENDED_SECTIONS, Collections.emptyList());
set(APPENDED_SECTIONS, new ArrayList<>()); set(APPENDED_SECTIONS, Collections.emptyList());
set(AVAILABLE_PAYMENT_INSTRUMENTS, Collections.emptyList());
set(AVAILABLE_CONTACTS, Collections.emptyList());
set(AVAILABLE_SHIPPING_ADDRESSES, Collections.emptyList());
set(AVAILABLE_BILLING_ADDRESSES, Collections.emptyList());
} }
@CalledByNative @CalledByNative
...@@ -266,23 +260,19 @@ public class AssistantCollectUserDataModel extends PropertyModel { ...@@ -266,23 +260,19 @@ public class AssistantCollectUserDataModel extends PropertyModel {
} }
@CalledByNative @CalledByNative
private void setContactDetails(@Nullable PersonalDataManager.AutofillProfile contact) { private void setSelectedContactDetails(@Nullable AutofillContact contact) {
set(CONTACT_DETAILS, contact); set(SELECTED_CONTACT_DETAILS, contact);
} }
@CalledByNative @CalledByNative
private void setShippingAddress(@Nullable PersonalDataManager.AutofillProfile shippingAddress) { private void setSelectedShippingAddress(@Nullable AutofillAddress shippingAddress) {
set(SHIPPING_ADDRESS, shippingAddress); set(SELECTED_SHIPPING_ADDRESS, shippingAddress);
} }
@CalledByNative @CalledByNative
private void setPaymentMethod(@Nullable PersonalDataManager.CreditCard card, private void setSelectedPaymentInstrument(
@Nullable PersonalDataManager.AutofillProfile billingAddress) { @Nullable AutofillPaymentInstrument paymentInstrument) {
if (card == null) { set(SELECTED_PAYMENT_INSTRUMENT, paymentInstrument);
set(PAYMENT_METHOD, null);
} else {
set(PAYMENT_METHOD, new PaymentTuple(card, billingAddress));
}
} }
/** Creates an empty list of login options. */ /** Creates an empty list of login options. */
...@@ -397,39 +387,105 @@ public class AssistantCollectUserDataModel extends PropertyModel { ...@@ -397,39 +387,105 @@ public class AssistantCollectUserDataModel extends PropertyModel {
} }
@CalledByNative @CalledByNative
private static List<PersonalDataManager.AutofillProfile> createAutofillProfileList() { private static List<AutofillContact> createAutofillContactList() {
return new ArrayList<>(); return new ArrayList<>();
} }
@CalledByNative @CalledByNative
private static void addAutofillProfile(List<PersonalDataManager.AutofillProfile> profiles, private static void addAutofillContact(
PersonalDataManager.AutofillProfile profile) { List<AutofillContact> contacts, AutofillContact contact) {
profiles.add(profile); contacts.add(contact);
} }
@VisibleForTesting
@CalledByNative @CalledByNative
private void setAutofillProfiles(List<PersonalDataManager.AutofillProfile> profiles) { @Nullable
set(AVAILABLE_PROFILES, profiles); public static AutofillContact createAutofillContact(Context context,
@Nullable PersonalDataManager.AutofillProfile profile, boolean requestName,
boolean requestPhone, boolean requestEmail) {
if (profile == null || !(requestName || requestPhone || requestEmail)) {
return null;
}
ContactEditor editor =
new ContactEditor(requestName, requestPhone, requestEmail, /* saveToDisk= */ false);
String name = profile.getFullName();
String phone = profile.getPhoneNumber();
String email = profile.getEmailAddress();
return new AutofillContact(context, profile, name, phone, email,
editor.checkContactCompletionStatus(name, phone, email), requestName, requestPhone,
requestEmail);
}
@CalledByNative
private void setAvailableContacts(List<AutofillContact> contacts) {
set(AVAILABLE_CONTACTS, contacts);
} }
@CalledByNative @CalledByNative
private static List<AssistantCollectUserDataModel.PaymentTuple> private static List<AutofillAddress> createAutofillAddressList() {
createAutofillPaymentMethodList() {
return new ArrayList<>(); return new ArrayList<>();
} }
@CalledByNative @CalledByNative
private static void addAutofillPaymentMethod( private static void addAutofillAddress(
List<AssistantCollectUserDataModel.PaymentTuple> paymentTuples, List<AutofillAddress> addresses, AutofillAddress address) {
PersonalDataManager.CreditCard card, addresses.add(address);
@Nullable PersonalDataManager.AutofillProfile billingAddress) { }
paymentTuples.add(new PaymentTuple(card, billingAddress));
@VisibleForTesting
@CalledByNative
@Nullable
public static AutofillAddress createAutofillAddress(
Context context, @Nullable PersonalDataManager.AutofillProfile profile) {
if (profile == null) {
return null;
}
return new AutofillAddress(context, profile);
}
@CalledByNative
private void setAvailableShippingAddresses(List<AutofillAddress> addresses) {
set(AVAILABLE_SHIPPING_ADDRESSES, addresses);
}
@CalledByNative
private void setAvailableBillingAddresses(List<AutofillAddress> addresses) {
set(AVAILABLE_BILLING_ADDRESSES, addresses);
}
@CalledByNative
private static List<AutofillPaymentInstrument> createAutofillPaymentInstrumentList() {
return new ArrayList<>();
}
@CalledByNative
private static void addAutofillPaymentInstrument(
List<AutofillPaymentInstrument> paymentInstruments,
AutofillPaymentInstrument paymentInstrument) {
paymentInstruments.add(paymentInstrument);
}
@VisibleForTesting
@CalledByNative
@Nullable
public AutofillPaymentInstrument createAutofillPaymentInstrument(
@Nullable PersonalDataManager.CreditCard card,
@Nullable PersonalDataManager.AutofillProfile billingProfile) {
if (card == null) {
return null;
}
WebContents webContents = get(WEB_CONTENTS);
if (webContents == null) {
return null;
}
return new AutofillPaymentInstrument(webContents, card, billingProfile,
MethodStrings.BASIC_CARD, /* matchesMerchantCardTypeExactly= */ true);
} }
@CalledByNative @CalledByNative
private void setAutofillPaymentMethods( private void setAvailablePaymentInstruments(
List<AssistantCollectUserDataModel.PaymentTuple> paymentTuples) { List<AutofillPaymentInstrument> paymentInstruments) {
set(AVAILABLE_AUTOFILL_PAYMENT_METHODS, paymentTuples); set(AVAILABLE_PAYMENT_INSTRUMENTS, paymentInstruments);
} }
@CalledByNative @CalledByNative
......
...@@ -14,12 +14,9 @@ import androidx.annotation.DrawableRes; ...@@ -14,12 +14,9 @@ import androidx.annotation.DrawableRes;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import org.chromium.chrome.autofill_assistant.R; import org.chromium.chrome.autofill_assistant.R;
import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile;
import org.chromium.chrome.browser.payments.AutofillContact; import org.chromium.chrome.browser.payments.AutofillContact;
import org.chromium.chrome.browser.payments.ContactEditor; import org.chromium.chrome.browser.payments.ContactEditor;
import org.chromium.chrome.browser.payments.ui.ContactDetailsSection;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
...@@ -140,39 +137,21 @@ public class AssistantContactDetailsSection ...@@ -140,39 +137,21 @@ public class AssistantContactDetailsSection
/** /**
* The Chrome profiles have changed externally. This will rebuild the UI with the new/changed * The Chrome profiles have changed externally. This will rebuild the UI with the new/changed
* set of profiles, while keeping the selected item if possible. * set of contacts derived from the profiles, while keeping the selected item if possible.
*/ */
void onProfilesChanged(List<AutofillProfile> profiles, boolean requestPayerEmail, void onContactsChanged(List<AutofillContact> contacts) {
boolean requestPayerName, boolean requestPayerPhone) {
if (mIgnoreProfileChangeNotifications) { if (mIgnoreProfileChangeNotifications) {
return; return;
} }
if (!requestPayerEmail && !requestPayerName && !requestPayerPhone) {
return;
}
// Note: we create a temporary editor (necessary for converting profiles to contacts)
// instead of using mEditor, which may be null.
ContactEditor tempEditor =
new ContactEditor(requestPayerName, requestPayerPhone, requestPayerEmail, false);
// Convert profiles into a list of |AutofillContact|.
int selectedContactIndex = -1; int selectedContactIndex = -1;
ContactDetailsSection sectionInformation = if (mSelectedOption != null) {
new ContactDetailsSection(mContext, profiles, tempEditor, null); for (int i = 0; i < contacts.size(); i++) {
List<AutofillContact> contacts = new ArrayList<>(); if (areEqual(contacts.get(i), mSelectedOption)) {
for (int i = 0; i < sectionInformation.getSize(); i++) {
AutofillContact contact = (AutofillContact) sectionInformation.getItem(i);
if (contact == null) {
continue;
}
contacts.add(contact);
if (mSelectedOption != null && areEqual(contact, mSelectedOption)) {
selectedContactIndex = i; selectedContactIndex = i;
break;
}
} }
} }
// Replace current set of items, keep selection if possible. // Replace current set of items, keep selection if possible.
setItems(contacts, selectedContactIndex); setItems(contacts, selectedContactIndex);
} }
......
...@@ -56,7 +56,7 @@ public class AssistantPaymentMethodSection ...@@ -56,7 +56,7 @@ public class AssistantPaymentMethodSection
String guid = method.getCard().getBillingAddressId(); String guid = method.getCard().getBillingAddressId();
PersonalDataManager.AutofillProfile profile = personalDataManager.getProfile(guid); PersonalDataManager.AutofillProfile profile = personalDataManager.getProfile(guid);
if (profile != null) { if (profile != null) {
addAutocompleteInformationToEditor(profile); addAutocompleteInformationToEditor(new AutofillAddress(mContext, profile));
} }
} }
} }
...@@ -166,10 +166,10 @@ public class AssistantPaymentMethodSection ...@@ -166,10 +166,10 @@ public class AssistantPaymentMethodSection
return TextUtils.equals(profileA.getGUID(), profileB.getGUID()); return TextUtils.equals(profileA.getGUID(), profileB.getGUID());
} }
void onProfilesChanged(List<PersonalDataManager.AutofillProfile> profiles) { void onAddressesChanged(List<AutofillAddress> addresses) {
// TODO(crbug.com/806868): replace suggested billing addresses (remove if necessary). // TODO(crbug.com/806868): replace suggested billing addresses (remove if necessary).
for (PersonalDataManager.AutofillProfile profile : profiles) { for (AutofillAddress address : addresses) {
addAutocompleteInformationToEditor(profile); addAutocompleteInformationToEditor(address);
} }
} }
...@@ -204,12 +204,12 @@ public class AssistantPaymentMethodSection ...@@ -204,12 +204,12 @@ public class AssistantPaymentMethodSection
mBillingPostalCodeMissingText = text; mBillingPostalCodeMissingText = text;
} }
private void addAutocompleteInformationToEditor(PersonalDataManager.AutofillProfile profile) { private void addAutocompleteInformationToEditor(AutofillAddress address) {
// The check for non-null label is necessary to prevent crash in editor when opening. // The check for non-null label is necessary to prevent crash in editor when opening.
if (mEditor == null || profile.getLabel() == null) { if (mEditor == null || address.getProfile().getLabel() == null) {
return; return;
} }
mEditor.updateBillingAddressIfComplete(new AutofillAddress(mContext, profile)); mEditor.updateBillingAddressIfComplete(address);
} }
private boolean hasAllRequiredFields(AutofillPaymentInstrument method) { private boolean hasAllRequiredFields(AutofillPaymentInstrument method) {
......
...@@ -18,7 +18,6 @@ import org.chromium.chrome.browser.autofill.PersonalDataManager; ...@@ -18,7 +18,6 @@ import org.chromium.chrome.browser.autofill.PersonalDataManager;
import org.chromium.chrome.browser.payments.AddressEditor; import org.chromium.chrome.browser.payments.AddressEditor;
import org.chromium.chrome.browser.payments.AutofillAddress; import org.chromium.chrome.browser.payments.AutofillAddress;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
...@@ -125,21 +124,23 @@ public class AssistantShippingAddressSection ...@@ -125,21 +124,23 @@ public class AssistantShippingAddressSection
return TextUtils.equals(optionA.getProfile().getGUID(), optionB.getProfile().getGUID()); return TextUtils.equals(optionA.getProfile().getGUID(), optionB.getProfile().getGUID());
} }
void onProfilesChanged(List<PersonalDataManager.AutofillProfile> profiles) { /**
* The Chrome profiles have changed externally. This will rebuild the UI with the new/changed
* set of addresses derived from the profiles, while keeping the selected item if possible.
*/
void onAddressesChanged(List<AutofillAddress> addresses) {
if (mIgnoreProfileChangeNotifications) { if (mIgnoreProfileChangeNotifications) {
return; return;
} }
int selectedAddressIndex = -1; int selectedAddressIndex = -1;
List<AutofillAddress> addresses = new ArrayList<>(); if (mSelectedOption != null) {
for (int i = 0; i < profiles.size(); i++) { for (int i = 0; i < addresses.size(); i++) {
AutofillAddress autofillAddress = new AutofillAddress(mContext, profiles.get(i)); if (areEqual(addresses.get(i), mSelectedOption)) {
if (mSelectedOption != null && areEqual(mSelectedOption, autofillAddress)) {
selectedAddressIndex = i; selectedAddressIndex = i;
break;
}
} }
addresses.add(autofillAddress);
} }
// Replace current set of items, keep selection if possible. // Replace current set of items, keep selection if possible.
setItems(addresses, selectedAddressIndex); setItems(addresses, selectedAddressIndex);
} }
......
...@@ -64,6 +64,9 @@ import org.chromium.chrome.browser.autofill_assistant.user_data.additional_secti ...@@ -64,6 +64,9 @@ import org.chromium.chrome.browser.autofill_assistant.user_data.additional_secti
import org.chromium.chrome.browser.autofill_assistant.user_data.additional_sections.AssistantTextInputSection.TextInputFactory; import org.chromium.chrome.browser.autofill_assistant.user_data.additional_sections.AssistantTextInputSection.TextInputFactory;
import org.chromium.chrome.browser.autofill_assistant.user_data.additional_sections.AssistantTextInputType; import org.chromium.chrome.browser.autofill_assistant.user_data.additional_sections.AssistantTextInputType;
import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule; import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
import org.chromium.chrome.browser.payments.AutofillAddress;
import org.chromium.chrome.browser.payments.AutofillContact;
import org.chromium.chrome.browser.payments.AutofillPaymentInstrument;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils;
...@@ -131,17 +134,18 @@ public class AutofillAssistantCollectUserDataUiTest { ...@@ -131,17 +134,18 @@ public class AutofillAssistantCollectUserDataUiTest {
/* Test initial model state. */ /* Test initial model state. */
assertThat(model.get(AssistantCollectUserDataModel.VISIBLE), is(false)); assertThat(model.get(AssistantCollectUserDataModel.VISIBLE), is(false));
assertThat(model.get(AssistantCollectUserDataModel.AVAILABLE_PROFILES), nullValue()); assertThat(model.get(AssistantCollectUserDataModel.AVAILABLE_CONTACTS), empty());
assertThat(model.get(AssistantCollectUserDataModel.AVAILABLE_AUTOFILL_PAYMENT_METHODS), assertThat(model.get(AssistantCollectUserDataModel.AVAILABLE_SHIPPING_ADDRESSES), empty());
nullValue()); assertThat(model.get(AssistantCollectUserDataModel.AVAILABLE_PAYMENT_INSTRUMENTS), empty());
assertThat(model.get(AssistantCollectUserDataModel.SUPPORTED_BASIC_CARD_NETWORKS), assertThat(model.get(AssistantCollectUserDataModel.SUPPORTED_BASIC_CARD_NETWORKS),
nullValue()); nullValue());
assertThat(model.get(AssistantCollectUserDataModel.EXPANDED_SECTION), nullValue()); assertThat(model.get(AssistantCollectUserDataModel.EXPANDED_SECTION), nullValue());
assertThat(model.get(AssistantCollectUserDataModel.DELEGATE), nullValue()); assertThat(model.get(AssistantCollectUserDataModel.DELEGATE), nullValue());
assertThat(model.get(AssistantCollectUserDataModel.WEB_CONTENTS), nullValue()); assertThat(model.get(AssistantCollectUserDataModel.WEB_CONTENTS), nullValue());
assertThat(model.get(AssistantCollectUserDataModel.SHIPPING_ADDRESS), nullValue()); assertThat(model.get(AssistantCollectUserDataModel.SELECTED_SHIPPING_ADDRESS), nullValue());
assertThat(model.get(AssistantCollectUserDataModel.PAYMENT_METHOD), nullValue()); assertThat(
assertThat(model.get(AssistantCollectUserDataModel.CONTACT_DETAILS), nullValue()); model.get(AssistantCollectUserDataModel.SELECTED_PAYMENT_INSTRUMENT), nullValue());
assertThat(model.get(AssistantCollectUserDataModel.SELECTED_CONTACT_DETAILS), nullValue());
assertThat(model.get(AssistantCollectUserDataModel.TERMS_STATUS), assertThat(model.get(AssistantCollectUserDataModel.TERMS_STATUS),
is(AssistantTermsAndConditionsState.NOT_SELECTED)); is(AssistantTermsAndConditionsState.NOT_SELECTED));
assertThat(model.get(AssistantCollectUserDataModel.SELECTED_LOGIN), nullValue()); assertThat(model.get(AssistantCollectUserDataModel.SELECTED_LOGIN), nullValue());
...@@ -378,8 +382,8 @@ public class AutofillAssistantCollectUserDataUiTest { ...@@ -378,8 +382,8 @@ public class AutofillAssistantCollectUserDataUiTest {
model.set(AssistantCollectUserDataModel.WEB_CONTENTS, mTestRule.getWebContents()); model.set(AssistantCollectUserDataModel.WEB_CONTENTS, mTestRule.getWebContents());
model.set(AssistantCollectUserDataModel.REQUEST_NAME, true); model.set(AssistantCollectUserDataModel.REQUEST_NAME, true);
model.set(AssistantCollectUserDataModel.REQUEST_EMAIL, true); model.set(AssistantCollectUserDataModel.REQUEST_EMAIL, true);
model.set(AssistantCollectUserDataModel.AVAILABLE_PROFILES, Collections.emptyList()); model.set(AssistantCollectUserDataModel.AVAILABLE_CONTACTS, Collections.emptyList());
model.set(AssistantCollectUserDataModel.CONTACT_DETAILS, null); model.set(AssistantCollectUserDataModel.SELECTED_CONTACT_DETAILS, null);
model.set(AssistantCollectUserDataModel.VISIBLE, true); model.set(AssistantCollectUserDataModel.VISIBLE, true);
}); });
...@@ -390,12 +394,14 @@ public class AutofillAssistantCollectUserDataUiTest { ...@@ -390,12 +394,14 @@ public class AutofillAssistantCollectUserDataUiTest {
assertThat(viewHolder.mContactList.getItemCount(), is(0)); assertThat(viewHolder.mContactList.getItemCount(), is(0));
// Add profile to the list and send the updated model. // Add profile to the list and send the updated model.
PersonalDataManager.AutofillProfile profile =
mHelper.createDummyProfile("John Doe", "john@gmail.com");
TestThreadUtils.runOnUiThreadBlocking(() -> { TestThreadUtils.runOnUiThreadBlocking(() -> {
model.set(AssistantCollectUserDataModel.AVAILABLE_PROFILES, AutofillContact contact = AssistantCollectUserDataModel.createAutofillContact(
Collections.singletonList(profile)); mTestRule.getActivity(),
model.set(AssistantCollectUserDataModel.CONTACT_DETAILS, profile); mHelper.createDummyProfile("John Doe", "john@gmail.com"),
/* requestName= */ true, /* requestPhone= */ true, /* requestEmail= */ false);
model.set(AssistantCollectUserDataModel.AVAILABLE_CONTACTS,
Collections.singletonList(contact));
model.set(AssistantCollectUserDataModel.SELECTED_CONTACT_DETAILS, contact);
}); });
// Contact details section should now contain and have pre-selected the new contact. // Contact details section should now contain and have pre-selected the new contact.
...@@ -409,8 +415,8 @@ public class AutofillAssistantCollectUserDataUiTest { ...@@ -409,8 +415,8 @@ public class AutofillAssistantCollectUserDataUiTest {
// Remove profile from the list and send the updated model. Section should be empty again. // Remove profile from the list and send the updated model. Section should be empty again.
TestThreadUtils.runOnUiThreadBlocking(() -> { TestThreadUtils.runOnUiThreadBlocking(() -> {
model.set(AssistantCollectUserDataModel.AVAILABLE_PROFILES, Collections.emptyList()); model.set(AssistantCollectUserDataModel.AVAILABLE_CONTACTS, Collections.emptyList());
model.set(AssistantCollectUserDataModel.CONTACT_DETAILS, null); model.set(AssistantCollectUserDataModel.SELECTED_CONTACT_DETAILS, null);
}); });
onView(allOf(withId(R.id.section_title_add_button), onView(allOf(withId(R.id.section_title_add_button),
...@@ -443,9 +449,9 @@ public class AutofillAssistantCollectUserDataUiTest { ...@@ -443,9 +449,9 @@ public class AutofillAssistantCollectUserDataUiTest {
model.set(AssistantCollectUserDataModel.WEB_CONTENTS, mTestRule.getWebContents()); model.set(AssistantCollectUserDataModel.WEB_CONTENTS, mTestRule.getWebContents());
model.set(AssistantCollectUserDataModel.REQUEST_PAYMENT, true); model.set(AssistantCollectUserDataModel.REQUEST_PAYMENT, true);
model.set(AssistantCollectUserDataModel.VISIBLE, true); model.set(AssistantCollectUserDataModel.VISIBLE, true);
model.set(AssistantCollectUserDataModel.AVAILABLE_AUTOFILL_PAYMENT_METHODS, model.set(AssistantCollectUserDataModel.AVAILABLE_PAYMENT_INSTRUMENTS,
Collections.emptyList()); Collections.emptyList());
model.set(AssistantCollectUserDataModel.PAYMENT_METHOD, null); model.set(AssistantCollectUserDataModel.SELECTED_PAYMENT_INSTRUMENT, null);
}); });
// Payment method section should be empty and show the 'add' button in the title. // Payment method section should be empty and show the 'add' button in the title.
...@@ -459,13 +465,13 @@ public class AutofillAssistantCollectUserDataUiTest { ...@@ -459,13 +465,13 @@ public class AutofillAssistantCollectUserDataUiTest {
mHelper.createDummyProfile("Jill Doe", "jill@gmail.com"); mHelper.createDummyProfile("Jill Doe", "jill@gmail.com");
String billingAddressId = mHelper.setProfile(billingAddress); String billingAddressId = mHelper.setProfile(billingAddress);
PersonalDataManager.CreditCard creditCard = mHelper.createDummyCreditCard(billingAddressId); PersonalDataManager.CreditCard creditCard = mHelper.createDummyCreditCard(billingAddressId);
AssistantCollectUserDataModel.PaymentTuple paymentTuple =
new AssistantCollectUserDataModel.PaymentTuple(creditCard, billingAddress);
TestThreadUtils.runOnUiThreadBlocking(() -> { TestThreadUtils.runOnUiThreadBlocking(() -> {
model.set(AssistantCollectUserDataModel.AVAILABLE_AUTOFILL_PAYMENT_METHODS, AutofillPaymentInstrument paymentInstrument =
Collections.singletonList(paymentTuple)); model.createAutofillPaymentInstrument(creditCard, billingAddress);
model.set(AssistantCollectUserDataModel.PAYMENT_METHOD, paymentTuple); model.set(AssistantCollectUserDataModel.AVAILABLE_PAYMENT_INSTRUMENTS,
Collections.singletonList(paymentInstrument));
model.set(AssistantCollectUserDataModel.SELECTED_PAYMENT_INSTRUMENT, paymentInstrument);
}); });
// Payment method section contains the new credit card, which should be pre-selected. // Payment method section contains the new credit card, which should be pre-selected.
...@@ -479,9 +485,9 @@ public class AutofillAssistantCollectUserDataUiTest { ...@@ -479,9 +485,9 @@ public class AutofillAssistantCollectUserDataUiTest {
// Remove credit card from the list. Section should be empty again. // Remove credit card from the list. Section should be empty again.
TestThreadUtils.runOnUiThreadBlocking(() -> { TestThreadUtils.runOnUiThreadBlocking(() -> {
model.set(AssistantCollectUserDataModel.AVAILABLE_AUTOFILL_PAYMENT_METHODS, model.set(AssistantCollectUserDataModel.AVAILABLE_PAYMENT_INSTRUMENTS,
Collections.emptyList()); Collections.emptyList());
model.set(AssistantCollectUserDataModel.PAYMENT_METHOD, null); model.set(AssistantCollectUserDataModel.SELECTED_PAYMENT_INSTRUMENT, null);
}); });
onView(allOf(withId(R.id.section_title_add_button), onView(allOf(withId(R.id.section_title_add_button),
isDescendantOfA(is(viewHolder.mPaymentSection)))) isDescendantOfA(is(viewHolder.mPaymentSection))))
...@@ -508,17 +514,17 @@ public class AutofillAssistantCollectUserDataUiTest { ...@@ -508,17 +514,17 @@ public class AutofillAssistantCollectUserDataUiTest {
mHelper.createDummyProfile("Jill Doe", "jill@gmail.com"); mHelper.createDummyProfile("Jill Doe", "jill@gmail.com");
String billingAddressId = mHelper.setProfile(billingAddress); String billingAddressId = mHelper.setProfile(billingAddress);
PersonalDataManager.CreditCard creditCard = mHelper.createDummyCreditCard(billingAddressId); PersonalDataManager.CreditCard creditCard = mHelper.createDummyCreditCard(billingAddressId);
AssistantCollectUserDataModel.PaymentTuple paymentTuple =
new AssistantCollectUserDataModel.PaymentTuple(creditCard, billingAddress);
TestThreadUtils.runOnUiThreadBlocking(() -> { TestThreadUtils.runOnUiThreadBlocking(() -> {
// WEB_CONTENTS are necessary for the creation of the editors. // WEB_CONTENTS are necessary for the creation of the editors.
model.set(AssistantCollectUserDataModel.WEB_CONTENTS, mTestRule.getWebContents()); model.set(AssistantCollectUserDataModel.WEB_CONTENTS, mTestRule.getWebContents());
model.set(AssistantCollectUserDataModel.REQUEST_PAYMENT, true); model.set(AssistantCollectUserDataModel.REQUEST_PAYMENT, true);
model.set(AssistantCollectUserDataModel.VISIBLE, true); model.set(AssistantCollectUserDataModel.VISIBLE, true);
model.set(AssistantCollectUserDataModel.AVAILABLE_AUTOFILL_PAYMENT_METHODS, AutofillPaymentInstrument paymentInstrument =
Collections.singletonList(paymentTuple)); model.createAutofillPaymentInstrument(creditCard, billingAddress);
model.set(AssistantCollectUserDataModel.PAYMENT_METHOD, paymentTuple); model.set(AssistantCollectUserDataModel.AVAILABLE_PAYMENT_INSTRUMENTS,
Collections.singletonList(paymentInstrument));
model.set(AssistantCollectUserDataModel.SELECTED_PAYMENT_INSTRUMENT, paymentInstrument);
}); });
// Payment method section contains the new credit card, which should be pre-selected. // Payment method section contains the new credit card, which should be pre-selected.
...@@ -569,8 +575,6 @@ public class AutofillAssistantCollectUserDataUiTest { ...@@ -569,8 +575,6 @@ public class AutofillAssistantCollectUserDataUiTest {
new PersonalDataManager.CreditCard("", "https://example.com", true, true, "Jon Doe", new PersonalDataManager.CreditCard("", "https://example.com", true, true, "Jon Doe",
"4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card,
CardType.UNKNOWN, /* billingAddressId= */ "GUID", /* serverId= */ ""); CardType.UNKNOWN, /* billingAddressId= */ "GUID", /* serverId= */ "");
AssistantCollectUserDataModel.PaymentTuple paymentTuple =
new AssistantCollectUserDataModel.PaymentTuple(creditCard, profile);
AssistantCollectUserDataModel model = new AssistantCollectUserDataModel(); AssistantCollectUserDataModel model = new AssistantCollectUserDataModel();
AssistantCollectUserDataCoordinator coordinator = createCollectUserDataCoordinator(model); AssistantCollectUserDataCoordinator coordinator = createCollectUserDataCoordinator(model);
...@@ -590,13 +594,22 @@ public class AutofillAssistantCollectUserDataUiTest { ...@@ -590,13 +594,22 @@ public class AutofillAssistantCollectUserDataUiTest {
model.set(AssistantCollectUserDataModel.REQUEST_EMAIL, true); model.set(AssistantCollectUserDataModel.REQUEST_EMAIL, true);
model.set(AssistantCollectUserDataModel.REQUEST_PAYMENT, true); model.set(AssistantCollectUserDataModel.REQUEST_PAYMENT, true);
model.set(AssistantCollectUserDataModel.REQUEST_SHIPPING_ADDRESS, true); model.set(AssistantCollectUserDataModel.REQUEST_SHIPPING_ADDRESS, true);
model.set(AssistantCollectUserDataModel.AVAILABLE_PROFILES, AutofillContact contact = AssistantCollectUserDataModel.createAutofillContact(
Collections.singletonList(profile)); mTestRule.getActivity(), profile, /* requestName= */ true,
model.set(AssistantCollectUserDataModel.CONTACT_DETAILS, profile); /* requestPhone= */ true, /* requestEmail= */ true);
model.set(AssistantCollectUserDataModel.SHIPPING_ADDRESS, profile); model.set(AssistantCollectUserDataModel.AVAILABLE_CONTACTS,
model.set(AssistantCollectUserDataModel.AVAILABLE_AUTOFILL_PAYMENT_METHODS, Collections.singletonList(contact));
Collections.singletonList(paymentTuple)); model.set(AssistantCollectUserDataModel.SELECTED_CONTACT_DETAILS, contact);
model.set(AssistantCollectUserDataModel.PAYMENT_METHOD, paymentTuple); AutofillAddress address = AssistantCollectUserDataModel.createAutofillAddress(
mTestRule.getActivity(), profile);
model.set(AssistantCollectUserDataModel.AVAILABLE_SHIPPING_ADDRESSES,
Collections.singletonList(address));
model.set(AssistantCollectUserDataModel.SELECTED_SHIPPING_ADDRESS, address);
AutofillPaymentInstrument paymentInstrument =
model.createAutofillPaymentInstrument(creditCard, profile);
model.set(AssistantCollectUserDataModel.AVAILABLE_PAYMENT_INSTRUMENTS,
Collections.singletonList(paymentInstrument));
model.set(AssistantCollectUserDataModel.SELECTED_PAYMENT_INSTRUMENT, paymentInstrument);
model.set(AssistantCollectUserDataModel.VISIBLE, true); model.set(AssistantCollectUserDataModel.VISIBLE, true);
model.set(AssistantCollectUserDataModel.REQUEST_LOGIN_CHOICE, true); model.set(AssistantCollectUserDataModel.REQUEST_LOGIN_CHOICE, true);
model.set(AssistantCollectUserDataModel.AVAILABLE_LOGINS, model.set(AssistantCollectUserDataModel.AVAILABLE_LOGINS,
...@@ -839,8 +852,6 @@ public class AutofillAssistantCollectUserDataUiTest { ...@@ -839,8 +852,6 @@ public class AutofillAssistantCollectUserDataUiTest {
AutofillAssistantCollectUserDataTestHelper AutofillAssistantCollectUserDataTestHelper
.ViewHolder viewHolder = TestThreadUtils.runOnUiThreadBlocking( .ViewHolder viewHolder = TestThreadUtils.runOnUiThreadBlocking(
() -> new AutofillAssistantCollectUserDataTestHelper.ViewHolder(coordinator)); () -> new AutofillAssistantCollectUserDataTestHelper.ViewHolder(coordinator));
AssistantCollectUserDataModel.PaymentTuple paymentTuple =
new AssistantCollectUserDataModel.PaymentTuple(creditCard, profile);
TestThreadUtils.runOnUiThreadBlocking(() -> { TestThreadUtils.runOnUiThreadBlocking(() -> {
// WEB_CONTENTS are necessary for the creation of AutofillPaymentInstrument. // WEB_CONTENTS are necessary for the creation of AutofillPaymentInstrument.
...@@ -851,9 +862,11 @@ public class AutofillAssistantCollectUserDataUiTest { ...@@ -851,9 +862,11 @@ public class AutofillAssistantCollectUserDataUiTest {
model.set(AssistantCollectUserDataModel.BILLING_POSTAL_CODE_MISSING_TEXT, model.set(AssistantCollectUserDataModel.BILLING_POSTAL_CODE_MISSING_TEXT,
"Billing postcode missing"); "Billing postcode missing");
model.set(AssistantCollectUserDataModel.REQUEST_PAYMENT, true); model.set(AssistantCollectUserDataModel.REQUEST_PAYMENT, true);
model.set(AssistantCollectUserDataModel.AVAILABLE_AUTOFILL_PAYMENT_METHODS, AutofillPaymentInstrument paymentInstrument =
Collections.singletonList(paymentTuple)); model.createAutofillPaymentInstrument(creditCard, profile);
model.set(AssistantCollectUserDataModel.PAYMENT_METHOD, paymentTuple); model.set(AssistantCollectUserDataModel.AVAILABLE_PAYMENT_INSTRUMENTS,
Collections.singletonList(paymentInstrument));
model.set(AssistantCollectUserDataModel.SELECTED_PAYMENT_INSTRUMENT, paymentInstrument);
model.set(AssistantCollectUserDataModel.VISIBLE, true); model.set(AssistantCollectUserDataModel.VISIBLE, true);
}); });
......
...@@ -1027,6 +1027,9 @@ void UiControllerAndroid::OnUserDataChanged( ...@@ -1027,6 +1027,9 @@ void UiControllerAndroid::OnUserDataChanged(
return; return;
} }
auto jcontext =
Java_AutofillAssistantUiController_getContext(env, java_object_);
if (field_change == UserData::FieldChange::ALL || if (field_change == UserData::FieldChange::ALL ||
field_change == UserData::FieldChange::TERMS_AND_CONDITIONS) { field_change == UserData::FieldChange::TERMS_AND_CONDITIONS) {
Java_AssistantCollectUserDataModel_setTermsStatus( Java_AssistantCollectUserDataModel_setTermsStatus(
...@@ -1035,73 +1038,132 @@ void UiControllerAndroid::OnUserDataChanged( ...@@ -1035,73 +1038,132 @@ void UiControllerAndroid::OnUserDataChanged(
if (field_change == UserData::FieldChange::ALL || if (field_change == UserData::FieldChange::ALL ||
field_change == UserData::FieldChange::AVAILABLE_PROFILES) { field_change == UserData::FieldChange::AVAILABLE_PROFILES) {
auto sorted_profile_indices = SortByCompleteness(*collect_user_data_options, // Contact profiles.
state->available_profiles); auto jcontactlist =
auto jlist = Java_AssistantCollectUserDataModel_createAutofillContactList(env);
Java_AssistantCollectUserDataModel_createAutofillProfileList(env); auto contact_indices = SortContactsByCompleteness(
for (int index : sorted_profile_indices) { *collect_user_data_options, state->available_profiles);
Java_AssistantCollectUserDataModel_addAutofillProfile( for (int index : contact_indices) {
env, jlist, auto jcontact = Java_AssistantCollectUserDataModel_createAutofillContact(
env, jcontext,
autofill::PersonalDataManagerAndroid::CreateJavaProfileFromNative( autofill::PersonalDataManagerAndroid::CreateJavaProfileFromNative(
env, *state->available_profiles[index])); env, *state->available_profiles[index]),
collect_user_data_options->request_payer_name,
collect_user_data_options->request_payer_phone,
collect_user_data_options->request_payer_email);
if (jcontact) {
Java_AssistantCollectUserDataModel_addAutofillContact(env, jcontactlist,
jcontact);
} }
Java_AssistantCollectUserDataModel_setAutofillProfiles(env, jmodel, jlist); }
Java_AssistantCollectUserDataModel_setAvailableContacts(env, jmodel,
jcontactlist);
// Ignore changes to FieldChange::CONTACT_PROFILE, this is already coming // Ignore changes to FieldChange::CONTACT_PROFILE, this is already coming
// from the view. // from the view.
autofill::AutofillProfile* contact_profile = state->contact_profile.get(); autofill::AutofillProfile* contact_profile = state->contact_profile.get();
Java_AssistantCollectUserDataModel_setContactDetails( Java_AssistantCollectUserDataModel_setSelectedContactDetails(
env, jmodel, env, jmodel,
contact_profile == nullptr contact_profile == nullptr
? nullptr ? nullptr
: autofill::PersonalDataManagerAndroid::CreateJavaProfileFromNative( : Java_AssistantCollectUserDataModel_createAutofillContact(
env, *contact_profile)); env, jcontext,
autofill::PersonalDataManagerAndroid::
CreateJavaProfileFromNative(env, *contact_profile),
collect_user_data_options->request_payer_name,
collect_user_data_options->request_payer_phone,
collect_user_data_options->request_payer_email));
// Billing addresses profiles.
auto jbillinglist =
Java_AssistantCollectUserDataModel_createAutofillAddressList(env);
for (const auto& profile : state->available_profiles) {
auto jaddress = Java_AssistantCollectUserDataModel_createAutofillAddress(
env, jcontext,
autofill::PersonalDataManagerAndroid::CreateJavaProfileFromNative(
env, *profile));
if (jaddress) {
Java_AssistantCollectUserDataModel_addAutofillAddress(env, jbillinglist,
jaddress);
}
}
Java_AssistantCollectUserDataModel_setAvailableBillingAddresses(
env, jmodel, jbillinglist);
// Address profiles.
auto jshippinglist =
Java_AssistantCollectUserDataModel_createAutofillAddressList(env);
auto address_indices = SortAddressesByCompleteness(
*collect_user_data_options, state->available_profiles);
for (int index : address_indices) {
auto jaddress = Java_AssistantCollectUserDataModel_createAutofillAddress(
env, jcontext,
autofill::PersonalDataManagerAndroid::CreateJavaProfileFromNative(
env, *state->available_profiles[index]));
if (jaddress) {
Java_AssistantCollectUserDataModel_addAutofillAddress(
env, jshippinglist, jaddress);
}
}
Java_AssistantCollectUserDataModel_setAvailableShippingAddresses(
env, jmodel, jshippinglist);
// Ignore changes to FieldChange::SHIPPING_ADDRESS, this is already coming // Ignore changes to FieldChange::SHIPPING_ADDRESS, this is already coming
// from the view. // from the view.
autofill::AutofillProfile* shipping_address = state->shipping_address.get(); autofill::AutofillProfile* shipping_address = state->shipping_address.get();
Java_AssistantCollectUserDataModel_setShippingAddress( Java_AssistantCollectUserDataModel_setSelectedShippingAddress(
env, jmodel, env, jmodel,
shipping_address == nullptr shipping_address == nullptr
? nullptr ? nullptr
: autofill::PersonalDataManagerAndroid::CreateJavaProfileFromNative( : Java_AssistantCollectUserDataModel_createAutofillAddress(
env, *shipping_address)); env, jcontext,
autofill::PersonalDataManagerAndroid::
CreateJavaProfileFromNative(env, *shipping_address)));
} }
if (field_change == UserData::FieldChange::ALL || if (field_change == UserData::FieldChange::ALL ||
field_change == UserData::FieldChange::AVAILABLE_PAYMENT_INSTRUMENTS) { field_change == UserData::FieldChange::AVAILABLE_PAYMENT_INSTRUMENTS) {
auto sorted_payment_instrument_indices = SortByCompleteness(
*collect_user_data_options, state->available_payment_instruments);
auto jlist = auto jlist =
Java_AssistantCollectUserDataModel_createAutofillPaymentMethodList(env); Java_AssistantCollectUserDataModel_createAutofillPaymentInstrumentList(
env);
auto sorted_payment_instrument_indices =
SortPaymentInstrumentsByCompleteness(
*collect_user_data_options, state->available_payment_instruments);
for (int index : sorted_payment_instrument_indices) { for (int index : sorted_payment_instrument_indices) {
const auto& instrument = state->available_payment_instruments[index]; const auto& instrument = state->available_payment_instruments[index];
Java_AssistantCollectUserDataModel_addAutofillPaymentMethod( auto jpaymentinstrument =
env, jlist, Java_AssistantCollectUserDataModel_createAutofillPaymentInstrument(
autofill::PersonalDataManagerAndroid::CreateJavaCreditCardFromNative( env, jmodel,
env, *(instrument->card)), autofill::PersonalDataManagerAndroid::
CreateJavaCreditCardFromNative(env, *(instrument->card)),
instrument->billing_address == nullptr instrument->billing_address == nullptr
? nullptr ? nullptr
: autofill::PersonalDataManagerAndroid:: : autofill::PersonalDataManagerAndroid::
CreateJavaProfileFromNative( CreateJavaProfileFromNative(
env, *(instrument->billing_address))); env, *(instrument->billing_address)));
if (jpaymentinstrument) {
Java_AssistantCollectUserDataModel_addAutofillPaymentInstrument(
env, jlist, jpaymentinstrument);
}
} }
Java_AssistantCollectUserDataModel_setAutofillPaymentMethods(env, jmodel, Java_AssistantCollectUserDataModel_setAvailablePaymentInstruments(
jlist); env, jmodel, jlist);
// Ignore changes to FieldChange::CARD, this is already coming from the // Ignore changes to FieldChange::CARD, this is already coming from the
// view. // view.
autofill::CreditCard* card = state->card.get(); autofill::CreditCard* card = state->card.get();
autofill::AutofillProfile* billing_address = state->billing_address.get(); autofill::AutofillProfile* billing_address = state->billing_address.get();
Java_AssistantCollectUserDataModel_setPaymentMethod( Java_AssistantCollectUserDataModel_setSelectedPaymentInstrument(
env, jmodel,
Java_AssistantCollectUserDataModel_createAutofillPaymentInstrument(
env, jmodel, env, jmodel,
card == nullptr ? nullptr card == nullptr ? nullptr
: autofill::PersonalDataManagerAndroid:: : autofill::PersonalDataManagerAndroid::
CreateJavaCreditCardFromNative(env, *card), CreateJavaCreditCardFromNative(env, *card),
billing_address == nullptr billing_address == nullptr
? nullptr ? nullptr
: autofill::PersonalDataManagerAndroid::CreateJavaProfileFromNative( : autofill::PersonalDataManagerAndroid::
env, *billing_address)); CreateJavaProfileFromNative(env, *billing_address)));
} }
// TODO(crbug.com/806868): Add |setSelectedLogin|. // TODO(crbug.com/806868): Add |setSelectedLogin|.
......
...@@ -832,8 +832,8 @@ void CollectUserDataAction::UpdatePersonalDataManagerProfiles( ...@@ -832,8 +832,8 @@ void CollectUserDataAction::UpdatePersonalDataManagerProfiles(
(collect_user_data_options_->request_payer_name || (collect_user_data_options_->request_payer_name ||
collect_user_data_options_->request_payer_phone || collect_user_data_options_->request_payer_phone ||
collect_user_data_options_->request_payer_email)) { collect_user_data_options_->request_payer_email)) {
int default_selection = GetDefaultProfile(*collect_user_data_options_, int default_selection = GetDefaultContactProfile(
user_data->available_profiles); *collect_user_data_options_, user_data->available_profiles);
if (default_selection != -1) { if (default_selection != -1) {
user_data->contact_profile = std::make_unique<autofill::AutofillProfile>( user_data->contact_profile = std::make_unique<autofill::AutofillProfile>(
*(user_data->available_profiles[default_selection])); *(user_data->available_profiles[default_selection]));
...@@ -845,8 +845,8 @@ void CollectUserDataAction::UpdatePersonalDataManagerProfiles( ...@@ -845,8 +845,8 @@ void CollectUserDataAction::UpdatePersonalDataManagerProfiles(
} }
if (user_data->shipping_address == nullptr && if (user_data->shipping_address == nullptr &&
collect_user_data_options_->request_shipping) { collect_user_data_options_->request_shipping) {
int default_selection = GetDefaultProfile(*collect_user_data_options_, int default_selection = GetDefaultAddressProfile(
user_data->available_profiles); *collect_user_data_options_, user_data->available_profiles);
if (default_selection != -1) { if (default_selection != -1) {
user_data->shipping_address = std::make_unique<autofill::AutofillProfile>( user_data->shipping_address = std::make_unique<autofill::AutofillProfile>(
*(user_data->available_profiles[default_selection])); *(user_data->available_profiles[default_selection]));
......
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
#include "base/i18n/case_conversion.h" #include "base/i18n/case_conversion.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_data_util.h" #include "components/autofill/core/browser/autofill_data_util.h"
#include "components/autofill/core/browser/geo/address_i18n.h"
#include "third_party/libaddressinput/chromium/addressinput_util.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h"
namespace autofill_assistant { namespace autofill_assistant {
namespace { namespace {
...@@ -20,7 +23,7 @@ base::string16 GetProfileFullName(const autofill::AutofillProfile& profile) { ...@@ -20,7 +23,7 @@ base::string16 GetProfileFullName(const autofill::AutofillProfile& profile) {
profile.GetRawInfo(autofill::NAME_LAST)); profile.GetRawInfo(autofill::NAME_LAST));
} }
int CountCompleteFields(const CollectUserDataOptions& options, int CountCompleteContactFields(const CollectUserDataOptions& options,
const autofill::AutofillProfile& profile) { const autofill::AutofillProfile& profile) {
int completed_fields = 0; int completed_fields = 0;
if (options.request_payer_name && !GetProfileFullName(profile).empty()) { if (options.request_payer_name && !GetProfileFullName(profile).empty()) {
...@@ -44,11 +47,11 @@ int CountCompleteFields(const CollectUserDataOptions& options, ...@@ -44,11 +47,11 @@ int CountCompleteFields(const CollectUserDataOptions& options,
// Helper function that compares instances of AutofillProfile by completeness // Helper function that compares instances of AutofillProfile by completeness
// in regards to the current options. Full profiles should be ordered before // in regards to the current options. Full profiles should be ordered before
// empty ones and fall back to compare the profile's name in case of equality. // empty ones and fall back to compare the profile's name in case of equality.
bool CompletenessCompare(const CollectUserDataOptions& options, bool CompletenessCompareContacts(const CollectUserDataOptions& options,
const autofill::AutofillProfile& a, const autofill::AutofillProfile& a,
const autofill::AutofillProfile& b) { const autofill::AutofillProfile& b) {
int complete_fields_a = CountCompleteFields(options, a); int complete_fields_a = CountCompleteContactFields(options, a);
int complete_fields_b = CountCompleteFields(options, b); int complete_fields_b = CountCompleteContactFields(options, b);
if (complete_fields_a == complete_fields_b) { if (complete_fields_a == complete_fields_b) {
return base::i18n::ToLower(GetProfileFullName(a)) return base::i18n::ToLower(GetProfileFullName(a))
.compare(base::i18n::ToLower(GetProfileFullName(b))) < 0; .compare(base::i18n::ToLower(GetProfileFullName(b))) < 0;
...@@ -56,7 +59,34 @@ bool CompletenessCompare(const CollectUserDataOptions& options, ...@@ -56,7 +59,34 @@ bool CompletenessCompare(const CollectUserDataOptions& options,
return complete_fields_a > complete_fields_b; return complete_fields_a > complete_fields_b;
} }
int CountCompleteFields(const CollectUserDataOptions& options, int GetAddressCompletenessRating(const CollectUserDataOptions& options,
const autofill::AutofillProfile& profile) {
auto address_data =
autofill::i18n::CreateAddressDataFromAutofillProfile(profile, "en-US");
std::multimap<i18n::addressinput::AddressField,
i18n::addressinput::AddressProblem>
problems;
autofill::addressinput::ValidateRequiredFields(
*address_data, /* filter= */ nullptr, &problems);
return -problems.size();
}
// Helper function that compares instances of AutofillProfile by completeness
// in regards to the current options. Full profiles should be ordered before
// empty ones and fall back to compare the profile's name in case of equality.
bool CompletenessCompareAddresses(const CollectUserDataOptions& options,
const autofill::AutofillProfile& a,
const autofill::AutofillProfile& b) {
int complete_fields_a = GetAddressCompletenessRating(options, a);
int complete_fields_b = GetAddressCompletenessRating(options, b);
if (complete_fields_a == complete_fields_b) {
return base::i18n::ToLower(GetProfileFullName(a))
.compare(base::i18n::ToLower(GetProfileFullName(b))) < 0;
}
return complete_fields_a > complete_fields_b;
}
int CountCompletePaymentInstrumentFields(const CollectUserDataOptions& options,
const PaymentInstrument& instrument) { const PaymentInstrument& instrument) {
int complete_fields = 0; int complete_fields = 0;
if (!instrument.card->GetRawInfo(autofill::CREDIT_CARD_NAME_FULL).empty()) { if (!instrument.card->GetRawInfo(autofill::CREDIT_CARD_NAME_FULL).empty()) {
...@@ -88,11 +118,12 @@ int CountCompleteFields(const CollectUserDataOptions& options, ...@@ -88,11 +118,12 @@ int CountCompleteFields(const CollectUserDataOptions& options,
// in regards to the current options. Full payment instruments should be // in regards to the current options. Full payment instruments should be
// ordered before empty ones and fall back to compare the full name on the // ordered before empty ones and fall back to compare the full name on the
// credit card in case of equality. // credit card in case of equality.
bool CompletenessCompare(const CollectUserDataOptions& options, bool CompletenessComparePaymentInstruments(
const CollectUserDataOptions& options,
const PaymentInstrument& a, const PaymentInstrument& a,
const PaymentInstrument& b) { const PaymentInstrument& b) {
int complete_fields_a = CountCompleteFields(options, a); int complete_fields_a = CountCompletePaymentInstrumentFields(options, a);
int complete_fields_b = CountCompleteFields(options, b); int complete_fields_b = CountCompletePaymentInstrumentFields(options, b);
if (complete_fields_a == complete_fields_b) { if (complete_fields_a == complete_fields_b) {
return base::i18n::ToLower( return base::i18n::ToLower(
a.card->GetRawInfo(autofill::CREDIT_CARD_NAME_FULL)) a.card->GetRawInfo(autofill::CREDIT_CARD_NAME_FULL))
...@@ -104,26 +135,27 @@ bool CompletenessCompare(const CollectUserDataOptions& options, ...@@ -104,26 +135,27 @@ bool CompletenessCompare(const CollectUserDataOptions& options,
} // namespace } // namespace
std::vector<int> SortByCompleteness( std::vector<int> SortContactsByCompleteness(
const CollectUserDataOptions& collect_user_data_options, const CollectUserDataOptions& collect_user_data_options,
const std::vector<std::unique_ptr<autofill::AutofillProfile>>& profiles) { const std::vector<std::unique_ptr<autofill::AutofillProfile>>& profiles) {
std::vector<int> profile_indices(profiles.size()); std::vector<int> profile_indices(profiles.size());
std::iota(std::begin(profile_indices), std::end(profile_indices), 0); std::iota(std::begin(profile_indices), std::end(profile_indices), 0);
std::sort(profile_indices.begin(), profile_indices.end(), std::sort(profile_indices.begin(), profile_indices.end(),
[&collect_user_data_options, &profiles](int i, int j) { [&collect_user_data_options, &profiles](int i, int j) {
return CompletenessCompare(collect_user_data_options, return CompletenessCompareContacts(collect_user_data_options,
*profiles[i], *profiles[j]); *profiles[i], *profiles[j]);
}); });
return profile_indices; return profile_indices;
} }
int GetDefaultProfile( int GetDefaultContactProfile(
const CollectUserDataOptions& collect_user_data_options, const CollectUserDataOptions& collect_user_data_options,
const std::vector<std::unique_ptr<autofill::AutofillProfile>>& profiles) { const std::vector<std::unique_ptr<autofill::AutofillProfile>>& profiles) {
if (profiles.empty()) { if (profiles.empty()) {
return -1; return -1;
} }
auto sorted_indices = SortByCompleteness(collect_user_data_options, profiles); auto sorted_indices =
SortContactsByCompleteness(collect_user_data_options, profiles);
if (!collect_user_data_options.default_email.empty()) { if (!collect_user_data_options.default_email.empty()) {
for (int index : sorted_indices) { for (int index : sorted_indices) {
if (base::UTF16ToUTF8( if (base::UTF16ToUTF8(
...@@ -136,7 +168,31 @@ int GetDefaultProfile( ...@@ -136,7 +168,31 @@ int GetDefaultProfile(
return sorted_indices[0]; return sorted_indices[0];
} }
std::vector<int> SortByCompleteness( std::vector<int> SortAddressesByCompleteness(
const CollectUserDataOptions& collect_user_data_options,
const std::vector<std::unique_ptr<autofill::AutofillProfile>>& profiles) {
std::vector<int> profile_indices(profiles.size());
std::iota(std::begin(profile_indices), std::end(profile_indices), 0);
std::sort(profile_indices.begin(), profile_indices.end(),
[&collect_user_data_options, &profiles](int i, int j) {
return CompletenessCompareAddresses(collect_user_data_options,
*profiles[i], *profiles[j]);
});
return profile_indices;
}
int GetDefaultAddressProfile(
const CollectUserDataOptions& collect_user_data_options,
const std::vector<std::unique_ptr<autofill::AutofillProfile>>& profiles) {
if (profiles.empty()) {
return -1;
}
auto sorted_indices =
SortContactsByCompleteness(collect_user_data_options, profiles);
return sorted_indices[0];
}
std::vector<int> SortPaymentInstrumentsByCompleteness(
const CollectUserDataOptions& collect_user_data_options, const CollectUserDataOptions& collect_user_data_options,
const std::vector<std::unique_ptr<PaymentInstrument>>& const std::vector<std::unique_ptr<PaymentInstrument>>&
payment_instruments) { payment_instruments) {
...@@ -146,8 +202,8 @@ std::vector<int> SortByCompleteness( ...@@ -146,8 +202,8 @@ std::vector<int> SortByCompleteness(
std::sort(payment_instrument_indices.begin(), std::sort(payment_instrument_indices.begin(),
payment_instrument_indices.end(), payment_instrument_indices.end(),
[&collect_user_data_options, &payment_instruments](int a, int b) { [&collect_user_data_options, &payment_instruments](int a, int b) {
return CompletenessCompare(collect_user_data_options, return CompletenessComparePaymentInstruments(
*payment_instruments[a], collect_user_data_options, *payment_instruments[a],
*payment_instruments[b]); *payment_instruments[b]);
}); });
return payment_instrument_indices; return payment_instrument_indices;
...@@ -160,8 +216,8 @@ int GetDefaultPaymentInstrument( ...@@ -160,8 +216,8 @@ int GetDefaultPaymentInstrument(
if (payment_instruments.empty()) { if (payment_instruments.empty()) {
return -1; return -1;
} }
auto sorted_indices = auto sorted_indices = SortPaymentInstrumentsByCompleteness(
SortByCompleteness(collect_user_data_options, payment_instruments); collect_user_data_options, payment_instruments);
return sorted_indices[0]; return sorted_indices[0];
} }
......
...@@ -16,13 +16,27 @@ namespace autofill_assistant { ...@@ -16,13 +16,27 @@ namespace autofill_assistant {
// vector of profile indices in sorted order. Full profiles will be ordered // vector of profile indices in sorted order. Full profiles will be ordered
// before empty ones, and for equally complete profiles, this falls back to // before empty ones, and for equally complete profiles, this falls back to
// sorting based on the profile names. // sorting based on the profile names.
std::vector<int> SortByCompleteness( std::vector<int> SortContactsByCompleteness(
const CollectUserDataOptions& collect_user_data_options, const CollectUserDataOptions& collect_user_data_options,
const std::vector<std::unique_ptr<autofill::AutofillProfile>>& profiles); const std::vector<std::unique_ptr<autofill::AutofillProfile>>& profiles);
// Get the default selection for the current list of profiles. Returns -1 if no // Get the default selection for the current list of profiles. Returns -1 if no
// default selection is possible. // default selection is possible.
int GetDefaultProfile( int GetDefaultContactProfile(
const CollectUserDataOptions& collect_user_data_options,
const std::vector<std::unique_ptr<autofill::AutofillProfile>>& profiles);
// Sorts the given autofill profiles based on completeness, and returns a
// vector of profile indices in sorted order. Full profiles will be ordered
// before empty ones, and for equally complete profiles, this falls back to
// sorting based on the profile names.
std::vector<int> SortAddressesByCompleteness(
const CollectUserDataOptions& collect_user_data_options,
const std::vector<std::unique_ptr<autofill::AutofillProfile>>& profiles);
// Get the default selection for the current list of profiles. Returns -1 if no
// default selection is possible.
int GetDefaultAddressProfile(
const CollectUserDataOptions& collect_user_data_options, const CollectUserDataOptions& collect_user_data_options,
const std::vector<std::unique_ptr<autofill::AutofillProfile>>& profiles); const std::vector<std::unique_ptr<autofill::AutofillProfile>>& profiles);
...@@ -30,7 +44,7 @@ int GetDefaultProfile( ...@@ -30,7 +44,7 @@ int GetDefaultProfile(
// of payment instrument indices in sorted order. Full payment instruments will // of payment instrument indices in sorted order. Full payment instruments will
// be ordered before empty ones, and for equally complete payment instruments, // be ordered before empty ones, and for equally complete payment instruments,
// this falls back to sorting based on the full name on the credit card. // this falls back to sorting based on the full name on the credit card.
std::vector<int> SortByCompleteness( std::vector<int> SortPaymentInstrumentsByCompleteness(
const CollectUserDataOptions& collect_user_data_options, const CollectUserDataOptions& collect_user_data_options,
const std::vector<std::unique_ptr<PaymentInstrument>>& payment_instruments); const std::vector<std::unique_ptr<PaymentInstrument>>& payment_instruments);
......
...@@ -18,7 +18,7 @@ using ::testing::ElementsAre; ...@@ -18,7 +18,7 @@ using ::testing::ElementsAre;
using ::testing::Eq; using ::testing::Eq;
using ::testing::SizeIs; using ::testing::SizeIs;
TEST(UserDataUtilTest, SortsCompleteProfilesAlphabetically) { TEST(UserDataUtilTest, SortsCompleteContactsAlphabetically) {
auto profile_a = std::make_unique<autofill::AutofillProfile>(); auto profile_a = std::make_unique<autofill::AutofillProfile>();
autofill::test::SetProfileInfo(profile_a.get(), "Adam", "", "West", autofill::test::SetProfileInfo(profile_a.get(), "Adam", "", "West",
"adam.west@gmail.com", "", "", "", "", "", "", "adam.west@gmail.com", "", "", "", "", "", "",
...@@ -47,12 +47,12 @@ TEST(UserDataUtilTest, SortsCompleteProfilesAlphabetically) { ...@@ -47,12 +47,12 @@ TEST(UserDataUtilTest, SortsCompleteProfilesAlphabetically) {
options.request_payer_email = true; options.request_payer_email = true;
std::vector<int> profile_indices = std::vector<int> profile_indices =
autofill_assistant::SortByCompleteness(options, profiles); autofill_assistant::SortContactsByCompleteness(options, profiles);
EXPECT_THAT(profile_indices, SizeIs(profiles.size())); EXPECT_THAT(profile_indices, SizeIs(profiles.size()));
EXPECT_THAT(profile_indices, ElementsAre(2, 1, 0)); EXPECT_THAT(profile_indices, ElementsAre(2, 1, 0));
} }
TEST(UserDataUtilTest, SortsProfilesByCompleteness) { TEST(UserDataUtilTest, SortsContactsByCompleteness) {
auto profile_complete = std::make_unique<autofill::AutofillProfile>(); auto profile_complete = std::make_unique<autofill::AutofillProfile>();
autofill::test::SetProfileInfo( autofill::test::SetProfileInfo(
profile_complete.get(), "Charlie", "", "West", "charlie.west@gmail.com", profile_complete.get(), "Charlie", "", "West", "charlie.west@gmail.com",
...@@ -81,19 +81,19 @@ TEST(UserDataUtilTest, SortsProfilesByCompleteness) { ...@@ -81,19 +81,19 @@ TEST(UserDataUtilTest, SortsProfilesByCompleteness) {
options.request_shipping = true; options.request_shipping = true;
std::vector<int> profile_indices = std::vector<int> profile_indices =
autofill_assistant::SortByCompleteness(options, profiles); autofill_assistant::SortContactsByCompleteness(options, profiles);
EXPECT_THAT(profile_indices, SizeIs(profiles.size())); EXPECT_THAT(profile_indices, SizeIs(profiles.size()));
EXPECT_THAT(profile_indices, ElementsAre(2, 1, 0)); EXPECT_THAT(profile_indices, ElementsAre(2, 1, 0));
} }
TEST(UserDataUtilTest, GetDefaultSelectionForEmptyProfiles) { TEST(UserDataUtilTest, GetDefaultContactSelectionForEmptyProfiles) {
std::vector<std::unique_ptr<autofill::AutofillProfile>> profiles; std::vector<std::unique_ptr<autofill::AutofillProfile>> profiles;
CollectUserDataOptions options; CollectUserDataOptions options;
EXPECT_THAT(GetDefaultProfile(options, profiles), -1); EXPECT_THAT(GetDefaultContactProfile(options, profiles), -1);
} }
TEST(UserDataUtilTest, GetDefaultSelectionForCompleteProfiles) { TEST(UserDataUtilTest, GetDefaultContactSelectionForCompleteProfiles) {
auto profile_b = std::make_unique<autofill::AutofillProfile>(); auto profile_b = std::make_unique<autofill::AutofillProfile>();
autofill::test::SetProfileInfo(profile_b.get(), "Berta", "", "West", autofill::test::SetProfileInfo(profile_b.get(), "Berta", "", "West",
"berta.west@gmail.com", "", "", "", "", "", "", "berta.west@gmail.com", "", "", "", "", "", "",
...@@ -113,7 +113,7 @@ TEST(UserDataUtilTest, GetDefaultSelectionForCompleteProfiles) { ...@@ -113,7 +113,7 @@ TEST(UserDataUtilTest, GetDefaultSelectionForCompleteProfiles) {
options.request_payer_name = true; options.request_payer_name = true;
options.request_payer_email = true; options.request_payer_email = true;
EXPECT_THAT(GetDefaultProfile(options, profiles), 1); EXPECT_THAT(GetDefaultContactProfile(options, profiles), 1);
} }
TEST(UserDataUtilTest, GetDefaultSelectionForDefaultEmail) { TEST(UserDataUtilTest, GetDefaultSelectionForDefaultEmail) {
...@@ -146,7 +146,89 @@ TEST(UserDataUtilTest, GetDefaultSelectionForDefaultEmail) { ...@@ -146,7 +146,89 @@ TEST(UserDataUtilTest, GetDefaultSelectionForDefaultEmail) {
options.request_payer_phone = true; options.request_payer_phone = true;
options.default_email = "adam.west@gmail.com"; options.default_email = "adam.west@gmail.com";
EXPECT_THAT(GetDefaultProfile(options, profiles), 2); EXPECT_THAT(GetDefaultContactProfile(options, profiles), 2);
}
TEST(UserDataUtilTest, SortsCompleteAddressesAlphabetically) {
auto profile_b = std::make_unique<autofill::AutofillProfile>();
autofill::test::SetProfileInfo(profile_b.get(), "Berta", "", "West", "", "",
"Brandschenkestrasse 110", "", "Zurich", "",
"8002", "CH", "");
auto profile_a = std::make_unique<autofill::AutofillProfile>();
autofill::test::SetProfileInfo(profile_a.get(), "Adam", "", "West", "", "",
"Brandschenkestrasse 110", "", "Zurich", "",
"8002", "CH", "");
// Specify profiles in reverse order to force sorting.
std::vector<std::unique_ptr<autofill::AutofillProfile>> profiles;
profiles.emplace_back(std::move(profile_b));
profiles.emplace_back(std::move(profile_a));
CollectUserDataOptions options;
std::vector<int> profile_indices =
autofill_assistant::SortAddressesByCompleteness(options, profiles);
EXPECT_THAT(profile_indices, SizeIs(profiles.size()));
EXPECT_THAT(profile_indices, ElementsAre(1, 0));
}
TEST(UserDataUtilTest, SortsAddressesByCompleteness) {
// Adding email address and phone number to demonstrate that they are not
// checked for completeness.
auto profile_no_street = std::make_unique<autofill::AutofillProfile>();
autofill::test::SetProfileInfo(profile_no_street.get(), "Adam", "", "West",
"adam.west@gmail.com", "", "", "", "Zurich",
"", "8002", "CH", "+41");
auto profile_complete = std::make_unique<autofill::AutofillProfile>();
autofill::test::SetProfileInfo(profile_complete.get(), "Berta", "", "West",
"", "", "Brandschenkestrasse 110", "",
"Zurich", "", "8002", "UK", "");
// Specify profiles in reverse order to force sorting.
std::vector<std::unique_ptr<autofill::AutofillProfile>> profiles;
profiles.emplace_back(std::move(profile_no_street));
profiles.emplace_back(std::move(profile_complete));
CollectUserDataOptions options;
std::vector<int> profile_indices =
autofill_assistant::SortAddressesByCompleteness(options, profiles);
EXPECT_THAT(profile_indices, SizeIs(profiles.size()));
EXPECT_THAT(profile_indices, ElementsAre(1, 0));
}
TEST(UserDataUtilTest, GetDefaultAddressSelectionForEmptyProfiles) {
std::vector<std::unique_ptr<autofill::AutofillProfile>> profiles;
CollectUserDataOptions options;
EXPECT_THAT(GetDefaultAddressProfile(options, profiles), -1);
}
TEST(UserDataUtilTest, GetDefaultAddressSelectionForCompleteProfiles) {
// Adding email address and phone number to demonstrate that they are not
// checked for completeness.
auto profile_with_irrelevant_details =
std::make_unique<autofill::AutofillProfile>();
autofill::test::SetProfileInfo(profile_with_irrelevant_details.get(), "Berta",
"berta.west@gmail.com", "West", "", "",
"Brandschenkestrasse 110", "", "Zurich", "",
"8002", "CH", "+41");
auto profile_complete = std::make_unique<autofill::AutofillProfile>();
autofill::test::SetProfileInfo(profile_complete.get(), "Adam", "", "West", "",
"", "Brandschenkestrasse 110", "", "Zurich",
"", "8002", "CH", "");
// Specify profiles in reverse order to force sorting.
std::vector<std::unique_ptr<autofill::AutofillProfile>> profiles;
profiles.emplace_back(std::move(profile_with_irrelevant_details));
profiles.emplace_back(std::move(profile_complete));
CollectUserDataOptions options;
EXPECT_THAT(GetDefaultAddressProfile(options, profiles), 1);
} }
TEST(UserDataUtilTest, SortsCreditCardsByCompleteness) { TEST(UserDataUtilTest, SortsCreditCardsByCompleteness) {
...@@ -172,7 +254,7 @@ TEST(UserDataUtilTest, SortsCreditCardsByCompleteness) { ...@@ -172,7 +254,7 @@ TEST(UserDataUtilTest, SortsCreditCardsByCompleteness) {
CollectUserDataOptions options; CollectUserDataOptions options;
std::vector<int> sorted_indices = std::vector<int> sorted_indices =
SortByCompleteness(options, payment_instruments); SortPaymentInstrumentsByCompleteness(options, payment_instruments);
EXPECT_THAT(sorted_indices, SizeIs(payment_instruments.size())); EXPECT_THAT(sorted_indices, SizeIs(payment_instruments.size()));
EXPECT_THAT(sorted_indices, ElementsAre(1, 0)); EXPECT_THAT(sorted_indices, ElementsAre(1, 0));
} }
...@@ -200,7 +282,7 @@ TEST(UserDataUtilTest, SortsCompleteCardsByName) { ...@@ -200,7 +282,7 @@ TEST(UserDataUtilTest, SortsCompleteCardsByName) {
CollectUserDataOptions options; CollectUserDataOptions options;
std::vector<int> sorted_indices = std::vector<int> sorted_indices =
SortByCompleteness(options, payment_instruments); SortPaymentInstrumentsByCompleteness(options, payment_instruments);
EXPECT_THAT(sorted_indices, SizeIs(payment_instruments.size())); EXPECT_THAT(sorted_indices, SizeIs(payment_instruments.size()));
EXPECT_THAT(sorted_indices, ElementsAre(1, 0)); EXPECT_THAT(sorted_indices, ElementsAre(1, 0));
} }
...@@ -253,7 +335,7 @@ TEST(UserDataUtilTest, SortsCreditCardsByAddressCompleteness) { ...@@ -253,7 +335,7 @@ TEST(UserDataUtilTest, SortsCreditCardsByAddressCompleteness) {
options.require_billing_postal_code = true; options.require_billing_postal_code = true;
std::vector<int> sorted_indices = std::vector<int> sorted_indices =
SortByCompleteness(options, payment_instruments); SortPaymentInstrumentsByCompleteness(options, payment_instruments);
EXPECT_THAT(sorted_indices, SizeIs(payment_instruments.size())); EXPECT_THAT(sorted_indices, SizeIs(payment_instruments.size()));
EXPECT_THAT(sorted_indices, ElementsAre(2, 1, 0)); EXPECT_THAT(sorted_indices, ElementsAre(2, 1, 0));
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment