Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1138)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java

Issue 2722283004: [Payments] Fix focus bug in the expiration date CVC unmaskp prompt. (Closed)
Patch Set: Only record focus changes Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chrome.browser.autofill; 5 package org.chromium.chrome.browser.autofill;
6 6
7 import android.content.Context; 7 import android.content.Context;
8 import android.content.DialogInterface; 8 import android.content.DialogInterface;
9 import android.content.res.Resources; 9 import android.content.res.Resources;
10 import android.graphics.Color; 10 import android.graphics.Color;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 private int mThisYear; 76 private int mThisYear;
77 private int mThisMonth; 77 private int mThisMonth;
78 private boolean mValidationWaitsForCalendarTask; 78 private boolean mValidationWaitsForCalendarTask;
79 79
80 private String mCvcErrorMessage; 80 private String mCvcErrorMessage;
81 private String mExpirationMonthErrorMessage; 81 private String mExpirationMonthErrorMessage;
82 private String mExpirationYearErrorMessage; 82 private String mExpirationYearErrorMessage;
83 private String mExpirationDateErrorMessage; 83 private String mExpirationDateErrorMessage;
84 private String mCvcAndExpirationErrorMessage; 84 private String mCvcAndExpirationErrorMessage;
85 85
86 private boolean mStartedTypingMonth; 86 private boolean mDidFocusOnMonth;
87 private boolean mStartedTypingYear; 87 private boolean mDidFocusOnYear;
88 private boolean mStartedTypingCvc; 88 private boolean mDidFocusOnCvc;
89 89
90 private static final int EXPIRATION_FIELDS_LENGTH = 2; 90 private static final int EXPIRATION_FIELDS_LENGTH = 2;
91 91
92 public static final int ERROR_TYPE_EXPIRATION_MONTH = 1; 92 public static final int ERROR_TYPE_EXPIRATION_MONTH = 1;
93 public static final int ERROR_TYPE_EXPIRATION_YEAR = 2; 93 public static final int ERROR_TYPE_EXPIRATION_YEAR = 2;
94 public static final int ERROR_TYPE_EXPIRATION_DATE = 3; 94 public static final int ERROR_TYPE_EXPIRATION_DATE = 3;
95 public static final int ERROR_TYPE_CVC = 4; 95 public static final int ERROR_TYPE_CVC = 4;
96 public static final int ERROR_TYPE_CVC_AND_EXPIRATION = 5; 96 public static final int ERROR_TYPE_CVC_AND_EXPIRATION = 5;
97 public static final int ERROR_TYPE_NOT_ENOUGH_INFO = 6; 97 public static final int ERROR_TYPE_NOT_ENOUGH_INFO = 6;
98 public static final int ERROR_TYPE_NONE = 7; 98 public static final int ERROR_TYPE_NONE = 7;
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 197
198 mShouldRequestExpirationDate = shouldRequestExpirationDate; 198 mShouldRequestExpirationDate = shouldRequestExpirationDate;
199 mThisYear = -1; 199 mThisYear = -1;
200 mThisMonth = -1; 200 mThisMonth = -1;
201 if (mShouldRequestExpirationDate) new CalendarTask().execute(); 201 if (mShouldRequestExpirationDate) new CalendarTask().execute();
202 202
203 // Create the listeners to be notified when the user focuses out the inp ut fields. 203 // Create the listeners to be notified when the user focuses out the inp ut fields.
204 mCardUnmaskInput.setOnFocusChangeListener(new OnFocusChangeListener() { 204 mCardUnmaskInput.setOnFocusChangeListener(new OnFocusChangeListener() {
205 @Override 205 @Override
206 public void onFocusChange(View v, boolean hasFocus) { 206 public void onFocusChange(View v, boolean hasFocus) {
207 mDidFocusOnCvc = true;
207 validate(); 208 validate();
208 } 209 }
209 }); 210 });
210 mMonthInput.setOnFocusChangeListener(new OnFocusChangeListener() { 211 mMonthInput.setOnFocusChangeListener(new OnFocusChangeListener() {
211 @Override 212 @Override
212 public void onFocusChange(View v, boolean hasFocus) { 213 public void onFocusChange(View v, boolean hasFocus) {
214 mDidFocusOnMonth = true;
213 validate(); 215 validate();
214 } 216 }
215 }); 217 });
216 mYearInput.setOnFocusChangeListener(new OnFocusChangeListener() { 218 mYearInput.setOnFocusChangeListener(new OnFocusChangeListener() {
217 @Override 219 @Override
218 public void onFocusChange(View v, boolean hasFocus) { 220 public void onFocusChange(View v, boolean hasFocus) {
221 mDidFocusOnYear = true;
219 validate(); 222 validate();
220 } 223 }
221 }); 224 });
222 225
223 // Create the listeners to be notified when the user types into the inpu t fields.
224 mCardUnmaskInput.addTextChangedListener(new TextWatcher() {
225 @Override
226 public void afterTextChanged(Editable s) {}
227
228 @Override
229 public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
230
231 @Override
232 public void onTextChanged(CharSequence s, int start, int before, int count) {
233 mStartedTypingCvc = true;
234 }
235 });
236 mMonthInput.addTextChangedListener(new TextWatcher() {
237 @Override
238 public void afterTextChanged(Editable s) {}
239
240 @Override
241 public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
242
243 @Override
244 public void onTextChanged(CharSequence s, int start, int before, int count) {
245 mStartedTypingMonth = true;
246 }
247 });
248 mYearInput.addTextChangedListener(new TextWatcher() {
249 @Override
250 public void afterTextChanged(Editable s) {}
251
252 @Override
253 public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
254
255 @Override
256 public void onTextChanged(CharSequence s, int start, int before, int count) {
257 mStartedTypingYear = true;
258 }
259 });
260
261 // Load the error messages to show to the user. 226 // Load the error messages to show to the user.
262 Resources resources = context.getResources(); 227 Resources resources = context.getResources();
263 mCvcErrorMessage = 228 mCvcErrorMessage =
264 resources.getString(R.string.autofill_card_unmask_prompt_error_t ry_again_cvc); 229 resources.getString(R.string.autofill_card_unmask_prompt_error_t ry_again_cvc);
265 mExpirationMonthErrorMessage = resources.getString( 230 mExpirationMonthErrorMessage = resources.getString(
266 R.string.autofill_card_unmask_prompt_error_try_again_expiration_ month); 231 R.string.autofill_card_unmask_prompt_error_try_again_expiration_ month);
267 mExpirationYearErrorMessage = resources.getString( 232 mExpirationYearErrorMessage = resources.getString(
268 R.string.autofill_card_unmask_prompt_error_try_again_expiration_ year); 233 R.string.autofill_card_unmask_prompt_error_try_again_expiration_ year);
269 mExpirationDateErrorMessage = resources.getString( 234 mExpirationDateErrorMessage = resources.getString(
270 R.string.autofill_card_unmask_prompt_error_try_again_expiration_ date); 235 R.string.autofill_card_unmask_prompt_error_try_again_expiration_ date);
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 /** 465 /**
501 * Moves the focus to the next field based on the value of the fields and th e specified type of 466 * Moves the focus to the next field based on the value of the fields and th e specified type of
502 * error found for the unmask field(s). 467 * error found for the unmask field(s).
503 * 468 *
504 * @param errorType The type of error detected. 469 * @param errorType The type of error detected.
505 */ 470 */
506 private void moveFocus(@ErrorType int errorType) { 471 private void moveFocus(@ErrorType int errorType) {
507 if (errorType == ERROR_TYPE_NOT_ENOUGH_INFO) { 472 if (errorType == ERROR_TYPE_NOT_ENOUGH_INFO) {
508 if (mMonthInput.isFocused() 473 if (mMonthInput.isFocused()
509 && mMonthInput.getText().length() == EXPIRATION_FIELDS_LENGT H) { 474 && mMonthInput.getText().length() == EXPIRATION_FIELDS_LENGT H) {
510 mYearInput.requestFocus(); 475 // The user just finished typing in the month field and there ar e no validation
476 // errors.
477 if (mYearInput.getText().length() == EXPIRATION_FIELDS_LENGTH) {
478 // Year was already filled, move focus to CVC field.
479 mCardUnmaskInput.requestFocus();
480 mDidFocusOnCvc = true;
481 } else {
482 // Year was not filled, move focus there.
483 mYearInput.requestFocus();
484 mDidFocusOnYear = true;
485 }
511 } else if (mYearInput.isFocused() 486 } else if (mYearInput.isFocused()
512 && mYearInput.getText().length() == EXPIRATION_FIELDS_LENGTH ) { 487 && mYearInput.getText().length() == EXPIRATION_FIELDS_LENGTH ) {
488 // The user just finished typing in the year field and there are no validation
489 // errors. Move focus to CVC field.
513 mCardUnmaskInput.requestFocus(); 490 mCardUnmaskInput.requestFocus();
491 mDidFocusOnCvc = true;
514 } 492 }
515 } 493 }
516 } 494 }
517 495
518 /** 496 /**
519 * Shows (or removes) the appropriate error message and apply the error filt er to the 497 * Shows (or removes) the appropriate error message and apply the error filt er to the
520 * appropriate fields depending on the error type. 498 * appropriate fields depending on the error type.
521 * 499 *
522 * @param errorType The type of error detected. 500 * @param errorType The type of error detected.
523 */ 501 */
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 * @return The ErrorType value representing the type of error found for the unmask fields. 568 * @return The ErrorType value representing the type of error found for the unmask fields.
591 */ 569 */
592 @ErrorType private int getExpirationAndCvcErrorType() { 570 @ErrorType private int getExpirationAndCvcErrorType() {
593 @ErrorType int errorType = ERROR_TYPE_NONE; 571 @ErrorType int errorType = ERROR_TYPE_NONE;
594 572
595 if (mShouldRequestExpirationDate) errorType = getExpirationDateErrorType (); 573 if (mShouldRequestExpirationDate) errorType = getExpirationDateErrorType ();
596 574
597 // If the CVC is valid, return the error type determined so far. 575 // If the CVC is valid, return the error type determined so far.
598 if (isCvcValid()) return errorType; 576 if (isCvcValid()) return errorType;
599 577
600 if (mStartedTypingCvc && !mCardUnmaskInput.isFocused()) { 578 if (mDidFocusOnCvc && !mCardUnmaskInput.isFocused()) {
601 // The CVC is invalid and the user has typed in the CVC field, but i s not focused on it 579 // The CVC is invalid and the user has typed in the CVC field, but i s not focused on it
602 // now. Add the CVC error to the current error. 580 // now. Add the CVC error to the current error.
603 if (errorType == ERROR_TYPE_NONE || errorType == ERROR_TYPE_NOT_ENOU GH_INFO) { 581 if (errorType == ERROR_TYPE_NONE || errorType == ERROR_TYPE_NOT_ENOU GH_INFO) {
604 errorType = ERROR_TYPE_CVC; 582 errorType = ERROR_TYPE_CVC;
605 } else { 583 } else {
606 errorType = ERROR_TYPE_CVC_AND_EXPIRATION; 584 errorType = ERROR_TYPE_CVC_AND_EXPIRATION;
607 } 585 }
608 } else { 586 } else {
609 // The CVC is invalid but the user is not done with the field. 587 // The CVC is invalid but the user is not done with the field.
610 // If no other errors were detected, set that there is not enough in formation. 588 // If no other errors were detected, set that there is not enough in formation.
(...skipping 12 matching lines...) Expand all
623 */ 601 */
624 @ErrorType private int getExpirationDateErrorType() { 602 @ErrorType private int getExpirationDateErrorType() {
625 if (mThisYear == -1 || mThisMonth == -1) { 603 if (mThisYear == -1 || mThisMonth == -1) {
626 mValidationWaitsForCalendarTask = true; 604 mValidationWaitsForCalendarTask = true;
627 return ERROR_TYPE_NOT_ENOUGH_INFO; 605 return ERROR_TYPE_NOT_ENOUGH_INFO;
628 } 606 }
629 607
630 int month = getMonth(); 608 int month = getMonth();
631 if (month < 1 || month > 12) { 609 if (month < 1 || month > 12) {
632 if (mMonthInput.getText().length() == EXPIRATION_FIELDS_LENGTH 610 if (mMonthInput.getText().length() == EXPIRATION_FIELDS_LENGTH
633 || (!mMonthInput.isFocused() && mStartedTypingMonth)) { 611 || (!mMonthInput.isFocused() && mDidFocusOnMonth)) {
634 // mFinishedTypingMonth = true; 612 // mFinishedTypingMonth = true;
635 return ERROR_TYPE_EXPIRATION_MONTH; 613 return ERROR_TYPE_EXPIRATION_MONTH;
636 } 614 }
637 return ERROR_TYPE_NOT_ENOUGH_INFO; 615 return ERROR_TYPE_NOT_ENOUGH_INFO;
638 } 616 }
639 617
640 int year = getFourDigitYear(); 618 int year = getFourDigitYear();
641 if (year < mThisYear || year > mThisYear + 10) { 619 if (year < mThisYear || year > mThisYear + 10) {
642 if (mYearInput.getText().length() == EXPIRATION_FIELDS_LENGTH 620 if (mYearInput.getText().length() == EXPIRATION_FIELDS_LENGTH
643 || (!mYearInput.isFocused() && mStartedTypingYear)) { 621 || (!mYearInput.isFocused() && mDidFocusOnYear)) {
644 // mFinishedTypingYear = true; 622 // mFinishedTypingYear = true;
645 return ERROR_TYPE_EXPIRATION_YEAR; 623 return ERROR_TYPE_EXPIRATION_YEAR;
646 } 624 }
647 return ERROR_TYPE_NOT_ENOUGH_INFO; 625 return ERROR_TYPE_NOT_ENOUGH_INFO;
648 } 626 }
649 627
650 if (year == mThisYear && month < mThisMonth) { 628 if (year == mThisYear && month < mThisMonth) {
651 return ERROR_TYPE_EXPIRATION_DATE; 629 return ERROR_TYPE_EXPIRATION_DATE;
652 } 630 }
653 631
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 @VisibleForTesting 763 @VisibleForTesting
786 public AlertDialog getDialogForTest() { 764 public AlertDialog getDialogForTest() {
787 return mDialog; 765 return mDialog;
788 } 766 }
789 767
790 @VisibleForTesting 768 @VisibleForTesting
791 public String getErrorMessage() { 769 public String getErrorMessage() {
792 return mErrorMessage.getText().toString(); 770 return mErrorMessage.getText().toString();
793 } 771 }
794 } 772 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698