Commit 6225da69 authored by gogerald's avatar gogerald Committed by Commit bot

Auto-advance to next field after typing in valid credit card with maximum digits

BUG=666885

Review-Url: https://codereview.chromium.org/2585453002
Cr-Commit-Position: refs/heads/master@{#439173}
parent 09e3482e
......@@ -308,6 +308,11 @@ public class AddressEditor extends EditorBase<AutofillAddress> {
&& PhoneNumberUtils.isGlobalPhoneNumber(
PhoneNumberUtils.stripSeparators(value.toString()));
}
@Override
public boolean isLengthMaximum(@Nullable CharSequence value) {
return false;
}
};
}
return mPhoneValidator;
......
......@@ -67,6 +67,16 @@ public class CardEditor extends EditorBase<AutofillPaymentInstrument>
}
}
/** The support credit card names. */
private static final String AMEX = "amex";
private static final String DINERS = "diners";
private static final String DISCOVER = "discover";
private static final String JCB = "jcb";
private static final String MASTERCARD = "mastercard";
private static final String MIR = "mir";
private static final String UNIONPAY = "unionpay";
private static final String VISA = "visa";
/** The dropdown key that triggers the address editor to add a new billing address. */
private static final String BILLING_ADDRESS_ADD_NEW = "add";
......@@ -161,22 +171,18 @@ public class CardEditor extends EditorBase<AutofillPaymentInstrument>
}
mCardTypes = new HashMap<>();
mCardTypes.put("amex",
new CardTypeInfo(R.drawable.pr_amex, R.string.autofill_cc_amex));
mCardTypes.put("diners",
new CardTypeInfo(R.drawable.pr_dinersclub, R.string.autofill_cc_diners));
mCardTypes.put("discover",
new CardTypeInfo(R.drawable.pr_discover, R.string.autofill_cc_discover));
mCardTypes.put("jcb",
new CardTypeInfo(R.drawable.pr_jcb, R.string.autofill_cc_jcb));
mCardTypes.put("mastercard",
new CardTypeInfo(R.drawable.pr_mc, R.string.autofill_cc_mastercard));
mCardTypes.put("mir",
new CardTypeInfo(R.drawable.pr_mir, R.string.autofill_cc_mir));
mCardTypes.put("unionpay",
new CardTypeInfo(R.drawable.pr_unionpay, R.string.autofill_cc_union_pay));
mCardTypes.put("visa",
new CardTypeInfo(R.drawable.pr_visa, R.string.autofill_cc_visa));
mCardTypes.put(AMEX, new CardTypeInfo(R.drawable.pr_amex, R.string.autofill_cc_amex));
mCardTypes.put(
DINERS, new CardTypeInfo(R.drawable.pr_dinersclub, R.string.autofill_cc_diners));
mCardTypes.put(
DISCOVER, new CardTypeInfo(R.drawable.pr_discover, R.string.autofill_cc_discover));
mCardTypes.put(JCB, new CardTypeInfo(R.drawable.pr_jcb, R.string.autofill_cc_jcb));
mCardTypes.put(
MASTERCARD, new CardTypeInfo(R.drawable.pr_mc, R.string.autofill_cc_mastercard));
mCardTypes.put(MIR, new CardTypeInfo(R.drawable.pr_mir, R.string.autofill_cc_mir));
mCardTypes.put(
UNIONPAY, new CardTypeInfo(R.drawable.pr_unionpay, R.string.autofill_cc_union_pay));
mCardTypes.put(VISA, new CardTypeInfo(R.drawable.pr_visa, R.string.autofill_cc_visa));
mAcceptedCardTypes = new HashSet<>();
mAcceptedCardTypeInfos = new ArrayList<>();
......@@ -190,6 +196,11 @@ public class CardEditor extends EditorBase<AutofillPaymentInstrument>
PersonalDataManager.getInstance().getBasicCardPaymentType(
value.toString(), true));
}
@Override
public boolean isLengthMaximum(@Nullable CharSequence value) {
return isCardNumberLengthMaximum(value);
}
};
mCardIconGenerator = new EditorValueIconGenerator() {
......@@ -213,6 +224,32 @@ public class CardEditor extends EditorBase<AutofillPaymentInstrument>
mCalendar.execute();
}
private boolean isCardNumberLengthMaximum(@Nullable CharSequence value) {
if (TextUtils.isEmpty(value)) return false;
String cardType =
PersonalDataManager.getInstance().getBasicCardPaymentType(value.toString(), false);
if (TextUtils.isEmpty(cardType)) return false;
// Below maximum values are consistent with the values used to check the validity of the
// credit card number in autofill::IsValidCreditCardNumber.
String cardNumber = removeSpaceAndBar(value);
switch (cardType) {
case AMEX:
return cardNumber.length() == 15;
case DINERS:
return cardNumber.length() == 14;
case UNIONPAY:
return cardNumber.length() == 19;
default:
// Valid DISCOVER, JCB, MASTERCARD, MIR and VISA cards have at most 16 digits.
return cardNumber.length() == 16;
}
}
private static String removeSpaceAndBar(CharSequence value) {
return value.toString().replace(" ", "").replace("-", "");
}
/**
* Adds accepted payment methods to the editor, if they are recognized credit card types.
*
......@@ -430,6 +467,11 @@ public class CardEditor extends EditorBase<AutofillPaymentInstrument>
return year > mCurrentYear
|| (year == mCurrentYear && month >= mCurrentMonth);
}
@Override
public boolean isLengthMaximum(@Nullable CharSequence value) {
return false;
}
};
}
......@@ -612,7 +654,7 @@ public class CardEditor extends EditorBase<AutofillPaymentInstrument>
return;
}
card.setNumber(mNumberField.getValue().toString().replace(" ", "").replace("-", ""));
card.setNumber(removeSpaceAndBar(mNumberField.getValue()));
card.setName(mNameField.getValue().toString());
card.setMonth(mMonthField.getValue().toString());
card.setYear(mYearField.getValue().toString());
......
......@@ -227,6 +227,11 @@ public class ContactEditor extends EditorBase<AutofillContact> {
&& PhoneNumberUtils.isGlobalPhoneNumber(
PhoneNumberUtils.stripSeparators(value.toString()));
}
@Override
public boolean isLengthMaximum(@Nullable CharSequence value) {
return false;
}
};
}
return mPhoneValidator;
......@@ -239,6 +244,11 @@ public class ContactEditor extends EditorBase<AutofillContact> {
public boolean isValid(@Nullable CharSequence value) {
return value != null && Patterns.EMAIL_ADDRESS.matcher(value).matches();
}
@Override
public boolean isLengthMaximum(@Nullable CharSequence value) {
return false;
}
};
}
return mEmailValidator;
......
......@@ -34,6 +34,15 @@ public class EditorFieldModel {
* @return True if the value is valid.
*/
boolean isValid(@Nullable CharSequence value);
/**
* Called to check whehter the length of the field value is maximum.
*
* @param value The value of the field to check.
* @return True if the field value length is maximum among all the possible valid values in
* this field.
*/
boolean isLengthMaximum(@Nullable CharSequence value);
}
/**
......@@ -498,6 +507,16 @@ public class EditorFieldModel {
return true;
}
/**
* Returns true if the field value length is maximum among all the possible valid values in this
* field.
*
* @Return Whether the field value length is maximum.
*/
public boolean isLengthMaximum() {
return mValidator == null ? false : mValidator.isLengthMaximum(mValue);
}
/**
* Sets the dropdown callback.
*
......
......@@ -9,10 +9,12 @@ import android.text.Editable;
import android.text.InputFilter;
import android.text.InputType;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.inputmethod.EditorInfo;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.FrameLayout;
......@@ -32,6 +34,7 @@ import javax.annotation.Nullable;
@VisibleForTesting
public class EditorTextField extends FrameLayout implements EditorFieldView, View.OnClickListener {
private EditorFieldModel mEditorFieldModel;
private OnEditorActionListener mEditorActionListener;
private CompatibilityTextInputLayout mInputLayout;
private AutoCompleteTextView mInput;
private View mIconsLayer;
......@@ -42,11 +45,12 @@ public class EditorTextField extends FrameLayout implements EditorFieldView, Vie
@Nullable private PaymentRequestObserverForTest mObserverForTest;
public EditorTextField(Context context, final EditorFieldModel fieldModel,
OnEditorActionListener actionlistener, @Nullable InputFilter filter,
OnEditorActionListener actionListener, @Nullable InputFilter filter,
@Nullable TextWatcher formatter, @Nullable PaymentRequestObserverForTest observer) {
super(context);
assert fieldModel.getInputTypeHint() != EditorFieldModel.INPUT_TYPE_HINT_DROPDOWN;
mEditorFieldModel = fieldModel;
mEditorActionListener = actionListener;
mObserverForTest = observer;
LayoutInflater.from(context).inflate(R.layout.payments_request_editor_textview, this, true);
......@@ -60,7 +64,7 @@ public class EditorTextField extends FrameLayout implements EditorFieldView, Vie
mInput = (AutoCompleteTextView) mInputLayout.findViewById(R.id.text_view);
mInput.setText(fieldModel.getValue());
mInput.setContentDescription(label);
mInput.setOnEditorActionListener(actionlistener);
mInput.setOnEditorActionListener(mEditorActionListener);
mIconsLayer = findViewById(R.id.icons_layer);
mIconsLayer.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
......@@ -114,6 +118,13 @@ public class EditorTextField extends FrameLayout implements EditorFieldView, Vie
if (mObserverForTest != null) {
mObserverForTest.onPaymentRequestEditorTextUpdate();
}
if (!mEditorFieldModel.isLengthMaximum()) return;
updateDisplayedError(true);
if (isValid()) {
// Simulate editor action to select next selectable field.
mEditorActionListener.onEditorAction(mInput, EditorInfo.IME_ACTION_NEXT,
new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER));
}
}
@Override
......
......@@ -43,6 +43,7 @@ bool IsValidCreditCardNumber(const base::string16& text) {
// defined sizes.
// [1] http://www.merriampark.com/anatomycc.htm
// [2] http://en.wikipedia.org/wiki/Bank_card_number
// CardEditor.isCardNumberLengthMaxium() needs to be kept in sync.
const char* const type = CreditCard::GetCreditCardType(text);
if (type == kAmericanExpressCard && number.size() != 15)
return false;
......
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