summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorestade <estade@chromium.org>2014-12-17 17:46:23 -0800
committerCommit bot <commit-bot@chromium.org>2014-12-18 01:47:30 +0000
commit7c369d42b3557d37884d03a71021fa5b15919932 (patch)
treea846cc4aedd172bb9bdfe5ad962764122f30804d
parent70b8668bc59fce9f818948d74486ed616f60c090 (diff)
downloadchromium_src-7c369d42b3557d37884d03a71021fa5b15919932.zip
chromium_src-7c369d42b3557d37884d03a71021fa5b15919932.tar.gz
chromium_src-7c369d42b3557d37884d03a71021fa5b15919932.tar.bz2
Add some more state to the card unmasking prompt.
The prompt now pretends to attempt to verify the input. It always fails. BUG=437116 TBR=sgurun@chromium.org Review URL: https://codereview.chromium.org/804213002 Cr-Commit-Position: refs/heads/master@{#308918}
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwAutofillClient.java2
-rw-r--r--chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java4
-rw-r--r--chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskBridge.java41
-rw-r--r--chrome/browser/ui/android/autofill/autofill_popup_view_android.cc2
-rw-r--r--chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.cc49
-rw-r--r--chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.h20
-rw-r--r--chrome/browser/ui/autofill/card_unmask_prompt_controller.h25
-rw-r--r--chrome/browser/ui/autofill/card_unmask_prompt_view.cc4
-rw-r--r--chrome/browser/ui/autofill/card_unmask_prompt_view.h19
-rw-r--r--chrome/browser/ui/autofill/chrome_autofill_client.cc33
-rw-r--r--chrome/browser/ui/autofill/chrome_autofill_client.h15
-rw-r--r--chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc74
-rw-r--r--chrome/chrome_browser_ui.gypi1
-rw-r--r--ui/android/java/res/layout/autofill_card_unmask_prompt.xml31
-rw-r--r--ui/android/java/src/org/chromium/ui/autofill/AutofillPopup.java7
-rw-r--r--ui/android/java/src/org/chromium/ui/autofill/CardUnmaskPrompt.java68
16 files changed, 282 insertions, 113 deletions
diff --git a/android_webview/java/src/org/chromium/android_webview/AwAutofillClient.java b/android_webview/java/src/org/chromium/android_webview/AwAutofillClient.java
index e510aa6..09c9440 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwAutofillClient.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwAutofillClient.java
@@ -66,7 +66,7 @@ public class AwAutofillClient {
public void hideAutofillPopup() {
if (mAutofillPopup == null)
return;
- mAutofillPopup.hide();
+ mAutofillPopup.dismiss();
mAutofillPopup = null;
}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java
index 1f4407c..0aca77e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java
@@ -66,8 +66,8 @@ public class AutofillPopupBridge implements AutofillPopupDelegate{
* Hides the Autofill Popup and removes its anchor from the ContainerView.
*/
@CalledByNative
- private void hide() {
- if (mAutofillPopup != null) mAutofillPopup.hide();
+ private void dismiss() {
+ if (mAutofillPopup != null) mAutofillPopup.dismiss();
}
/**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskBridge.java
index b613ea2..d52b518 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskBridge.java
@@ -31,7 +31,7 @@ public class CardUnmaskBridge implements CardUnmaskPromptDelegate {
new Handler().post(new Runnable() {
@Override
public void run() {
- dismissed("");
+ dismissed();
}
});
} else {
@@ -46,19 +46,48 @@ public class CardUnmaskBridge implements CardUnmaskPromptDelegate {
}
@Override
- public void dismissed(String userResponse) {
- nativePromptDismissed(mNativeCardUnmaskPromptViewAndroid, userResponse);
+ public void dismissed() {
+ nativePromptDismissed(mNativeCardUnmaskPromptViewAndroid);
+ }
+
+ @Override
+ public void onUserInput(String userResponse) {
+ nativeOnUserInput(mNativeCardUnmaskPromptViewAndroid, userResponse);
}
/**
* Shows a prompt for unmasking a Wallet credit card.
- * @param suggestions Autofill suggestions to be displayed.
*/
@CalledByNative
private void show() {
if (mCardUnmaskPrompt != null) mCardUnmaskPrompt.show();
}
- private native void nativePromptDismissed(long nativeCardUnmaskPromptViewAndroid,
- String userResponse);
+ /**
+ * Dismisses the prompt without returning any user response.
+ */
+ @CalledByNative
+ private void dismiss() {
+ if (mCardUnmaskPrompt != null) mCardUnmaskPrompt.dismiss();
+ }
+
+ /**
+ * Disables input and visually indicates that verification is ongoing.
+ */
+ @CalledByNative
+ private void disableAndWaitForVerification() {
+ if (mCardUnmaskPrompt != null) mCardUnmaskPrompt.disableAndWaitForVerification();
+ }
+
+ /**
+ * Indicate that verification failed, allow user to retry.
+ */
+ @CalledByNative
+ private void verificationFailed() {
+ if (mCardUnmaskPrompt != null) mCardUnmaskPrompt.verificationFailed();
+ }
+
+ private native void nativePromptDismissed(long nativeCardUnmaskPromptViewAndroid);
+ private native void nativeOnUserInput(
+ long nativeCardUnmaskPromptViewAndroid, String userResponse);
}
diff --git a/chrome/browser/ui/android/autofill/autofill_popup_view_android.cc b/chrome/browser/ui/android/autofill/autofill_popup_view_android.cc
index 5e4acdc..0b5d2d8 100644
--- a/chrome/browser/ui/android/autofill/autofill_popup_view_android.cc
+++ b/chrome/browser/ui/android/autofill/autofill_popup_view_android.cc
@@ -44,7 +44,7 @@ void AutofillPopupViewAndroid::Show() {
void AutofillPopupViewAndroid::Hide() {
controller_ = NULL;
JNIEnv* env = base::android::AttachCurrentThread();
- Java_AutofillPopupBridge_hide(env, java_object_.obj());
+ Java_AutofillPopupBridge_dismiss(env, java_object_.obj());
}
void AutofillPopupViewAndroid::UpdateBoundsAndRedrawPopup() {
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 7177cfd..836b5c6 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
@@ -4,6 +4,7 @@
#include "chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.h"
+#include "chrome/browser/ui/autofill/card_unmask_prompt_controller.h"
#include "content/public/browser/web_contents.h"
#include "jni/CardUnmaskBridge_jni.h"
#include "ui/base/android/view_android.h"
@@ -12,27 +13,27 @@
namespace autofill {
CardUnmaskPromptView* CardUnmaskPromptView::CreateAndShow(
- content::WebContents* web_contents,
- const UnmaskCallback& finished) {
+ CardUnmaskPromptController* controller) {
CardUnmaskPromptViewAndroid* view =
- new CardUnmaskPromptViewAndroid(web_contents, finished);
+ new CardUnmaskPromptViewAndroid(controller);
view->Show();
return view;
}
CardUnmaskPromptViewAndroid::CardUnmaskPromptViewAndroid(
- content::WebContents* web_contents,
- const UnmaskCallback& finished)
- : web_contents_(web_contents), finished_(finished) {
+ CardUnmaskPromptController* controller)
+ : controller_(controller) {
}
CardUnmaskPromptViewAndroid::~CardUnmaskPromptViewAndroid() {
- finished_.Run(response_);
+ if (controller_)
+ controller_->OnUnmaskDialogClosed();
}
void CardUnmaskPromptViewAndroid::Show() {
JNIEnv* env = base::android::AttachCurrentThread();
- ui::ViewAndroid* view_android = web_contents_->GetNativeView();
+ ui::ViewAndroid* view_android =
+ controller_->GetWebContents()->GetNativeView();
java_object_.Reset(Java_CardUnmaskBridge_create(
env, reinterpret_cast<intptr_t>(this),
@@ -41,13 +42,37 @@ void CardUnmaskPromptViewAndroid::Show() {
Java_CardUnmaskBridge_show(env, java_object_.obj());
}
-void CardUnmaskPromptViewAndroid::PromptDismissed(JNIEnv* env,
- jobject obj,
- jstring response) {
- response_ = base::android::ConvertJavaStringToUTF16(env, response);
+void CardUnmaskPromptViewAndroid::OnUserInput(JNIEnv* env,
+ jobject obj,
+ jstring response) {
+ controller_->OnUnmaskResponse(
+ base::android::ConvertJavaStringToUTF16(env, response));
+}
+
+void CardUnmaskPromptViewAndroid::PromptDismissed(JNIEnv* env, jobject obj) {
delete this;
}
+void CardUnmaskPromptViewAndroid::ControllerGone() {
+ controller_ = nullptr;
+ JNIEnv* env = base::android::AttachCurrentThread();
+ Java_CardUnmaskBridge_dismiss(env, java_object_.obj());
+}
+
+void CardUnmaskPromptViewAndroid::DisableAndWaitForVerification() {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ 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());
+}
+
// static
bool CardUnmaskPromptViewAndroid::Register(JNIEnv* env) {
return RegisterNativesImpl(env);
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 9a78c1b..2486fdd 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
@@ -12,20 +12,22 @@
#include "base/strings/string16.h"
#include "chrome/browser/ui/autofill/card_unmask_prompt_view.h"
-namespace content {
-class WebContents;
-}
-
namespace autofill {
class CardUnmaskPromptViewAndroid : public CardUnmaskPromptView {
public:
- CardUnmaskPromptViewAndroid(content::WebContents* web_contents,
- const UnmaskCallback& finished);
+ explicit CardUnmaskPromptViewAndroid(CardUnmaskPromptController* controller);
void Show();
- void PromptDismissed(JNIEnv* env, jobject obj, jstring response);
+ void OnUserInput(JNIEnv* env, jobject obj, jstring response);
+ void PromptDismissed(JNIEnv* env, jobject obj);
+
+ // CardUnmaskPromptView implementation.
+ void ControllerGone() override;
+ void DisableAndWaitForVerification() override;
+ void VerificationSucceeded() override;
+ void VerificationFailed() override;
static bool Register(JNIEnv* env);
@@ -35,9 +37,7 @@ class CardUnmaskPromptViewAndroid : public CardUnmaskPromptView {
// The corresponding java object.
base::android::ScopedJavaGlobalRef<jobject> java_object_;
- content::WebContents* web_contents_;
- UnmaskCallback finished_;
- base::string16 response_;
+ CardUnmaskPromptController* controller_;
DISALLOW_COPY_AND_ASSIGN(CardUnmaskPromptViewAndroid);
};
diff --git a/chrome/browser/ui/autofill/card_unmask_prompt_controller.h b/chrome/browser/ui/autofill/card_unmask_prompt_controller.h
new file mode 100644
index 0000000..914be29
--- /dev/null
+++ b/chrome/browser/ui/autofill/card_unmask_prompt_controller.h
@@ -0,0 +1,25 @@
+// 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_H_
+#define CHROME_BROWSER_UI_AUTOFILL_CARD_UNMASK_PROMPT_CONTROLLER_H_
+
+#include "base/strings/string16.h"
+
+namespace content {
+class WebContents;
+}
+
+namespace autofill {
+
+class CardUnmaskPromptController {
+ public:
+ virtual content::WebContents* GetWebContents() = 0;
+ virtual void OnUnmaskDialogClosed() = 0;
+ virtual void OnUnmaskResponse(const base::string16& cvc) = 0;
+};
+
+} // namespace autofill
+
+#endif // CHROME_BROWSER_UI_AUTOFILL_CARD_UNMASK_PROMPT_CONTROLLER_H_
diff --git a/chrome/browser/ui/autofill/card_unmask_prompt_view.cc b/chrome/browser/ui/autofill/card_unmask_prompt_view.cc
index f4da38e..c420f91 100644
--- a/chrome/browser/ui/autofill/card_unmask_prompt_view.cc
+++ b/chrome/browser/ui/autofill/card_unmask_prompt_view.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/basictypes.h"
#include "chrome/browser/ui/autofill/card_unmask_prompt_view.h"
namespace autofill {
@@ -9,8 +10,7 @@ namespace autofill {
#if !defined(OS_ANDROID) && !defined(TOOLKIT_VIEWS)
// static
CardUnmaskPromptView* CardUnmaskPromptView::CreateAndShow(
- content::WebContents* web_contents,
- const UnmaskCallback& finished) {
+ CardUnmaskPromptController* controller) {
return nullptr;
}
#endif
diff --git a/chrome/browser/ui/autofill/card_unmask_prompt_view.h b/chrome/browser/ui/autofill/card_unmask_prompt_view.h
index 354a765..b923390 100644
--- a/chrome/browser/ui/autofill/card_unmask_prompt_view.h
+++ b/chrome/browser/ui/autofill/card_unmask_prompt_view.h
@@ -5,25 +5,22 @@
#ifndef CHROME_BROWSER_UI_AUTOFILL_CARD_UNMASK_PROMPT_VIEW_H_
#define CHROME_BROWSER_UI_AUTOFILL_CARD_UNMASK_PROMPT_VIEW_H_
-#include "base/callback.h"
-#include "base/strings/string16.h"
-
-namespace content {
-class WebContents;
-}
-
namespace autofill {
+class CardUnmaskPromptController;
+
// The cross-platform UI interface which prompts the user to unlock a masked
// Wallet instrument (credit card). This object is responsible for its own
// lifetime.
class CardUnmaskPromptView {
public:
- typedef base::Callback<void(const base::string16& /* CVC */)> UnmaskCallback;
+ static CardUnmaskPromptView* CreateAndShow(
+ CardUnmaskPromptController* controller);
- // |finished| is guaranteed to be called.
- static CardUnmaskPromptView* CreateAndShow(content::WebContents* web_contents,
- const UnmaskCallback& finished);
+ virtual void ControllerGone() = 0;
+ virtual void DisableAndWaitForVerification() = 0;
+ virtual void VerificationSucceeded() = 0;
+ virtual void VerificationFailed() = 0;
protected:
CardUnmaskPromptView();
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc
index 98199e4..882e989 100644
--- a/chrome/browser/ui/autofill/chrome_autofill_client.cc
+++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -41,7 +41,9 @@ DEFINE_WEB_CONTENTS_USER_DATA_KEY(autofill::ChromeAutofillClient);
namespace autofill {
ChromeAutofillClient::ChromeAutofillClient(content::WebContents* web_contents)
- : content::WebContentsObserver(web_contents), weak_pointer_factory_(this) {
+ : content::WebContentsObserver(web_contents),
+ card_unmask_view_(nullptr),
+ weak_pointer_factory_(this) {
DCHECK(web_contents);
#if !defined(OS_ANDROID)
@@ -63,6 +65,8 @@ 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
@@ -108,15 +112,28 @@ void ChromeAutofillClient::ShowAutofillSettings() {
}
void ChromeAutofillClient::ShowUnmaskPrompt() {
- // TODO(estade): we'll need to store the returned pointer at some point when
- // the view object gets more complicated.
- CardUnmaskPromptView::CreateAndShow(
- web_contents(), base::Bind(&ChromeAutofillClient::OnUnmaskResponse,
- weak_pointer_factory_.GetWeakPtr()));
+ card_unmask_view_ = CardUnmaskPromptView::CreateAndShow(this);
}
-void ChromeAutofillClient::OnUnmaskResponse(const base::string16& response) {
- NOTIMPLEMENTED() << " I should probably do something with this: " << response;
+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::ConfirmSaveCreditCard(
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.h b/chrome/browser/ui/autofill/chrome_autofill_client.h
index 42395b0..c0a3be3 100644
--- a/chrome/browser/ui/autofill/chrome_autofill_client.h
+++ b/chrome/browser/ui/autofill/chrome_autofill_client.h
@@ -10,6 +10,8 @@
#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 "components/autofill/core/browser/autofill_client.h"
#include "components/ui/zoom/zoom_observer.h"
#include "content/public/browser/web_contents_observer.h"
@@ -34,7 +36,8 @@ class ChromeAutofillClient
: public AutofillClient,
public content::WebContentsUserData<ChromeAutofillClient>,
public content::WebContentsObserver,
- public ui_zoom::ZoomObserver {
+ public ui_zoom::ZoomObserver,
+ public CardUnmaskPromptController {
public:
~ChromeAutofillClient() override;
@@ -87,6 +90,11 @@ 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
@@ -97,7 +105,8 @@ class ChromeAutofillClient
void UnregisterFromKeystoneNotifications();
#endif // defined(OS_MACOSX) && !defined(OS_IOS)
- void OnUnmaskResponse(const base::string16& response);
+ // The CVC the user entered failed to authenticate the masked card.
+ void OnVerificationFailure();
explicit ChromeAutofillClient(content::WebContents* web_contents);
friend class content::WebContentsUserData<ChromeAutofillClient>;
@@ -116,6 +125,8 @@ 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 e478eee..6cf6f59 100644
--- a/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc
+++ b/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc
@@ -5,6 +5,7 @@
#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"
#include "chrome/grit/generated_resources.h"
#include "components/constrained_window/constrained_window_views.h"
@@ -16,6 +17,7 @@
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/controls/textfield/textfield_controller.h"
#include "ui/views/layout/box_layout.h"
+#include "ui/views/widget/widget.h"
#include "ui/views/window/dialog_client_view.h"
#include "ui/views/window/dialog_delegate.h"
@@ -27,19 +29,44 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
views::DialogDelegateView,
views::TextfieldController {
public:
- CardUnmaskPromptViews(content::WebContents* web_contents,
- const UnmaskCallback& finished)
- : web_contents_(web_contents),
- finished_(finished),
- accepted_(false),
- cvc_(nullptr) {}
+ explicit CardUnmaskPromptViews(CardUnmaskPromptController* controller)
+ : controller_(controller), cvc_(nullptr), message_label_(nullptr) {}
~CardUnmaskPromptViews() override {
- finished_.Run(accepted_ ? cvc_->text() : base::string16());
+ if (controller_)
+ controller_->OnUnmaskDialogClosed();
}
void Show() {
- constrained_window::ShowWebModalDialogViews(this, web_contents_);
+ constrained_window::ShowWebModalDialogViews(this,
+ controller_->GetWebContents());
+ }
+
+ // CardUnmaskPromptView
+ void ControllerGone() override {
+ controller_ = nullptr;
+ GetWidget()->Close();
+ }
+
+ void DisableAndWaitForVerification() override {
+ cvc_->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();
+ Layout();
}
// views::DialogDelegateView
@@ -79,7 +106,7 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
base::string16 input_text;
base::TrimWhitespace(cvc_->text(), base::TRIM_ALL, &input_text);
- return input_text.size() == 3 &&
+ return cvc_->enabled() && input_text.size() == 3 &&
base::ContainsOnlyChars(input_text,
base::ASCIIToUTF16("0123456789"));
}
@@ -87,13 +114,15 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
views::View* GetInitiallyFocusedView() override { return cvc_; }
bool Cancel() override {
- DCHECK_EQ(false, accepted_);
return true;
}
bool Accept() override {
- accepted_ = true;
- return true;
+ if (!controller_)
+ return true;
+
+ controller_->OnUnmaskResponse(cvc_->text());
+ return false;
}
// views::TextfieldController
@@ -130,17 +159,20 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
cvc_image->SetImage(rb.GetImageSkiaNamed(IDR_CREDIT_CARD_CVC_HINT));
cvc_container->AddChildView(cvc_image);
- }
-
- content::WebContents* web_contents_;
- UnmaskCallback finished_;
+ message_label_ = new views::Label();
+ cvc_container->AddChildView(message_label_);
+ message_label_->SetVisible(false);
+ }
- // Set to true when the user accepts.
- bool accepted_;
+ CardUnmaskPromptController* controller_;
views::Textfield* cvc_;
+ // TODO(estade): this is a temporary standin in place of some spinner UI
+ // as well as a better error message.
+ views::Label* message_label_;
+
DISALLOW_COPY_AND_ASSIGN(CardUnmaskPromptViews);
};
@@ -148,10 +180,8 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
// static
CardUnmaskPromptView* CardUnmaskPromptView::CreateAndShow(
- content::WebContents* web_contents,
- const UnmaskCallback& finished) {
- CardUnmaskPromptViews* view =
- new CardUnmaskPromptViews(web_contents, finished);
+ CardUnmaskPromptController* controller) {
+ CardUnmaskPromptViews* view = new CardUnmaskPromptViews(controller);
view->Show();
return view;
}
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi
index b09da54..8e2fffa 100644
--- a/chrome/chrome_browser_ui.gypi
+++ b/chrome/chrome_browser_ui.gypi
@@ -82,6 +82,7 @@
'browser/ui/autofill/autofill_popup_controller_impl.h',
'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_view.cc',
'browser/ui/autofill/card_unmask_prompt_view.h',
'browser/ui/autofill/chrome_autofill_client.cc',
diff --git a/ui/android/java/res/layout/autofill_card_unmask_prompt.xml b/ui/android/java/res/layout/autofill_card_unmask_prompt.xml
index d65e974..8204304 100644
--- a/ui/android/java/res/layout/autofill_card_unmask_prompt.xml
+++ b/ui/android/java/res/layout/autofill_card_unmask_prompt.xml
@@ -22,16 +22,29 @@
android:gravity="start"
/>
- <EditText
- android:id="@+id/card_unmask_input"
- android:inputType="number"
+ <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginStart="16dp"
- android:layout_marginEnd="16dp"
- android:focusable="true"
- android:focusableInTouchMode="true"
- android:hint="@string/card_unmask_input_hint"
- />
+ android:orientation="horizontal">
+
+ <EditText
+ android:id="@+id/card_unmask_input"
+ android:inputType="number"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_marginStart="16dp"
+ android:layout_marginEnd="16dp"
+ android:ems="4"
+ android:hint="@string/card_unmask_input_hint"
+ />
+
+ <TextView
+ android:id="@+id/card_unmask_verification_message"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="start"
+ android:visibility="gone"
+ />
+ </LinearLayout>
</LinearLayout>
diff --git a/ui/android/java/src/org/chromium/ui/autofill/AutofillPopup.java b/ui/android/java/src/org/chromium/ui/autofill/AutofillPopup.java
index 7b9f3fb..5c50e63 100644
--- a/ui/android/java/src/org/chromium/ui/autofill/AutofillPopup.java
+++ b/ui/android/java/src/org/chromium/ui/autofill/AutofillPopup.java
@@ -93,13 +93,6 @@ public class AutofillPopup extends DropdownPopupWindow implements AdapterView.On
show();
}
- /**
- * Hides the popup.
- */
- public void hide() {
- dismiss();
- }
-
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
DropdownAdapter adapter = (DropdownAdapter) parent.getAdapter();
diff --git a/ui/android/java/src/org/chromium/ui/autofill/CardUnmaskPrompt.java b/ui/android/java/src/org/chromium/ui/autofill/CardUnmaskPrompt.java
index c4500d4..ca09167 100644
--- a/ui/android/java/src/org/chromium/ui/autofill/CardUnmaskPrompt.java
+++ b/ui/android/java/src/org/chromium/ui/autofill/CardUnmaskPrompt.java
@@ -9,17 +9,17 @@ import android.content.Context;
import android.content.DialogInterface;
import android.view.LayoutInflater;
import android.view.View;
+import android.widget.Button;
import android.widget.EditText;
+import android.widget.TextView;
import org.chromium.ui.R;
/**
* A prompt that bugs users to enter their CVC when unmasking a Wallet instrument (credit card).
*/
-public class CardUnmaskPrompt implements DialogInterface.OnClickListener,
- DialogInterface.OnDismissListener {
+public class CardUnmaskPrompt implements DialogInterface.OnDismissListener {
private CardUnmaskPromptDelegate mDelegate;
- private int mClickedButton;
private AlertDialog mDialog;
/**
@@ -28,44 +28,72 @@ public class CardUnmaskPrompt implements DialogInterface.OnClickListener,
public interface CardUnmaskPromptDelegate {
/**
* Called when the dialog has been dismissed.
+ */
+ void dismissed();
+
+ /**
+ * Called when the user has entered a value and pressed "verify".
* @param userResponse The value the user entered (a CVC), or an empty string if the
* user canceled.
*/
- void dismissed(String userResponse);
+ void onUserInput(String userResponse);
}
public CardUnmaskPrompt(Context context, CardUnmaskPromptDelegate delegate) {
mDelegate = delegate;
- mClickedButton = DialogInterface.BUTTON_NEGATIVE;
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(R.layout.autofill_card_unmask_prompt, null);
mDialog = new AlertDialog.Builder(context)
- .setTitle("Unlocking Visa - 1111")
- .setView(v)
- .setNegativeButton("Back", this)
- .setPositiveButton("Rock on", this)
- .setOnDismissListener(this).create();
+ .setTitle("Unlocking Visa - 1111")
+ .setView(v)
+ .setNegativeButton("Back", null)
+ .setPositiveButton("Rock on", null)
+ .setOnDismissListener(this)
+ .create();
}
public void show() {
mDialog.show();
+
+ // Override the View.OnClickListener so that pressing the positive button doesn't dismiss
+ // the dialog.
+ Button verifyButton = mDialog.getButton(AlertDialog.BUTTON_POSITIVE);
+ verifyButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ mDelegate.onUserInput(cardUnmaskInput().getText().toString());
+ }
+ });
}
- @Override
- public void onClick(DialogInterface dialog, int which) {
- mClickedButton = which;
+ public void dismiss() {
+ mDialog.dismiss();
+ }
+
+ public void disableAndWaitForVerification() {
+ cardUnmaskInput().setEnabled(false);
+ TextView message = verificationView();
+ message.setText("Verifying...");
+ message.setVisibility(View.VISIBLE);
+ }
+
+ public void verificationFailed() {
+ verificationView().setText("Verification failed. Please try again.");
+ cardUnmaskInput().setEnabled(true);
}
@Override
public void onDismiss(DialogInterface dialog) {
- if (mClickedButton == DialogInterface.BUTTON_POSITIVE) {
- String response = ((EditText) mDialog.findViewById(R.id.card_unmask_input))
- .getText().toString();
- mDelegate.dismissed(response);
- } else {
- mDelegate.dismissed("");
- }
+ mDelegate.dismissed();
+ }
+
+ private EditText cardUnmaskInput() {
+ return (EditText) mDialog.findViewById(R.id.card_unmask_input);
+ }
+
+ private TextView verificationView() {
+ return (TextView) mDialog.findViewById(R.id.card_unmask_verification_message);
}
}