Commit 09bb8534 authored by estade's avatar estade Committed by Commit bot

Autofill - show expiration date in CVC prompt when card is expired. (Views)

BUG=451654

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

Cr-Commit-Position: refs/heads/master@{#313186}
parent 59114f60
...@@ -60,7 +60,9 @@ void CardUnmaskPromptViewAndroid::OnUserInput(JNIEnv* env, ...@@ -60,7 +60,9 @@ void CardUnmaskPromptViewAndroid::OnUserInput(JNIEnv* env,
jobject obj, jobject obj,
jstring response) { jstring response) {
controller_->OnUnmaskResponse( controller_->OnUnmaskResponse(
base::android::ConvertJavaStringToUTF16(env, response)); base::android::ConvertJavaStringToUTF16(env, response),
base::string16(),
base::string16());
} }
void CardUnmaskPromptViewAndroid::PromptDismissed(JNIEnv* env, jobject obj) { void CardUnmaskPromptViewAndroid::PromptDismissed(JNIEnv* env, jobject obj) {
......
...@@ -17,7 +17,9 @@ class CardUnmaskPromptController { ...@@ -17,7 +17,9 @@ class CardUnmaskPromptController {
public: public:
// Interaction. // Interaction.
virtual void OnUnmaskDialogClosed() = 0; virtual void OnUnmaskDialogClosed() = 0;
virtual void OnUnmaskResponse(const base::string16& cvc) = 0; virtual void OnUnmaskResponse(const base::string16& cvc,
const base::string16& exp_month,
const base::string16& exp_year) = 0;
// State. // State.
virtual content::WebContents* GetWebContents() = 0; virtual content::WebContents* GetWebContents() = 0;
......
...@@ -48,9 +48,11 @@ void CardUnmaskPromptControllerImpl::OnUnmaskDialogClosed() { ...@@ -48,9 +48,11 @@ void CardUnmaskPromptControllerImpl::OnUnmaskDialogClosed() {
} }
void CardUnmaskPromptControllerImpl::OnUnmaskResponse( void CardUnmaskPromptControllerImpl::OnUnmaskResponse(
const base::string16& cvc) { const base::string16& cvc,
const base::string16& exp_month,
const base::string16& exp_year) {
card_unmask_view_->DisableAndWaitForVerification(); card_unmask_view_->DisableAndWaitForVerification();
delegate_->OnUnmaskResponse(cvc); delegate_->OnUnmaskResponse(cvc, exp_month, exp_year);
} }
content::WebContents* CardUnmaskPromptControllerImpl::GetWebContents() { content::WebContents* CardUnmaskPromptControllerImpl::GetWebContents() {
...@@ -59,7 +61,7 @@ content::WebContents* CardUnmaskPromptControllerImpl::GetWebContents() { ...@@ -59,7 +61,7 @@ content::WebContents* CardUnmaskPromptControllerImpl::GetWebContents() {
base::string16 CardUnmaskPromptControllerImpl::GetWindowTitle() const { base::string16 CardUnmaskPromptControllerImpl::GetWindowTitle() const {
// TODO(estade): i18n. // TODO(estade): i18n.
if (card_.GetServerStatus() == CreditCard::EXPIRED) { if (ShouldRequestExpirationDate()) {
return base::ASCIIToUTF16("Update and verify your card ") + return base::ASCIIToUTF16("Update and verify your card ") +
card_.TypeAndLastFourDigits(); card_.TypeAndLastFourDigits();
} }
...@@ -69,7 +71,7 @@ base::string16 CardUnmaskPromptControllerImpl::GetWindowTitle() const { ...@@ -69,7 +71,7 @@ base::string16 CardUnmaskPromptControllerImpl::GetWindowTitle() const {
} }
base::string16 CardUnmaskPromptControllerImpl::GetInstructionsMessage() const { base::string16 CardUnmaskPromptControllerImpl::GetInstructionsMessage() const {
if (card_.GetServerStatus() == CreditCard::EXPIRED) { if (ShouldRequestExpirationDate()) {
return l10n_util::GetStringUTF16( return l10n_util::GetStringUTF16(
card_.type() == kAmericanExpressCard card_.type() == kAmericanExpressCard
? IDS_AUTOFILL_CARD_UNMASK_PROMPT_INSTRUCTIONS_EXPIRED_AMEX ? IDS_AUTOFILL_CARD_UNMASK_PROMPT_INSTRUCTIONS_EXPIRED_AMEX
......
...@@ -27,7 +27,10 @@ class CardUnmaskPromptControllerImpl : public CardUnmaskPromptController { ...@@ -27,7 +27,10 @@ class CardUnmaskPromptControllerImpl : public CardUnmaskPromptController {
// CardUnmaskPromptController implementation. // CardUnmaskPromptController implementation.
void OnUnmaskDialogClosed() override; void OnUnmaskDialogClosed() override;
void OnUnmaskResponse(const base::string16& cvc) override; void OnUnmaskResponse(const base::string16& cvc,
const base::string16& exp_month,
const base::string16& exp_year) override;
content::WebContents* GetWebContents() override; content::WebContents* GetWebContents() override;
base::string16 GetWindowTitle() const override; base::string16 GetWindowTitle() const override;
base::string16 GetInstructionsMessage() const override; base::string16 GetInstructionsMessage() const override;
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/autofill/autofill_dialog_models.h"
#include "chrome/browser/ui/autofill/card_unmask_prompt_controller.h" #include "chrome/browser/ui/autofill/card_unmask_prompt_controller.h"
#include "chrome/browser/ui/autofill/card_unmask_prompt_view.h" #include "chrome/browser/ui/autofill/card_unmask_prompt_view.h"
#include "chrome/grit/generated_resources.h" #include "chrome/grit/generated_resources.h"
...@@ -11,6 +12,8 @@ ...@@ -11,6 +12,8 @@
#include "grit/theme_resources.h" #include "grit/theme_resources.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_bundle.h"
#include "ui/views/controls/combobox/combobox.h"
#include "ui/views/controls/combobox/combobox_listener.h"
#include "ui/views/controls/image_view.h" #include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h" #include "ui/views/controls/label.h"
#include "ui/views/controls/textfield/textfield.h" #include "ui/views/controls/textfield/textfield.h"
...@@ -25,11 +28,16 @@ namespace autofill { ...@@ -25,11 +28,16 @@ namespace autofill {
namespace { namespace {
class CardUnmaskPromptViews : public CardUnmaskPromptView, class CardUnmaskPromptViews : public CardUnmaskPromptView,
views::ComboboxListener,
views::DialogDelegateView, views::DialogDelegateView,
views::TextfieldController { views::TextfieldController {
public: public:
explicit CardUnmaskPromptViews(CardUnmaskPromptController* controller) explicit CardUnmaskPromptViews(CardUnmaskPromptController* controller)
: controller_(controller), cvc_input_(nullptr), message_label_(nullptr) {} : controller_(controller),
cvc_input_(nullptr),
month_input_(nullptr),
year_input_(nullptr),
message_label_(nullptr) {}
~CardUnmaskPromptViews() override { ~CardUnmaskPromptViews() override {
if (controller_) if (controller_)
...@@ -48,7 +56,7 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView, ...@@ -48,7 +56,7 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
} }
void DisableAndWaitForVerification() override { void DisableAndWaitForVerification() override {
cvc_input_->SetEnabled(false); SetInputsEnabled(false);
message_label_->SetText(base::ASCIIToUTF16("Verifying...")); message_label_->SetText(base::ASCIIToUTF16("Verifying..."));
message_label_->SetVisible(true); message_label_->SetVisible(true);
GetDialogClientView()->UpdateDialogButtons(); GetDialogClientView()->UpdateDialogButtons();
...@@ -63,13 +71,22 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView, ...@@ -63,13 +71,22 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
base::Unretained(this)), base::Unretained(this)),
base::TimeDelta::FromSeconds(1)); base::TimeDelta::FromSeconds(1));
} else { } else {
cvc_input_->SetEnabled(true); SetInputsEnabled(true);
message_label_->SetText(base::ASCIIToUTF16("Verification error.")); message_label_->SetText(base::ASCIIToUTF16("Verification error."));
GetDialogClientView()->UpdateDialogButtons(); GetDialogClientView()->UpdateDialogButtons();
} }
Layout(); Layout();
} }
void SetInputsEnabled(bool enabled) {
cvc_input_->SetEnabled(enabled);
if (month_input_)
month_input_->SetEnabled(enabled);
if (year_input_)
year_input_->SetEnabled(enabled);
}
// views::DialogDelegateView // views::DialogDelegateView
View* GetContentsView() override { View* GetContentsView() override {
InitIfNecessary(); InitIfNecessary();
...@@ -114,7 +131,13 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView, ...@@ -114,7 +131,13 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
DCHECK_EQ(ui::DIALOG_BUTTON_OK, button); DCHECK_EQ(ui::DIALOG_BUTTON_OK, button);
return cvc_input_->enabled() && return cvc_input_->enabled() &&
controller_->InputTextIsValid(cvc_input_->text()); controller_->InputTextIsValid(cvc_input_->text()) &&
(!month_input_ ||
month_input_->selected_index() !=
month_combobox_model_.GetDefaultIndex()) &&
(!year_input_ ||
year_input_->selected_index() !=
year_combobox_model_.GetDefaultIndex());
} }
views::View* GetInitiallyFocusedView() override { return cvc_input_; } views::View* GetInitiallyFocusedView() override { return cvc_input_; }
...@@ -127,7 +150,14 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView, ...@@ -127,7 +150,14 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
if (!controller_) if (!controller_)
return true; return true;
controller_->OnUnmaskResponse(cvc_input_->text()); controller_->OnUnmaskResponse(
cvc_input_->text(),
month_input_
? month_combobox_model_.GetItemAt(month_input_->selected_index())
: base::string16(),
year_input_
? year_combobox_model_.GetItemAt(year_input_->selected_index())
: base::string16());
return false; return false;
} }
...@@ -137,6 +167,11 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView, ...@@ -137,6 +167,11 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
GetDialogClientView()->UpdateDialogButtons(); GetDialogClientView()->UpdateDialogButtons();
} }
// views::ComboboxListener
void OnPerformAction(views::Combobox* combobox) override {
GetDialogClientView()->UpdateDialogButtons();
}
private: private:
void InitIfNecessary() { void InitIfNecessary() {
if (has_children()) if (has_children())
...@@ -151,27 +186,36 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView, ...@@ -151,27 +186,36 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
instructions->SetHorizontalAlignment(gfx::ALIGN_LEFT); instructions->SetHorizontalAlignment(gfx::ALIGN_LEFT);
AddChildView(instructions); AddChildView(instructions);
views::View* cvc_container = new views::View(); views::View* input_row = new views::View();
cvc_container->SetLayoutManager( input_row->SetLayoutManager(
new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 5)); new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 5));
AddChildView(cvc_container); AddChildView(input_row);
if (controller_->ShouldRequestExpirationDate()) {
month_input_ = new views::Combobox(&month_combobox_model_);
month_input_->set_listener(this);
input_row->AddChildView(month_input_);
year_input_ = new views::Combobox(&year_combobox_model_);
year_input_->set_listener(this);
input_row->AddChildView(year_input_);
}
cvc_input_ = new views::Textfield(); cvc_input_ = new views::Textfield();
cvc_input_->set_controller(this); cvc_input_->set_controller(this);
cvc_input_->set_placeholder_text( cvc_input_->set_placeholder_text(
l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC)); l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC));
cvc_input_->set_default_width_in_chars(10); cvc_input_->set_default_width_in_chars(10);
cvc_container->AddChildView(cvc_input_); input_row->AddChildView(cvc_input_);
views::ImageView* cvc_image = new views::ImageView(); views::ImageView* cvc_image = new views::ImageView();
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
cvc_image->SetImage(rb.GetImageSkiaNamed(controller_->GetCvcImageRid())); cvc_image->SetImage(rb.GetImageSkiaNamed(controller_->GetCvcImageRid()));
cvc_container->AddChildView(cvc_image); input_row->AddChildView(cvc_image);
message_label_ = new views::Label(); message_label_ = new views::Label();
cvc_container->AddChildView(message_label_); input_row->AddChildView(message_label_);
message_label_->SetVisible(false); message_label_->SetVisible(false);
} }
...@@ -181,6 +225,13 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView, ...@@ -181,6 +225,13 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
views::Textfield* cvc_input_; views::Textfield* cvc_input_;
// These will be null when expiration date is not required.
views::Combobox* month_input_;
views::Combobox* year_input_;
MonthComboboxModel month_combobox_model_;
YearComboboxModel year_combobox_model_;
// TODO(estade): this is a temporary standin in place of some spinner UI // TODO(estade): this is a temporary standin in place of some spinner UI
// as well as a better error message. // as well as a better error message.
views::Label* message_label_; views::Label* message_label_;
......
...@@ -683,10 +683,12 @@ void AutofillManager::OnLoadedServerPredictions( ...@@ -683,10 +683,12 @@ void AutofillManager::OnLoadedServerPredictions(
driver_->SendAutofillTypePredictionsToRenderer(form_structures_.get()); driver_->SendAutofillTypePredictionsToRenderer(form_structures_.get());
} }
void AutofillManager::OnUnmaskResponse(const base::string16& cvc) { void AutofillManager::OnUnmaskResponse(const base::string16& cvc,
const base::string16& exp_month,
const base::string16& exp_year) {
// Most of this function is demo code. The real code should look something // Most of this function is demo code. The real code should look something
// like: // like:
// real_pan_client_.UnmaskCard(unmasking_card_, cvc); // real_pan_client_.UnmaskCard(unmasking_card_, cvc, exp_month, exp_year);
unmasking_cvc_ = cvc; unmasking_cvc_ = cvc;
// TODO(estade): fake verification: assume 123/1234 is the correct cvc. // TODO(estade): fake verification: assume 123/1234 is the correct cvc.
...@@ -723,6 +725,8 @@ void AutofillManager::OnUnmaskVerificationResult(bool success) { ...@@ -723,6 +725,8 @@ void AutofillManager::OnUnmaskVerificationResult(bool success) {
unmasking_card_.set_record_type(CreditCard::FULL_SERVER_CARD); unmasking_card_.set_record_type(CreditCard::FULL_SERVER_CARD);
if (unmasking_card_.type() == kAmericanExpressCard) { if (unmasking_card_.type() == kAmericanExpressCard) {
unmasking_card_.SetNumber(base::ASCIIToUTF16("371449635398431")); unmasking_card_.SetNumber(base::ASCIIToUTF16("371449635398431"));
} else if (unmasking_card_.type() == kVisaCard) {
unmasking_card_.SetNumber(base::ASCIIToUTF16("4012888888881881"));
} else { } else {
DCHECK_EQ(kDiscoverCard, unmasking_card_.type()); DCHECK_EQ(kDiscoverCard, unmasking_card_.type());
unmasking_card_.SetNumber(base::ASCIIToUTF16("6011000990139424")); unmasking_card_.SetNumber(base::ASCIIToUTF16("6011000990139424"));
......
...@@ -226,7 +226,9 @@ class AutofillManager : public AutofillDownloadManager::Observer, ...@@ -226,7 +226,9 @@ class AutofillManager : public AutofillDownloadManager::Observer,
void OnLoadedServerPredictions(const std::string& response_xml) override; void OnLoadedServerPredictions(const std::string& response_xml) override;
// CardUnmaskDelegate: // CardUnmaskDelegate:
void OnUnmaskResponse(const base::string16& cvc) override; void OnUnmaskResponse(const base::string16& cvc,
const base::string16& exp_month,
const base::string16& exp_year) override;
void OnUnmaskPromptClosed() override; void OnUnmaskPromptClosed() override;
// wallet::RealPanWalletClient::Delegate: // wallet::RealPanWalletClient::Delegate:
......
...@@ -13,7 +13,9 @@ class CardUnmaskDelegate { ...@@ -13,7 +13,9 @@ class CardUnmaskDelegate {
public: public:
// Called when the user has attempted a verification. Prompt is still // Called when the user has attempted a verification. Prompt is still
// open at this point. // open at this point.
virtual void OnUnmaskResponse(const base::string16& cvc) = 0; virtual void OnUnmaskResponse(const base::string16& cvc,
const base::string16& exp_month,
const base::string16& exp_year) = 0;
// Called when the unmask prompt is closed (e.g., cancelled). // Called when the unmask prompt is closed (e.g., cancelled).
virtual void OnUnmaskPromptClosed() = 0; virtual void OnUnmaskPromptClosed() = 0;
......
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