| Index: chrome/android/java/src/org/chromium/chrome/browser/payments/CardEditor.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/CardEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/CardEditor.java
|
| index 7a312f97a36b5863b1ec9e3ff0d562f27bfef4a2..9408598c0b738b1fdd1af3e9e93050fdc4670844 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/CardEditor.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/CardEditor.java
|
| @@ -6,9 +6,13 @@ package org.chromium.chrome.browser.payments;
|
|
|
| import android.os.AsyncTask;
|
| import android.os.Handler;
|
| +import android.text.SpannableStringBuilder;
|
| import android.text.TextUtils;
|
| +import android.text.style.AbsoluteSizeSpan;
|
| +import android.text.style.ForegroundColorSpan;
|
| import android.util.Pair;
|
|
|
| +import org.chromium.base.ApiCompatibilityUtils;
|
| import org.chromium.base.Callback;
|
| import org.chromium.chrome.R;
|
| import org.chromium.chrome.browser.autofill.CreditCardScanner;
|
| @@ -27,6 +31,8 @@ import org.chromium.payments.mojom.PaymentMethodData;
|
| import java.text.SimpleDateFormat;
|
| import java.util.ArrayList;
|
| import java.util.Calendar;
|
| +import java.util.Collections;
|
| +import java.util.Comparator;
|
| import java.util.Date;
|
| import java.util.HashMap;
|
| import java.util.HashSet;
|
| @@ -93,6 +99,9 @@ public class CardEditor extends EditorBase<AutofillPaymentInstrument>
|
| */
|
| private final List<AutofillProfile> mProfilesForBillingAddress;
|
|
|
| + /** A map of GUIDs of the incomplete profiles to their edit required message resource Ids. */
|
| + private final Map<String, Integer> mIncompleteProfilesForBillingAddress;
|
| +
|
| /** Used for verifying billing address completeness and also editing billing addresses. */
|
| private final AddressEditor mAddressEditor;
|
|
|
| @@ -164,19 +173,33 @@ public class CardEditor extends EditorBase<AutofillPaymentInstrument>
|
| List<AutofillProfile> profiles =
|
| PersonalDataManager.getInstance().getBillingAddressesToSuggest();
|
| mProfilesForBillingAddress = new ArrayList<>();
|
| + mIncompleteProfilesForBillingAddress = new HashMap<>();
|
| for (int i = 0; i < profiles.size(); i++) {
|
| AutofillProfile profile = profiles.get(i);
|
| - // 1) Include only local profiles, because GUIDs of server profiles change on every
|
| - // browser restart. Server profiles are not supported as billing addresses.
|
| - // 2) Include only complete profiles, so that user launches the editor only when
|
| - // explicitly selecting [+ ADD ADDRESS] in the dropdown.
|
| - if (profile.getIsLocal()
|
| - && AutofillAddress.checkAddressCompletionStatus(profile)
|
| - == AutofillAddress.COMPLETE) {
|
| - mProfilesForBillingAddress.add(profile);
|
| + // Include only local profiles, because GUIDs of server profiles change on every browser
|
| + // restart. Server profiles are not supported as billing addresses.
|
| + if (!profile.getIsLocal()) continue;
|
| + mProfilesForBillingAddress.add(profile);
|
| + Pair<Integer, Integer> editMessageResIds = AutofillAddress.getEditMessageAndTitleResIds(
|
| + AutofillAddress.checkAddressCompletionStatus(profile));
|
| + if (editMessageResIds.first.intValue() != 0) {
|
| + mIncompleteProfilesForBillingAddress.put(
|
| + profile.getGUID(), editMessageResIds.first);
|
| }
|
| }
|
|
|
| + // Sort profiles for billing address according to completeness.
|
| + Collections.sort(mProfilesForBillingAddress, new Comparator<AutofillProfile>() {
|
| + @Override
|
| + public int compare(AutofillProfile a, AutofillProfile b) {
|
| + boolean isAComplete =
|
| + AutofillAddress.checkAddressCompletionStatus(a) == AutofillAddress.COMPLETE;
|
| + boolean isBComplete =
|
| + AutofillAddress.checkAddressCompletionStatus(b) == AutofillAddress.COMPLETE;
|
| + return (isBComplete ? 1 : 0) - (isAComplete ? 1 : 0);
|
| + }
|
| + });
|
| +
|
| mCardTypes = new HashMap<>();
|
| mCardTypes.put(AMEX, new CardTypeInfo(R.drawable.pr_amex, R.string.autofill_cc_amex));
|
| mCardTypes.put(
|
| @@ -380,14 +403,8 @@ public class CardEditor extends EditorBase<AutofillPaymentInstrument>
|
| }
|
| assert methodName != null;
|
|
|
| - AutofillProfile billingAddress = null;
|
| - for (int i = 0; i < mProfilesForBillingAddress.size(); ++i) {
|
| - if (TextUtils.equals(mProfilesForBillingAddress.get(i).getGUID(),
|
| - card.getBillingAddressId())) {
|
| - billingAddress = mProfilesForBillingAddress.get(i);
|
| - break;
|
| - }
|
| - }
|
| + AutofillProfile billingAddress =
|
| + findTargetProfile(mProfilesForBillingAddress, card.getBillingAddressId());
|
| assert billingAddress != null;
|
|
|
| instrument.completeInstrument(card, methodName, billingAddress);
|
| @@ -412,6 +429,7 @@ public class CardEditor extends EditorBase<AutofillPaymentInstrument>
|
| if (TextUtils.equals(mProfilesForBillingAddress.get(i).getGUID(),
|
| billingAddress.getIdentifier())) {
|
| mProfilesForBillingAddress.set(i, billingAddress.getProfile());
|
| + mIncompleteProfilesForBillingAddress.remove(billingAddress.getIdentifier());
|
| return;
|
| }
|
| }
|
| @@ -603,8 +621,31 @@ public class CardEditor extends EditorBase<AutofillPaymentInstrument>
|
| final List<DropdownKeyValue> billingAddresses = new ArrayList<>();
|
|
|
| for (int i = 0; i < mProfilesForBillingAddress.size(); ++i) {
|
| - billingAddresses.add(new DropdownKeyValue(mProfilesForBillingAddress.get(i).getGUID(),
|
| - mProfilesForBillingAddress.get(i).getLabel()));
|
| + AutofillProfile profile = mProfilesForBillingAddress.get(i);
|
| + SpannableStringBuilder builder = new SpannableStringBuilder(profile.getLabel());
|
| +
|
| + // Append the edit required message if the address is incomplete.
|
| + if (mIncompleteProfilesForBillingAddress.containsKey(profile.getGUID())) {
|
| + builder.append(mContext.getString(R.string.autofill_address_summary_separator));
|
| +
|
| + int startIndex = builder.length();
|
| + int editMessageResId =
|
| + mIncompleteProfilesForBillingAddress.get(profile.getGUID()).intValue();
|
| + String editMessage = mContext.getString(editMessageResId);
|
| + builder.append(editMessage);
|
| + int endIndex = builder.length();
|
| +
|
| + Object foregroundSpanner = new ForegroundColorSpan(ApiCompatibilityUtils.getColor(
|
| + mContext.getResources(), R.color.google_blue_700));
|
| + builder.setSpan(foregroundSpanner, startIndex, endIndex, 0);
|
| +
|
| + // The text size in the dropdown is 14dp.
|
| + Object sizeSpanner = new AbsoluteSizeSpan(14, true);
|
| + builder.setSpan(sizeSpanner, startIndex, endIndex, 0);
|
| + }
|
| +
|
| + billingAddresses.add(
|
| + new DropdownKeyValue(mProfilesForBillingAddress.get(i).getGUID(), builder));
|
| }
|
|
|
| billingAddresses.add(new DropdownKeyValue(BILLING_ADDRESS_ADD_NEW,
|
| @@ -623,19 +664,26 @@ public class CardEditor extends EditorBase<AutofillPaymentInstrument>
|
| mBillingAddressField.setDropdownCallback(new Callback<Pair<String, Runnable>>() {
|
| @Override
|
| public void onResult(final Pair<String, Runnable> eventData) {
|
| - if (!BILLING_ADDRESS_ADD_NEW.equals(eventData.first)) {
|
| + final boolean isAddingNewAddress = BILLING_ADDRESS_ADD_NEW.equals(eventData.first);
|
| + final boolean isSelectingIncompleteAddress =
|
| + mIncompleteProfilesForBillingAddress.containsKey(eventData.first);
|
| + if (!isAddingNewAddress && !isSelectingIncompleteAddress) {
|
| if (mObserverForTest != null) {
|
| mObserverForTest.onPaymentRequestServiceBillingAddressChangeProcessed();
|
| }
|
| return;
|
| }
|
|
|
| - mAddressEditor.edit(null, new Callback<AutofillAddress>() {
|
| + final AutofillAddress editAddress = isSelectingIncompleteAddress
|
| + ? new AutofillAddress(mContext,
|
| + findTargetProfile(mProfilesForBillingAddress, eventData.first))
|
| + : null;
|
| + mAddressEditor.edit(editAddress, new Callback<AutofillAddress>() {
|
| @Override
|
| public void onResult(AutofillAddress billingAddress) {
|
| - if (billingAddress == null) {
|
| - // User cancelled out of the "add flow". Restore the selection to the
|
| - // card's billing address, if any, else clear the selection.
|
| + if (billingAddress == null || !billingAddress.isComplete()) {
|
| + // User cancelled out of the add or edit flow. Restore the selection
|
| + // to the card's billing address, if any, else clear the selection.
|
| if (mBillingAddressField.getDropdownKeys().contains(
|
| card.getBillingAddressId())) {
|
| mBillingAddressField.setValue(card.getBillingAddressId());
|
| @@ -646,9 +694,25 @@ public class CardEditor extends EditorBase<AutofillPaymentInstrument>
|
| // Set the billing address label.
|
| billingAddress.setBillingAddressLabel();
|
|
|
| - // User has added a new complete address. Add it to the top of the
|
| - // dropdown.
|
| - mProfilesForBillingAddress.add(billingAddress.getProfile());
|
| + if (isSelectingIncompleteAddress) {
|
| + // User completed an incomplete address.
|
| + mIncompleteProfilesForBillingAddress.remove(
|
| + billingAddress.getProfile().getGUID());
|
| +
|
| + // Remove the old key-value from the dropdown.
|
| + for (int i = 0; i < billingAddresses.size(); i++) {
|
| + if (billingAddresses.get(i).first.equals(
|
| + billingAddress.getIdentifier())) {
|
| + billingAddresses.remove(i);
|
| + break;
|
| + }
|
| + }
|
| + } else {
|
| + // User added a new complete address.
|
| + mProfilesForBillingAddress.add(billingAddress.getProfile());
|
| + }
|
| +
|
| + // Add the newly added or edited address to the top of the dropdown.
|
| billingAddresses.add(
|
| 0, new DropdownKeyValue(billingAddress.getIdentifier(),
|
| billingAddress.getSublabel()));
|
| @@ -670,6 +734,14 @@ public class CardEditor extends EditorBase<AutofillPaymentInstrument>
|
| editor.addField(mBillingAddressField);
|
| }
|
|
|
| + private static AutofillProfile findTargetProfile(List<AutofillProfile> profiles, String guid) {
|
| + for (int i = 0; i < profiles.size(); i++) {
|
| + if (profiles.get(i).getGUID().equals(guid)) return profiles.get(i);
|
| + }
|
| + assert false : "Never reached.";
|
| + return null;
|
| + }
|
| +
|
| /** Adds the "save this card" checkbox to the editor. */
|
| private void addSaveCardCheckbox(EditorModel editor) {
|
| if (mSaveCardCheckbox == null) {
|
|
|