summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorestade <estade@chromium.org>2014-12-30 15:35:19 -0800
committerCommit bot <commit-bot@chromium.org>2014-12-30 23:35:57 +0000
commit39f60498e6576e5402e67d77990478d31415f337 (patch)
tree457bbf6a8b36265af0e9db15dd837a984fad785a
parentf3810b62c20630764d4845edd17279ddfaef5633 (diff)
downloadchromium_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}
-rw-r--r--android_webview/native/aw_autofill_client.cc8
-rw-r--r--android_webview/native/aw_autofill_client.h6
-rw-r--r--chrome/app/generated_resources.grd7
-rw-r--r--chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.cc14
-rw-r--r--chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.h3
-rw-r--r--chrome/browser/ui/autofill/card_unmask_prompt_controller.h9
-rw-r--r--chrome/browser/ui/autofill/card_unmask_prompt_controller_impl.cc85
-rw-r--r--chrome/browser/ui/autofill/card_unmask_prompt_controller_impl.h50
-rw-r--r--chrome/browser/ui/autofill/card_unmask_prompt_view.h3
-rw-r--r--chrome/browser/ui/autofill/chrome_autofill_client.cc32
-rw-r--r--chrome/browser/ui/autofill/chrome_autofill_client.h23
-rw-r--r--chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc80
-rw-r--r--chrome/chrome_browser_ui.gypi2
-rw-r--r--components/autofill.gypi1
-rw-r--r--components/autofill/core/browser/autofill_client.h5
-rw-r--r--components/autofill/core/browser/autofill_external_delegate.cc32
-rw-r--r--components/autofill/core/browser/autofill_external_delegate.h10
-rw-r--r--components/autofill/core/browser/card_unmask_delegate.h19
-rw-r--r--components/autofill/core/browser/credit_card.cc5
-rw-r--r--components/autofill/core/browser/credit_card.h3
-rw-r--r--components/autofill/core/browser/test_autofill_client.cc7
-rw-r--r--components/autofill/core/browser/test_autofill_client.h4
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;