Commit 4c240bbb authored by estade's avatar estade Committed by Commit bot

Update Android card unmasking prompt for the expiration date case.

Also fix up some padding so the demo looks better

BUG=451654

Review URL: https://codereview.chromium.org/873313011

Cr-Commit-Position: refs/heads/master@{#313975}
parent a87e3a84
......@@ -22,7 +22,7 @@ public class CardUnmaskBridge implements CardUnmaskPromptDelegate {
private final CardUnmaskPrompt mCardUnmaskPrompt;
public CardUnmaskBridge(long nativeCardUnmaskPromptViewAndroid, String title,
String instructions, WindowAndroid windowAndroid) {
String instructions, boolean shouldRequestExpirationDate, WindowAndroid windowAndroid) {
mNativeCardUnmaskPromptViewAndroid = nativeCardUnmaskPromptViewAndroid;
Activity activity = windowAndroid.getActivity().get();
if (activity == null) {
......@@ -36,14 +36,16 @@ public class CardUnmaskBridge implements CardUnmaskPromptDelegate {
}
});
} else {
mCardUnmaskPrompt = new CardUnmaskPrompt(activity, this, title, instructions);
mCardUnmaskPrompt = new CardUnmaskPrompt(
activity, this, title, instructions, shouldRequestExpirationDate);
}
}
@CalledByNative
private static CardUnmaskBridge create(long nativeUnmaskPrompt, String title,
String instructions, WindowAndroid windowAndroid) {
return new CardUnmaskBridge(nativeUnmaskPrompt, title, instructions, windowAndroid);
String instructions, boolean shouldRequestExpirationDate, WindowAndroid windowAndroid) {
return new CardUnmaskBridge(nativeUnmaskPrompt, title, instructions,
shouldRequestExpirationDate, windowAndroid);
}
@Override
......@@ -57,8 +59,8 @@ public class CardUnmaskBridge implements CardUnmaskPromptDelegate {
}
@Override
public void onUserInput(String userResponse) {
nativeOnUserInput(mNativeCardUnmaskPromptViewAndroid, userResponse);
public void onUserInput(String cvc, String month, String year) {
nativeOnUserInput(mNativeCardUnmaskPromptViewAndroid, cvc, month, year);
}
/**
......@@ -97,5 +99,5 @@ public class CardUnmaskBridge implements CardUnmaskPromptDelegate {
private native boolean nativeCheckUserInputValidity(
long nativeCardUnmaskPromptViewAndroid, String userResponse);
private native void nativeOnUserInput(
long nativeCardUnmaskPromptViewAndroid, String userResponse);
long nativeCardUnmaskPromptViewAndroid, String cvc, String month, String year);
}
......@@ -43,7 +43,7 @@ void CardUnmaskPromptViewAndroid::Show() {
env, controller_->GetInstructionsMessage());
java_object_.Reset(Java_CardUnmaskBridge_create(
env, reinterpret_cast<intptr_t>(this), dialog_title.obj(),
instructions.obj(),
instructions.obj(), controller_->ShouldRequestExpirationDate(),
view_android->GetWindowAndroid()->GetJavaObject().obj()));
Java_CardUnmaskBridge_show(env, java_object_.obj());
......@@ -58,11 +58,13 @@ bool CardUnmaskPromptViewAndroid::CheckUserInputValidity(JNIEnv* env,
void CardUnmaskPromptViewAndroid::OnUserInput(JNIEnv* env,
jobject obj,
jstring response) {
jstring cvc,
jstring month,
jstring year) {
controller_->OnUnmaskResponse(
base::android::ConvertJavaStringToUTF16(env, response),
base::string16(),
base::string16());
base::android::ConvertJavaStringToUTF16(env, cvc),
base::android::ConvertJavaStringToUTF16(env, month),
base::android::ConvertJavaStringToUTF16(env, year));
}
void CardUnmaskPromptViewAndroid::PromptDismissed(JNIEnv* env, jobject obj) {
......
......@@ -21,7 +21,11 @@ class CardUnmaskPromptViewAndroid : public CardUnmaskPromptView {
void Show();
bool CheckUserInputValidity(JNIEnv* env, jobject obj, jstring response);
void OnUserInput(JNIEnv* env, jobject obj, jstring response);
void OnUserInput(JNIEnv* env,
jobject obj,
jstring cvc,
jstring month,
jstring year);
void PromptDismissed(JNIEnv* env, jobject obj);
// CardUnmaskPromptView implementation.
......
......@@ -62,8 +62,8 @@ content::WebContents* CardUnmaskPromptControllerImpl::GetWebContents() {
base::string16 CardUnmaskPromptControllerImpl::GetWindowTitle() const {
// TODO(estade): i18n.
if (ShouldRequestExpirationDate()) {
return base::ASCIIToUTF16("Update and verify your card ") +
card_.TypeAndLastFourDigits();
return base::ASCIIToUTF16("Update your card ") +
card_.TypeAndLastFourDigits();
}
return base::ASCIIToUTF16("Verify your card ") +
......
......@@ -14,11 +14,11 @@
android:id="@+id/instructions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:paddingBottom="5dp"
android:paddingTop="5dp"
android:textSize="16sp"
android:layout_marginStart="24dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="10dp"
android:gravity="start" />
<LinearLayout
......@@ -26,6 +26,21 @@
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- TODO(estade): add accessibility content descriptions. -->
<Spinner
android:id="@+id/expiration_month"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:visibility="gone" />
<Spinner
android:id="@+id/expiration_year"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:visibility="gone" />
<EditText
android:id="@+id/card_unmask_input"
android:inputType="number"
......
......@@ -13,19 +13,31 @@ import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
import org.chromium.ui.R;
import java.text.NumberFormat;
import java.util.Calendar;
/**
* A prompt that bugs users to enter their CVC when unmasking a Wallet instrument (credit card).
*/
public class CardUnmaskPrompt implements DialogInterface.OnDismissListener, TextWatcher {
private CardUnmaskPromptDelegate mDelegate;
private AlertDialog mDialog;
private final CardUnmaskPromptDelegate mDelegate;
private final AlertDialog mDialog;
private final boolean mShouldRequestExpirationDate;
private final EditText mCardUnmaskInput;
private final Spinner mMonthSpinner;
private final Spinner mYearSpinner;
private final ProgressBar mVerificationProgressBar;
private final TextView mVerificationView;
/**
* An interface to handle the interaction with an CardUnmaskPrompt object.
......@@ -46,17 +58,23 @@ public class CardUnmaskPrompt implements DialogInterface.OnDismissListener, Text
* @param userResponse The value the user entered (a CVC), or an empty string if the
* user canceled.
*/
void onUserInput(String userResponse);
void onUserInput(String cvc, String month, String year);
}
public CardUnmaskPrompt(
Context context, CardUnmaskPromptDelegate delegate, String title, String instructions) {
public CardUnmaskPrompt(Context context, CardUnmaskPromptDelegate delegate, String title,
String instructions, boolean shouldRequestExpirationDate) {
mDelegate = delegate;
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(R.layout.autofill_card_unmask_prompt, null);
((TextView) v.findViewById(R.id.instructions)).setText(instructions);
mCardUnmaskInput = (EditText) v.findViewById(R.id.card_unmask_input);
mMonthSpinner = (Spinner) v.findViewById(R.id.expiration_month);
mYearSpinner = (Spinner) v.findViewById(R.id.expiration_year);
mVerificationProgressBar = (ProgressBar) v.findViewById(R.id.verification_progress_bar);
mVerificationView = (TextView) v.findViewById(R.id.verification_message);
mDialog = new AlertDialog.Builder(context)
.setTitle(title)
.setView(v)
......@@ -64,11 +82,15 @@ public class CardUnmaskPrompt implements DialogInterface.OnDismissListener, Text
.setPositiveButton(R.string.card_unmask_confirm_button, null)
.setOnDismissListener(this)
.create();
mShouldRequestExpirationDate = shouldRequestExpirationDate;
}
public void show() {
mDialog.show();
if (mShouldRequestExpirationDate) initializeExpirationDateSpinners();
// Override the View.OnClickListener so that pressing the positive button doesn't dismiss
// the dialog.
Button verifyButton = mDialog.getButton(AlertDialog.BUTTON_POSITIVE);
......@@ -76,16 +98,18 @@ public class CardUnmaskPrompt implements DialogInterface.OnDismissListener, Text
verifyButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mDelegate.onUserInput(cardUnmaskInput().getText().toString());
mDelegate.onUserInput(mCardUnmaskInput.getText().toString(),
(String) mMonthSpinner.getSelectedItem(),
(String) mYearSpinner.getSelectedItem());
}
});
final EditText input = cardUnmaskInput();
final EditText input = mCardUnmaskInput;
input.addTextChangedListener(this);
input.post(new Runnable() {
@Override
public void run() {
showKeyboardForUnmaskInput();
setInitialFocus();
}
});
}
......@@ -95,22 +119,26 @@ public class CardUnmaskPrompt implements DialogInterface.OnDismissListener, Text
}
public void disableAndWaitForVerification() {
cardUnmaskInput().setEnabled(false);
mCardUnmaskInput.setEnabled(false);
mMonthSpinner.setEnabled(false);
mYearSpinner.setEnabled(false);
mDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
getVerificationProgressBar().setVisibility(View.VISIBLE);
getVerificationView().setVisibility(View.GONE);
mVerificationProgressBar.setVisibility(View.VISIBLE);
mVerificationView.setVisibility(View.GONE);
}
public void verificationFinished(boolean success) {
getVerificationProgressBar().setVisibility(View.GONE);
mVerificationProgressBar.setVisibility(View.GONE);
if (!success) {
TextView message = getVerificationView();
TextView message = mVerificationView;
message.setText("Verification failed. Please try again.");
message.setVisibility(View.VISIBLE);
EditText input = cardUnmaskInput();
input.setEnabled(true);
showKeyboardForUnmaskInput();
mCardUnmaskInput.setEnabled(true);
mMonthSpinner.setEnabled(true);
mYearSpinner.setEnabled(true);
setInitialFocus();
// TODO(estade): UI decision - should we clear the input?
} else {
mDialog.findViewById(R.id.verification_success).setVisibility(View.VISIBLE);
......@@ -130,8 +158,7 @@ public class CardUnmaskPrompt implements DialogInterface.OnDismissListener, Text
@Override
public void afterTextChanged(Editable s) {
boolean valid = mDelegate.checkUserInputValidity(cardUnmaskInput().getText().toString());
mDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(valid);
mDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(areInputsValid());
}
@Override
......@@ -140,21 +167,49 @@ public class CardUnmaskPrompt implements DialogInterface.OnDismissListener, Text
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
private void showKeyboardForUnmaskInput() {
InputMethodManager imm = (InputMethodManager) mDialog.getContext().getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(cardUnmaskInput(), InputMethodManager.SHOW_IMPLICIT);
}
private void initializeExpirationDateSpinners() {
ArrayAdapter<CharSequence> monthAdapter = new ArrayAdapter<CharSequence>(
mDialog.getContext(), android.R.layout.simple_spinner_item);
// TODO(estade): i18n, or remove this entry, or something.
monthAdapter.add("MM");
NumberFormat nf = NumberFormat.getInstance();
nf.setMinimumIntegerDigits(2);
for (int month = 1; month <= 12; month++) {
monthAdapter.add(nf.format(month));
}
monthAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mMonthSpinner.setAdapter(monthAdapter);
ArrayAdapter<CharSequence> yearAdapter = new ArrayAdapter<CharSequence>(
mDialog.getContext(), android.R.layout.simple_spinner_item);
yearAdapter.add("YYYY");
Calendar calendar = Calendar.getInstance();
int initialYear = calendar.get(Calendar.YEAR);
for (int year = initialYear; year < initialYear + 10; year++) {
yearAdapter.add(Integer.toString(year));
}
yearAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mYearSpinner.setAdapter(yearAdapter);
private EditText cardUnmaskInput() {
return (EditText) mDialog.findViewById(R.id.card_unmask_input);
mMonthSpinner.setVisibility(View.VISIBLE);
mYearSpinner.setVisibility(View.VISIBLE);
}
private ProgressBar getVerificationProgressBar() {
return (ProgressBar) mDialog.findViewById(R.id.verification_progress_bar);
private void setInitialFocus() {
if (mShouldRequestExpirationDate) return;
InputMethodManager imm = (InputMethodManager) mDialog.getContext().getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(mCardUnmaskInput, InputMethodManager.SHOW_IMPLICIT);
}
private TextView getVerificationView() {
return (TextView) mDialog.findViewById(R.id.verification_message);
private boolean areInputsValid() {
if (mShouldRequestExpirationDate
&& (mMonthSpinner.getSelectedItemPosition() == 0
|| mYearSpinner.getSelectedItemPosition() == 0)) {
return false;
}
return mDelegate.checkUserInputValidity(mCardUnmaskInput.getText().toString());
}
}
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