diff options
author | estade <estade@chromium.org> | 2014-12-30 15:35:19 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-12-30 23:35:57 +0000 |
commit | 39f60498e6576e5402e67d77990478d31415f337 (patch) | |
tree | 457bbf6a8b36265af0e9db15dd837a984fad785a | |
parent | f3810b62c20630764d4845edd17279ddfaef5633 (diff) | |
download | chromium_src-39f60498e6576e5402e67d77990478d31415f337.zip chromium_src-39f60498e6576e5402e67d77990478d31415f337.tar.gz chromium_src-39f60498e6576e5402e67d77990478d31415f337.tar.bz2 |
Iterate on the card unmasking prompt on Views a little bit more.
Move some code from ChromeAutofillClient into new controller class. Move some potentially shared view code into this class.
Move verification to AutofillExternalDelegate. Add new verification algorithm: assume "1234" is the correct cvc.
BUG=437116
TBR=aruslan@chromium.org,sgurun@chromium.org
Review URL: https://codereview.chromium.org/802933003
Cr-Commit-Position: refs/heads/master@{#309789}
22 files changed, 313 insertions, 95 deletions
diff --git a/android_webview/native/aw_autofill_client.cc b/android_webview/native/aw_autofill_client.cc index bc056e3..a26614e 100644 --- a/android_webview/native/aw_autofill_client.cc +++ b/android_webview/native/aw_autofill_client.cc @@ -184,7 +184,13 @@ void AwAutofillClient::ShowAutofillSettings() { NOTIMPLEMENTED(); } -void AwAutofillClient::ShowUnmaskPrompt() { +void AwAutofillClient::ShowUnmaskPrompt( + const autofill::CreditCard& card, + base::WeakPtr<autofill::CardUnmaskDelegate> delegate) { + NOTIMPLEMENTED(); +} + +void AwAutofillClient::OnUnmaskVerificationResult(bool success) { NOTIMPLEMENTED(); } diff --git a/android_webview/native/aw_autofill_client.h b/android_webview/native/aw_autofill_client.h index a6158fa..b1f81ed 100644 --- a/android_webview/native/aw_autofill_client.h +++ b/android_webview/native/aw_autofill_client.h @@ -19,6 +19,7 @@ namespace autofill { class AutofillMetrics; class AutofillPopupDelegate; +class CardUnmaskDelegate; class CreditCard; class FormStructure; class PasswordGenerator; @@ -61,7 +62,10 @@ class AwAutofillClient : public autofill::AutofillClient, virtual PrefService* GetPrefs() override; virtual void HideRequestAutocompleteDialog() override; virtual void ShowAutofillSettings() override; - virtual void ShowUnmaskPrompt() override; + virtual void ShowUnmaskPrompt( + const autofill::CreditCard& card, + base::WeakPtr<autofill::CardUnmaskDelegate> delegate) override; + virtual void OnUnmaskVerificationResult(bool success) override; virtual void ConfirmSaveCreditCard( const base::Closure& save_card_callback) override; virtual bool HasCreditCardScanFeature() override; diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index ac08799..bce6d69 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -10994,6 +10994,13 @@ Chrome ran out of memory. </message> </if> + <message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_INSTRUCTIONS" desc="Text explaining what the user should do in the card unmasking dialog."> + Enter the three digit verification code from the back of your credit card + </message> + <message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_INSTRUCTIONS_AMEX" desc="Text explaining what the user should do in the card unmasking dialog for amex cards."> + Enter the four digit verification code from the front of your credit card + </message> + <message name="IDS_APPEARANCE_GROUP_NAME" desc="The title of the appearance group"> Appearance </message> diff --git a/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.cc b/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.cc index 836b5c6..3e3230e 100644 --- a/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.cc +++ b/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.cc @@ -64,13 +64,13 @@ void CardUnmaskPromptViewAndroid::DisableAndWaitForVerification() { Java_CardUnmaskBridge_disableAndWaitForVerification(env, java_object_.obj()); } -void CardUnmaskPromptViewAndroid::VerificationSucceeded() { - // TODO(estade): implement. -} - -void CardUnmaskPromptViewAndroid::VerificationFailed() { - JNIEnv* env = base::android::AttachCurrentThread(); - Java_CardUnmaskBridge_verificationFailed(env, java_object_.obj()); +void CardUnmaskPromptViewAndroid::GotVerificationResult(bool success) { + if (success) { + // TODO(estade): implement. + } else { + JNIEnv* env = base::android::AttachCurrentThread(); + Java_CardUnmaskBridge_verificationFailed(env, java_object_.obj()); + } } // static diff --git a/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.h b/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.h index 2486fdd..a5b02fb 100644 --- a/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.h +++ b/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.h @@ -26,8 +26,7 @@ class CardUnmaskPromptViewAndroid : public CardUnmaskPromptView { // CardUnmaskPromptView implementation. void ControllerGone() override; void DisableAndWaitForVerification() override; - void VerificationSucceeded() override; - void VerificationFailed() override; + void GotVerificationResult(bool success) override; static bool Register(JNIEnv* env); diff --git a/chrome/browser/ui/autofill/card_unmask_prompt_controller.h b/chrome/browser/ui/autofill/card_unmask_prompt_controller.h index 914be29..b4eba4e 100644 --- a/chrome/browser/ui/autofill/card_unmask_prompt_controller.h +++ b/chrome/browser/ui/autofill/card_unmask_prompt_controller.h @@ -15,9 +15,16 @@ namespace autofill { class CardUnmaskPromptController { public: - virtual content::WebContents* GetWebContents() = 0; + // Interaction. virtual void OnUnmaskDialogClosed() = 0; virtual void OnUnmaskResponse(const base::string16& cvc) = 0; + + // State. + virtual content::WebContents* GetWebContents() = 0; + virtual base::string16 GetWindowTitle() const = 0; + virtual base::string16 GetInstructionsMessage() const = 0; + virtual int GetCvcImageRid() const = 0; + virtual bool InputTextIsValid(const base::string16& input_text) const = 0; }; } // namespace autofill diff --git a/chrome/browser/ui/autofill/card_unmask_prompt_controller_impl.cc b/chrome/browser/ui/autofill/card_unmask_prompt_controller_impl.cc new file mode 100644 index 0000000..676b329 --- /dev/null +++ b/chrome/browser/ui/autofill/card_unmask_prompt_controller_impl.cc @@ -0,0 +1,85 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/autofill/card_unmask_prompt_controller_impl.h" + +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/ui/autofill/card_unmask_prompt_view.h" +#include "chrome/grit/generated_resources.h" +#include "components/autofill/core/browser/card_unmask_delegate.h" +#include "grit/theme_resources.h" +#include "ui/base/l10n/l10n_util.h" + +namespace autofill { + +CardUnmaskPromptControllerImpl::CardUnmaskPromptControllerImpl( + content::WebContents* web_contents) + : web_contents_(web_contents), + card_unmask_view_(nullptr), + weak_pointer_factory_(this) { +} + +CardUnmaskPromptControllerImpl::~CardUnmaskPromptControllerImpl() { + if (card_unmask_view_) + card_unmask_view_->ControllerGone(); +} + +void CardUnmaskPromptControllerImpl::ShowPrompt( + const CreditCard& card, + base::WeakPtr<CardUnmaskDelegate> delegate) { + if (card_unmask_view_) + card_unmask_view_->ControllerGone(); + + card_ = card; + delegate_ = delegate; + card_unmask_view_ = CardUnmaskPromptView::CreateAndShow(this); +} + +void CardUnmaskPromptControllerImpl::OnVerificationResult(bool success) { + if (card_unmask_view_) + card_unmask_view_->GotVerificationResult(success); +} + +void CardUnmaskPromptControllerImpl::OnUnmaskDialogClosed() { + card_unmask_view_ = nullptr; +} + +void CardUnmaskPromptControllerImpl::OnUnmaskResponse( + const base::string16& cvc) { + card_unmask_view_->DisableAndWaitForVerification(); + delegate_->OnUnmaskResponse(cvc); +} + +content::WebContents* CardUnmaskPromptControllerImpl::GetWebContents() { + return web_contents_; +} + +base::string16 CardUnmaskPromptControllerImpl::GetWindowTitle() const { + return base::ASCIIToUTF16("Unlocking ") + card_.TypeAndLastFourDigits(); +} + +base::string16 CardUnmaskPromptControllerImpl::GetInstructionsMessage() const { + return l10n_util::GetStringUTF16( + card_.type() == kAmericanExpressCard + ? IDS_AUTOFILL_CARD_UNMASK_PROMPT_INSTRUCTIONS_AMEX + : IDS_AUTOFILL_CARD_UNMASK_PROMPT_INSTRUCTIONS); +} + +int CardUnmaskPromptControllerImpl::GetCvcImageRid() const { + return card_.type() == kAmericanExpressCard ? IDR_CREDIT_CARD_CVC_HINT_AMEX + : IDR_CREDIT_CARD_CVC_HINT; +} + +bool CardUnmaskPromptControllerImpl::InputTextIsValid( + const base::string16& input_text) const { + base::string16 trimmed_text; + base::TrimWhitespace(input_text, base::TRIM_ALL, &trimmed_text); + size_t input_size = card_.type() == kAmericanExpressCard ? 4 : 3; + return trimmed_text.size() == input_size && + base::ContainsOnlyChars(trimmed_text, + base::ASCIIToUTF16("0123456789")); +} + +} // namespace autofill diff --git a/chrome/browser/ui/autofill/card_unmask_prompt_controller_impl.h b/chrome/browser/ui/autofill/card_unmask_prompt_controller_impl.h new file mode 100644 index 0000000..5e30859 --- /dev/null +++ b/chrome/browser/ui/autofill/card_unmask_prompt_controller_impl.h @@ -0,0 +1,50 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_AUTOFILL_CARD_UNMASK_PROMPT_CONTROLLER_IMPL_H_ +#define CHROME_BROWSER_UI_AUTOFILL_CARD_UNMASK_PROMPT_CONTROLLER_IMPL_H_ + +#include "base/memory/weak_ptr.h" +#include "chrome/browser/ui/autofill/card_unmask_prompt_controller.h" +#include "components/autofill/core/browser/credit_card.h" + +namespace autofill { + +class CardUnmaskDelegate; +class CardUnmaskPromptView; + +class CardUnmaskPromptControllerImpl : public CardUnmaskPromptController { + public: + explicit CardUnmaskPromptControllerImpl(content::WebContents* web_contents); + ~CardUnmaskPromptControllerImpl(); + + // Functions called by ChromeAutofillClient. + void ShowPrompt(const CreditCard& card, + base::WeakPtr<CardUnmaskDelegate> delegate); + // The CVC the user entered went through validation. + void OnVerificationResult(bool success); + + // CardUnmaskPromptController implementation. + void OnUnmaskDialogClosed() override; + void OnUnmaskResponse(const base::string16& cvc) override; + content::WebContents* GetWebContents() override; + base::string16 GetWindowTitle() const override; + base::string16 GetInstructionsMessage() const override; + int GetCvcImageRid() const override; + bool InputTextIsValid(const base::string16& input_text) const override; + + private: + content::WebContents* web_contents_; + CreditCard card_; + base::WeakPtr<CardUnmaskDelegate> delegate_; + CardUnmaskPromptView* card_unmask_view_; + + base::WeakPtrFactory<CardUnmaskPromptControllerImpl> weak_pointer_factory_; + + DISALLOW_COPY_AND_ASSIGN(CardUnmaskPromptControllerImpl); +}; + +} // namespace autofill + +#endif // CHROME_BROWSER_UI_AUTOFILL_CARD_UNMASK_PROMPT_CONTROLLER_IMPL_H_ diff --git a/chrome/browser/ui/autofill/card_unmask_prompt_view.h b/chrome/browser/ui/autofill/card_unmask_prompt_view.h index b923390..d075ecd 100644 --- a/chrome/browser/ui/autofill/card_unmask_prompt_view.h +++ b/chrome/browser/ui/autofill/card_unmask_prompt_view.h @@ -19,8 +19,7 @@ class CardUnmaskPromptView { virtual void ControllerGone() = 0; virtual void DisableAndWaitForVerification() = 0; - virtual void VerificationSucceeded() = 0; - virtual void VerificationFailed() = 0; + virtual void GotVerificationResult(bool success) = 0; protected: CardUnmaskPromptView(); diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc index 882e989..ad6608a 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.cc +++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc @@ -42,8 +42,7 @@ namespace autofill { ChromeAutofillClient::ChromeAutofillClient(content::WebContents* web_contents) : content::WebContentsObserver(web_contents), - card_unmask_view_(nullptr), - weak_pointer_factory_(this) { + unmask_controller_(web_contents) { DCHECK(web_contents); #if !defined(OS_ANDROID) @@ -65,8 +64,6 @@ ChromeAutofillClient::ChromeAutofillClient(content::WebContents* web_contents) } ChromeAutofillClient::~ChromeAutofillClient() { - if (card_unmask_view_) - card_unmask_view_->ControllerGone(); // NOTE: It is too late to clean up the autofill popup; that cleanup process // requires that the WebContents instance still be valid and it is not at // this point (in particular, the WebContentsImpl destructor has already @@ -111,29 +108,14 @@ void ChromeAutofillClient::ShowAutofillSettings() { #endif // #if defined(OS_ANDROID) } -void ChromeAutofillClient::ShowUnmaskPrompt() { - card_unmask_view_ = CardUnmaskPromptView::CreateAndShow(this); +void ChromeAutofillClient::ShowUnmaskPrompt( + const CreditCard& card, + base::WeakPtr<CardUnmaskDelegate> delegate) { + unmask_controller_.ShowPrompt(card, delegate); } -content::WebContents* ChromeAutofillClient::GetWebContents() { - return web_contents(); -} - -void ChromeAutofillClient::OnUnmaskDialogClosed() { - card_unmask_view_ = nullptr; -} - -void ChromeAutofillClient::OnUnmaskResponse(const base::string16& cvc) { - card_unmask_view_->DisableAndWaitForVerification(); - base::MessageLoop::current()->PostDelayedTask( - FROM_HERE, base::Bind(&ChromeAutofillClient::OnVerificationFailure, - weak_pointer_factory_.GetWeakPtr()), - base::TimeDelta::FromSeconds(2)); -} - -void ChromeAutofillClient::OnVerificationFailure() { - if (card_unmask_view_) - card_unmask_view_->VerificationFailed(); +void ChromeAutofillClient::OnUnmaskVerificationResult(bool success) { + unmask_controller_.OnVerificationResult(success); } void ChromeAutofillClient::ConfirmSaveCreditCard( diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.h b/chrome/browser/ui/autofill/chrome_autofill_client.h index c0a3be3..6080abd 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.h +++ b/chrome/browser/ui/autofill/chrome_autofill_client.h @@ -10,8 +10,7 @@ #include "base/i18n/rtl.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.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_controller_impl.h" #include "components/autofill/core/browser/autofill_client.h" #include "components/ui/zoom/zoom_observer.h" #include "content/public/browser/web_contents_observer.h" @@ -36,8 +35,7 @@ class ChromeAutofillClient : public AutofillClient, public content::WebContentsUserData<ChromeAutofillClient>, public content::WebContentsObserver, - public ui_zoom::ZoomObserver, - public CardUnmaskPromptController { + public ui_zoom::ZoomObserver { public: ~ChromeAutofillClient() override; @@ -50,7 +48,9 @@ class ChromeAutofillClient PrefService* GetPrefs() override; void HideRequestAutocompleteDialog() override; void ShowAutofillSettings() override; - void ShowUnmaskPrompt() override; + void ShowUnmaskPrompt(const CreditCard& card, + base::WeakPtr<CardUnmaskDelegate> delegate) override; + void OnUnmaskVerificationResult(bool success) override; void ConfirmSaveCreditCard(const base::Closure& save_card_callback) override; bool HasCreditCardScanFeature() override; void ScanCreditCard(const CreditCardScanCallback& callback) override; @@ -90,11 +90,6 @@ class ChromeAutofillClient dialog_controller_ = dialog_controller; } - // CardUnmaskPromptController implementation. - content::WebContents* GetWebContents() override; - void OnUnmaskDialogClosed() override; - void OnUnmaskResponse(const base::string16& cvc) override; - private: #if defined(OS_MACOSX) && !defined(OS_IOS) // Creates |bridge_wrapper_|, which is responsible for dealing with Keystone @@ -105,14 +100,12 @@ class ChromeAutofillClient void UnregisterFromKeystoneNotifications(); #endif // defined(OS_MACOSX) && !defined(OS_IOS) - // The CVC the user entered failed to authenticate the masked card. - void OnVerificationFailure(); - explicit ChromeAutofillClient(content::WebContents* web_contents); friend class content::WebContentsUserData<ChromeAutofillClient>; base::WeakPtr<AutofillDialogController> dialog_controller_; base::WeakPtr<AutofillPopupControllerImpl> popup_controller_; + CardUnmaskPromptControllerImpl unmask_controller_; #if defined(OS_MACOSX) && !defined(OS_IOS) // Listens to Keystone notifications and passes relevant ones on to the @@ -125,10 +118,6 @@ class ChromeAutofillClient AutofillKeystoneBridgeWrapper* bridge_wrapper_; #endif // defined(OS_MACOSX) && !defined(OS_IOS) - CardUnmaskPromptView* card_unmask_view_; - - base::WeakPtrFactory<ChromeAutofillClient> weak_pointer_factory_; - DISALLOW_COPY_AND_ASSIGN(ChromeAutofillClient); }; diff --git a/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc b/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc index 6cf6f59..cf21a18 100644 --- a/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc +++ b/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc @@ -3,7 +3,6 @@ // found in the LICENSE file. #include "base/basictypes.h" -#include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/ui/autofill/card_unmask_prompt_controller.h" #include "chrome/browser/ui/autofill/card_unmask_prompt_view.h" @@ -30,7 +29,7 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView, views::TextfieldController { public: explicit CardUnmaskPromptViews(CardUnmaskPromptController* controller) - : controller_(controller), cvc_(nullptr), message_label_(nullptr) {} + : controller_(controller), cvc_input_(nullptr), message_label_(nullptr) {} ~CardUnmaskPromptViews() override { if (controller_) @@ -45,27 +44,29 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView, // CardUnmaskPromptView void ControllerGone() override { controller_ = nullptr; - GetWidget()->Close(); + ClosePrompt(); } void DisableAndWaitForVerification() override { - cvc_->SetEnabled(false); + cvc_input_->SetEnabled(false); message_label_->SetText(base::ASCIIToUTF16("Verifying...")); message_label_->SetVisible(true); GetDialogClientView()->UpdateDialogButtons(); Layout(); } - void VerificationSucceeded() override { - // TODO(estade): implement. - } - - void VerificationFailed() override { - cvc_->SetEnabled(true); - message_label_->SetText( - base::ASCIIToUTF16("Verification error. Please try again.")); - message_label_->SetVisible(true); - GetDialogClientView()->UpdateDialogButtons(); + void GotVerificationResult(bool success) override { + if (success) { + message_label_->SetText(base::ASCIIToUTF16("Success!")); + base::MessageLoop::current()->PostDelayedTask( + FROM_HERE, base::Bind(&CardUnmaskPromptViews::ClosePrompt, + base::Unretained(this)), + base::TimeDelta::FromSeconds(1)); + } else { + cvc_input_->SetEnabled(true); + message_label_->SetText(base::ASCIIToUTF16("Verification error.")); + GetDialogClientView()->UpdateDialogButtons(); + } Layout(); } @@ -75,11 +76,19 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView, return this; } + // views::View + gfx::Size GetPreferredSize() const override { + // Must hardcode a width so the label knows where to wrap. TODO(estade): + // This can lead to a weird looking dialog if we end up getting allocated + // more width than we ask for, e.g. if the title is super long. + const int kWidth = 250; + return gfx::Size(kWidth, GetHeightForWidth(kWidth)); + } + ui::ModalType GetModalType() const override { return ui::MODAL_TYPE_CHILD; } base::string16 GetWindowTitle() const override { - // TODO(estade): fix this. - return base::ASCIIToUTF16("Unlocking Visa - 1111"); + return controller_->GetWindowTitle(); } void DeleteDelegate() override { delete this; } @@ -104,14 +113,11 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView, DCHECK_EQ(ui::DIALOG_BUTTON_OK, button); - base::string16 input_text; - base::TrimWhitespace(cvc_->text(), base::TRIM_ALL, &input_text); - return cvc_->enabled() && input_text.size() == 3 && - base::ContainsOnlyChars(input_text, - base::ASCIIToUTF16("0123456789")); + return cvc_input_->enabled() && + controller_->InputTextIsValid(cvc_input_->text()); } - views::View* GetInitiallyFocusedView() override { return cvc_; } + views::View* GetInitiallyFocusedView() override { return cvc_input_; } bool Cancel() override { return true; @@ -121,7 +127,7 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView, if (!controller_) return true; - controller_->OnUnmaskResponse(cvc_->text()); + controller_->OnUnmaskResponse(cvc_input_->text()); return false; } @@ -136,28 +142,32 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView, if (has_children()) return; - // TODO(estade): for amex, text and CVC image should be different. SetLayoutManager( new views::BoxLayout(views::BoxLayout::kVertical, 19, 0, 5)); - AddChildView(new views::Label(base::ASCIIToUTF16( - "Enter the three digit verification code from the back of your credit " - "card"))); + views::Label* instructions = + new views::Label(controller_->GetInstructionsMessage()); + + instructions->SetMultiLine(true); + instructions->SetHorizontalAlignment(gfx::ALIGN_LEFT); + AddChildView(instructions); views::View* cvc_container = new views::View(); cvc_container->SetLayoutManager( new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 5)); AddChildView(cvc_container); - cvc_ = new views::Textfield(); - cvc_->set_controller(this); - cvc_->set_placeholder_text( + cvc_input_ = new views::Textfield(); + cvc_input_->set_controller(this); + cvc_input_->set_placeholder_text( l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC)); - cvc_->set_default_width_in_chars(10); - cvc_container->AddChildView(cvc_); + cvc_input_->set_default_width_in_chars(10); + cvc_container->AddChildView(cvc_input_); views::ImageView* cvc_image = new views::ImageView(); ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); - cvc_image->SetImage(rb.GetImageSkiaNamed(IDR_CREDIT_CARD_CVC_HINT)); + + cvc_image->SetImage(rb.GetImageSkiaNamed(controller_->GetCvcImageRid())); + cvc_container->AddChildView(cvc_image); message_label_ = new views::Label(); @@ -165,9 +175,11 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView, message_label_->SetVisible(false); } + void ClosePrompt() { GetWidget()->Close(); } + CardUnmaskPromptController* controller_; - views::Textfield* cvc_; + views::Textfield* cvc_input_; // TODO(estade): this is a temporary standin in place of some spinner UI // as well as a better error message. diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index 918eccf..a2cd48a 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi @@ -83,6 +83,8 @@ 'browser/ui/autofill/autofill_popup_view.h', 'browser/ui/autofill/autofill_popup_view_delegate.h', 'browser/ui/autofill/card_unmask_prompt_controller.h', + 'browser/ui/autofill/card_unmask_prompt_controller_impl.cc', + 'browser/ui/autofill/card_unmask_prompt_controller_impl.h', 'browser/ui/autofill/card_unmask_prompt_view.cc', 'browser/ui/autofill/card_unmask_prompt_view.h', 'browser/ui/autofill/chrome_autofill_client.cc', diff --git a/components/autofill.gypi b/components/autofill.gypi index 20390be..d6e4e33 100644 --- a/components/autofill.gypi +++ b/components/autofill.gypi @@ -147,6 +147,7 @@ 'autofill/core/browser/autofill_type.h', 'autofill/core/browser/autofill_xml_parser.cc', 'autofill/core/browser/autofill_xml_parser.h', + 'autofill/core/browser/card_unmask_delegate.h', 'autofill/core/browser/contact_info.cc', 'autofill/core/browser/contact_info.h', 'autofill/core/browser/credit_card.cc', diff --git a/components/autofill/core/browser/autofill_client.h b/components/autofill/core/browser/autofill_client.h index 6ffcd70..4e95487 100644 --- a/components/autofill/core/browser/autofill_client.h +++ b/components/autofill/core/browser/autofill_client.h @@ -28,6 +28,7 @@ namespace autofill { class AutofillPopupDelegate; class AutofillWebDataService; +class CardUnmaskDelegate; class CreditCard; class FormStructure; class PersonalDataManager; @@ -78,7 +79,9 @@ class AutofillClient { // A user has attempted to use a masked card. Prompt them for further // information to proceed. - virtual void ShowUnmaskPrompt() = 0; + virtual void ShowUnmaskPrompt(const CreditCard& card, + base::WeakPtr<CardUnmaskDelegate> delegate) = 0; + virtual void OnUnmaskVerificationResult(bool success) = 0; // Run |save_card_callback| if the credit card should be imported as personal // data. |metric_logger| can be used to log user actions. diff --git a/components/autofill/core/browser/autofill_external_delegate.cc b/components/autofill/core/browser/autofill_external_delegate.cc index d058523..54f0d7f 100644 --- a/components/autofill/core/browser/autofill_external_delegate.cc +++ b/components/autofill/core/browser/autofill_external_delegate.cc @@ -9,6 +9,7 @@ #include "base/message_loop/message_loop.h" #include "base/metrics/histogram.h" #include "base/metrics/sparse_histogram.h" +#include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "components/autofill/core/browser/autocomplete_history_manager.h" #include "components/autofill/core/browser/autofill_driver.h" @@ -267,7 +268,10 @@ void AutofillExternalDelegate::DidAcceptSuggestion(const base::string16& value, manager_->client()->ScanCreditCard(base::Bind( &AutofillExternalDelegate::OnCreditCardScanned, GetWeakPtr())); } else if (identifier == POPUP_ITEM_ID_FAKE_MASKED_INSTRUMENT) { - manager_->client()->ShowUnmaskPrompt(); + CreditCard fake_masked_card(base::ASCIIToUTF16("8431"), 5, 2016); + fake_masked_card.set_record_type(CreditCard::MASKED_WALLET_CARD); + fake_masked_card.SetTypeForMaskedCard(kAmericanExpressCard); + manager_->client()->ShowUnmaskPrompt(fake_masked_card, GetWeakPtr()); } else { FillAutofillFormData(identifier, false); } @@ -300,6 +304,23 @@ void AutofillExternalDelegate::ClearPreviewedForm() { driver_->RendererShouldClearPreviewedForm(); } +void AutofillExternalDelegate::OnUnmaskResponse(const base::string16& cvc) { + // TODO(estade): fake verification: assume 1234 is the correct cvc. + if (LowerCaseEqualsASCII(cvc, "1234")) { + base::MessageLoop::current()->PostDelayedTask( + FROM_HERE, + base::Bind(&AutofillExternalDelegate::OnUnmaskVerificationResult, + base::Unretained(this), true), + base::TimeDelta::FromSeconds(2)); + } else { + base::MessageLoop::current()->PostDelayedTask( + FROM_HERE, + base::Bind(&AutofillExternalDelegate::OnUnmaskVerificationResult, + base::Unretained(this), false), + base::TimeDelta::FromSeconds(2)); + } +} + void AutofillExternalDelegate::Reset() { manager_->client()->HideAutofillPopup(); } @@ -418,4 +439,13 @@ void AutofillExternalDelegate::PingRenderer() { } #endif // defined(OS_MACOSX) && !defined(OS_IOS) +void AutofillExternalDelegate::OnUnmaskVerificationResult(bool success) { + if (success) { + CreditCard fake_card(base::ASCIIToUTF16("371449635398431"), 5, 2016); + manager_->FillCreditCardForm(query_id_, query_form_, query_field_, + fake_card); + } + manager_->client()->OnUnmaskVerificationResult(success); +} + } // namespace autofill diff --git a/components/autofill/core/browser/autofill_external_delegate.h b/components/autofill/core/browser/autofill_external_delegate.h index c45ea6b..0e7f352 100644 --- a/components/autofill/core/browser/autofill_external_delegate.h +++ b/components/autofill/core/browser/autofill_external_delegate.h @@ -12,6 +12,7 @@ #include "base/memory/weak_ptr.h" #include "base/strings/string16.h" #include "components/autofill/core/browser/autofill_popup_delegate.h" +#include "components/autofill/core/browser/card_unmask_delegate.h" #include "components/autofill/core/browser/suggestion.h" #include "components/autofill/core/common/form_data.h" #include "components/autofill/core/common/form_field_data.h" @@ -27,7 +28,8 @@ class AutofillManager; // this logic. See http://crbug.com/51644 // Delegate for in-browser Autocomplete and Autofill display and selection. -class AutofillExternalDelegate : public AutofillPopupDelegate { +class AutofillExternalDelegate : public AutofillPopupDelegate, + public CardUnmaskDelegate { public: // Creates an AutofillExternalDelegate for the specified AutofillManager and // AutofillDriver. @@ -45,6 +47,9 @@ class AutofillExternalDelegate : public AutofillPopupDelegate { void RemoveSuggestion(const base::string16& value, int identifier) override; void ClearPreviewedForm() override; + // CardUnmaskDelegate implementation. + void OnUnmaskResponse(const base::string16& cvc) override; + // Records and associates a query_id with web form data. Called // when the renderer posts an Autofill query to the browser. |bounds| // is window relative. |display_warning_if_disabled| tells us if we should @@ -115,6 +120,9 @@ class AutofillExternalDelegate : public AutofillPopupDelegate { void PingRenderer(); #endif // defined(OS_MACOSX) && !defined(OS_IOS) + // FIXME + void OnUnmaskVerificationResult(bool success); + AutofillManager* manager_; // weak. // Provides driver-level context to the shared code of the component. Must diff --git a/components/autofill/core/browser/card_unmask_delegate.h b/components/autofill/core/browser/card_unmask_delegate.h new file mode 100644 index 0000000..bf9f5a4 --- /dev/null +++ b/components/autofill/core/browser/card_unmask_delegate.h @@ -0,0 +1,19 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_CARD_UNMASK_DELEGATE_H_ +#define COMPONENTS_AUTOFILL_CORE_BROWSER_CARD_UNMASK_DELEGATE_H_ + +#include "base/strings/string16.h" + +namespace autofill { + +class CardUnmaskDelegate { + public: + virtual void OnUnmaskResponse(const base::string16& cvc) = 0; +}; + +} // namespace autofill + +#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_CARD_UNMASK_DELEGATE_H_ diff --git a/components/autofill/core/browser/credit_card.cc b/components/autofill/core/browser/credit_card.cc index 5e2cc635..94821b2 100644 --- a/components/autofill/core/browser/credit_card.cc +++ b/components/autofill/core/browser/credit_card.cc @@ -300,6 +300,11 @@ const char* CreditCard::GetCreditCardType(const base::string16& number) { return kGenericCard; } +void CreditCard::SetTypeForMaskedCard(const char* type) { + DCHECK_EQ(MASKED_WALLET_CARD, record_type()); + type_ = type; +} + base::string16 CreditCard::GetRawInfo(ServerFieldType type) const { DCHECK_EQ(CREDIT_CARD, AutofillType(type).group()); switch (type) { diff --git a/components/autofill/core/browser/credit_card.h b/components/autofill/core/browser/credit_card.h index a9dd937..50a1f96 100644 --- a/components/autofill/core/browser/credit_card.h +++ b/components/autofill/core/browser/credit_card.h @@ -68,6 +68,9 @@ class CreditCard : public AutofillDataModel { // the invalid card "4garbage" will be Visa, which has an IIN of 4. static const char* GetCreditCardType(const base::string16& number); + // Type strings are defined at the bottom of this file, e.g. kVisaCard. + void SetTypeForMaskedCard(const char* type); + // FormGroup: void GetMatchingTypes(const base::string16& text, const std::string& app_locale, diff --git a/components/autofill/core/browser/test_autofill_client.cc b/components/autofill/core/browser/test_autofill_client.cc index bb94d05..5361b0f 100644 --- a/components/autofill/core/browser/test_autofill_client.cc +++ b/components/autofill/core/browser/test_autofill_client.cc @@ -31,7 +31,12 @@ void TestAutofillClient::HideRequestAutocompleteDialog() { void TestAutofillClient::ShowAutofillSettings() { } -void TestAutofillClient::ShowUnmaskPrompt() { +void TestAutofillClient::ShowUnmaskPrompt( + const CreditCard& card, + base::WeakPtr<CardUnmaskDelegate> delegate) { +} + +void TestAutofillClient::OnUnmaskVerificationResult(bool success) { } void TestAutofillClient::ConfirmSaveCreditCard( diff --git a/components/autofill/core/browser/test_autofill_client.h b/components/autofill/core/browser/test_autofill_client.h index a809a8c..295669d 100644 --- a/components/autofill/core/browser/test_autofill_client.h +++ b/components/autofill/core/browser/test_autofill_client.h @@ -25,7 +25,9 @@ class TestAutofillClient : public AutofillClient { PrefService* GetPrefs() override; void HideRequestAutocompleteDialog() override; void ShowAutofillSettings() override; - void ShowUnmaskPrompt() override; + void ShowUnmaskPrompt(const CreditCard& card, + base::WeakPtr<CardUnmaskDelegate> delegate) override; + void OnUnmaskVerificationResult(bool success) override; void ConfirmSaveCreditCard(const base::Closure& save_card_callback) override; bool HasCreditCardScanFeature() override; void ScanCreditCard(const CreditCardScanCallback& callback) override; |