Index: ui/android/java/src/org/chromium/ui/autofill/CardUnmaskPrompt.java |
diff --git a/ui/android/java/src/org/chromium/ui/autofill/CardUnmaskPrompt.java b/ui/android/java/src/org/chromium/ui/autofill/CardUnmaskPrompt.java |
index b2fd58da40fe2639bb8d4f4502cee8832c7737d1..500bb5501a758adf283dd901e80b07be7dde3072 100644 |
--- a/ui/android/java/src/org/chromium/ui/autofill/CardUnmaskPrompt.java |
+++ b/ui/android/java/src/org/chromium/ui/autofill/CardUnmaskPrompt.java |
@@ -13,19 +13,25 @@ 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 boolean mShouldRequestExpirationDate; |
/** |
* An interface to handle the interaction with an CardUnmaskPrompt object. |
@@ -46,17 +52,19 @@ 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, int iconId, 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); |
+ // TODO(estade): do something with iconId. |
+ |
mDialog = new AlertDialog.Builder(context) |
.setTitle(title) |
.setView(v) |
@@ -64,11 +72,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 +88,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(getCardUnmaskInput().getText().toString(), |
+ (String) getMonthSpinner().getSelectedItem(), |
+ (String) getYearSpinner().getSelectedItem()); |
} |
}); |
- final EditText input = cardUnmaskInput(); |
+ final EditText input = getCardUnmaskInput(); |
input.addTextChangedListener(this); |
input.post(new Runnable() { |
@Override |
public void run() { |
- showKeyboardForUnmaskInput(); |
+ setInitialFocus(); |
} |
}); |
} |
@@ -95,7 +109,10 @@ public class CardUnmaskPrompt implements DialogInterface.OnDismissListener, Text |
} |
public void disableAndWaitForVerification() { |
- cardUnmaskInput().setEnabled(false); |
+ getCardUnmaskInput().setEnabled(false); |
+ getMonthSpinner().setEnabled(false); |
+ getYearSpinner().setEnabled(false); |
+ |
mDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false); |
getVerificationProgressBar().setVisibility(View.VISIBLE); |
@@ -108,9 +125,10 @@ public class CardUnmaskPrompt implements DialogInterface.OnDismissListener, Text |
TextView message = getVerificationView(); |
message.setText("Verification failed. Please try again."); |
message.setVisibility(View.VISIBLE); |
- EditText input = cardUnmaskInput(); |
- input.setEnabled(true); |
- showKeyboardForUnmaskInput(); |
+ getCardUnmaskInput().setEnabled(true); |
+ getMonthSpinner().setEnabled(true); |
+ getYearSpinner().setEnabled(true); |
+ setInitialFocus(); |
// TODO(estade): UI decision - should we clear the input? |
newt (away)
2015/01/29 04:42:28
IMO, no. I'd leave the input so the user can see a
Evan Stade
2015/01/30 02:13:23
this is mostly a note to myself to check with ains
newt (away)
2015/01/30 16:29:00
I'm aware. Just providing another opinion in case
|
} else { |
mDialog.findViewById(R.id.verification_success).setVisibility(View.VISIBLE); |
@@ -130,8 +148,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(inputsAreValid()); |
} |
@Override |
@@ -140,13 +157,51 @@ public class CardUnmaskPrompt implements DialogInterface.OnDismissListener, Text |
@Override |
public void onTextChanged(CharSequence s, int start, int before, int count) {} |
- private void showKeyboardForUnmaskInput() { |
+ private void initializeExpirationDateSpinners() { |
+ ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>( |
newt (away)
2015/01/29 04:42:28
Reusing this variable makes the code a bit harder
Evan Stade
2015/01/30 02:13:23
Done.
|
+ mDialog.getContext(), android.R.layout.simple_spinner_item); |
+ |
+ // TODO(estade): i18n, or remove this entry, or something. |
+ adapter.add("MM"); |
newt (away)
2015/01/29 04:42:28
You could follow the UI design used in the autofil
Evan Stade
2015/01/30 02:13:24
I don't think that fits nicely into the mocks that
|
+ NumberFormat nf = NumberFormat.getInstance(); |
+ nf.setMinimumIntegerDigits(2); |
+ for (int month = 1; month <= 12; month++) { |
+ adapter.add(nf.format(month)); |
+ } |
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); |
+ getMonthSpinner().setAdapter(adapter); |
+ |
+ adapter = new ArrayAdapter<CharSequence>( |
+ mDialog.getContext(), android.R.layout.simple_spinner_item); |
+ adapter.add("YYYY"); |
+ Calendar calendar = Calendar.getInstance(); |
+ int initialYear = calendar.get(Calendar.YEAR); |
+ for (int year = initialYear; year < initialYear + 10; year++) { |
+ adapter.add(Integer.toString(year)); |
+ } |
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); |
+ getYearSpinner().setAdapter(adapter); |
+ |
+ getMonthSpinner().setVisibility(View.VISIBLE); |
+ getYearSpinner().setVisibility(View.VISIBLE); |
+ } |
+ |
+ private void setInitialFocus() { |
+ if (mShouldRequestExpirationDate) return; |
+ |
InputMethodManager imm = (InputMethodManager) mDialog.getContext().getSystemService( |
Context.INPUT_METHOD_SERVICE); |
- imm.showSoftInput(cardUnmaskInput(), InputMethodManager.SHOW_IMPLICIT); |
+ imm.showSoftInput(getCardUnmaskInput(), InputMethodManager.SHOW_IMPLICIT); |
+ } |
+ |
+ private boolean inputsAreValid() { |
newt (away)
2015/01/29 04:42:28
I'd call this "areInputsValid()". The current name
Evan Stade
2015/01/30 02:13:24
Done.
|
+ return mDelegate.checkUserInputValidity(getCardUnmaskInput().getText().toString()) |
newt (away)
2015/01/29 04:42:28
Maybe easier to read:
if (mShouldRequestExpir
Evan Stade
2015/01/30 02:13:24
not a huge fan of nested ifs in place of &&, but I
|
+ && (!mShouldRequestExpirationDate |
+ || (getMonthSpinner().getSelectedItemPosition() != 0 |
+ && getYearSpinner().getSelectedItemPosition() != 0)); |
} |
- private EditText cardUnmaskInput() { |
+ private EditText getCardUnmaskInput() { |
return (EditText) mDialog.findViewById(R.id.card_unmask_input); |
newt (away)
2015/01/29 04:42:28
A more typical pattern is have a member variable f
Evan Stade
2015/01/30 02:13:23
Done.
|
} |
@@ -157,4 +212,12 @@ public class CardUnmaskPrompt implements DialogInterface.OnDismissListener, Text |
private TextView getVerificationView() { |
return (TextView) mDialog.findViewById(R.id.verification_message); |
} |
+ |
+ private Spinner getMonthSpinner() { |
+ return (Spinner) mDialog.findViewById(R.id.expiration_month); |
+ } |
+ |
+ private Spinner getYearSpinner() { |
+ return (Spinner) mDialog.findViewById(R.id.expiration_year); |
+ } |
} |