Commit 8c654e6f authored by siyua's avatar siyua Committed by Commit Bot

[Autofill Auth UI] Add WebAuthn verify pending dialog

Logic for the dialog:
1. Show dialog when user has opted in, and after card verification
starts.
2. If card is not eligible for fido, fall back to CVC, close the dialog.
Card unmask prompt will be shown next.
3. If card is eligible for fido, close the dialog after card information
is filled to the form.

Uploaded screenshot in bug comment 21

Bug: 991037
Change-Id: Ibb32a03c491039664b0875ea40cc750f304e21b1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1834822Reviewed-by: default avatarEvan Stade <estade@chromium.org>
Reviewed-by: default avatarPeter Boström <pbos@chromium.org>
Reviewed-by: default avatarManas Verma <manasverma@google.com>
Reviewed-by: default avatarJared Saul <jsaul@google.com>
Commit-Queue: Siyu An <siyua@chromium.org>
Cr-Commit-Position: refs/heads/master@{#708307}
parent f7de2bf8
...@@ -1993,6 +1993,10 @@ jumbo_static_library("ui") { ...@@ -1993,6 +1993,10 @@ jumbo_static_library("ui") {
if (is_win || is_mac || is_desktop_linux || is_chromeos) { if (is_win || is_mac || is_desktop_linux || is_chromeos) {
sources += [ sources += [
"autofill/payments/verify_pending_dialog_controller.h",
"autofill/payments/verify_pending_dialog_controller_impl.cc",
"autofill/payments/verify_pending_dialog_controller_impl.h",
"autofill/payments/verify_pending_dialog_view.h",
"autofill/payments/webauthn_offer_dialog_controller.h", "autofill/payments/webauthn_offer_dialog_controller.h",
"autofill/payments/webauthn_offer_dialog_controller_impl.cc", "autofill/payments/webauthn_offer_dialog_controller_impl.cc",
"autofill/payments/webauthn_offer_dialog_controller_impl.h", "autofill/payments/webauthn_offer_dialog_controller_impl.h",
...@@ -2004,6 +2008,8 @@ jumbo_static_library("ui") { ...@@ -2004,6 +2008,8 @@ jumbo_static_library("ui") {
"frame/window_frame_util.h", "frame/window_frame_util.h",
"tab_contents/chrome_web_contents_view_handle_drop.cc", "tab_contents/chrome_web_contents_view_handle_drop.cc",
"tab_contents/chrome_web_contents_view_handle_drop.h", "tab_contents/chrome_web_contents_view_handle_drop.h",
"views/autofill/payments/verify_pending_dialog_view_impl.cc",
"views/autofill/payments/verify_pending_dialog_view_impl.h",
"views/autofill/payments/webauthn_offer_dialog_view_impl.cc", "views/autofill/payments/webauthn_offer_dialog_view_impl.cc",
"views/autofill/payments/webauthn_offer_dialog_view_impl.h", "views/autofill/payments/webauthn_offer_dialog_view_impl.h",
"views/close_bubble_on_tab_activation_helper.cc", "views/close_bubble_on_tab_activation_helper.cc",
......
...@@ -82,6 +82,8 @@ ...@@ -82,6 +82,8 @@
#include "ui/android/window_android.h" #include "ui/android/window_android.h"
#else // !OS_ANDROID #else // !OS_ANDROID
#include "chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.h" #include "chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.h"
#include "chrome/browser/ui/autofill/payments/verify_pending_dialog_controller_impl.h"
#include "chrome/browser/ui/autofill/payments/verify_pending_dialog_view.h"
#include "chrome/browser/ui/autofill/payments/webauthn_offer_dialog_controller_impl.h" #include "chrome/browser/ui/autofill/payments/webauthn_offer_dialog_controller_impl.h"
#include "chrome/browser/ui/autofill/payments/webauthn_offer_dialog_view.h" #include "chrome/browser/ui/autofill/payments/webauthn_offer_dialog_view.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
...@@ -268,6 +270,26 @@ void ChromeAutofillClient::ShowLocalCardMigrationResults( ...@@ -268,6 +270,26 @@ void ChromeAutofillClient::ShowLocalCardMigrationResults(
#endif #endif
} }
#if !defined(OS_ANDROID)
void ChromeAutofillClient::ShowVerifyPendingDialog(
base::OnceClosure cancel_card_verification_callback) {
autofill::VerifyPendingDialogControllerImpl::CreateForWebContents(
web_contents());
autofill::VerifyPendingDialogControllerImpl::FromWebContents(web_contents())
->ShowDialog(std::move(cancel_card_verification_callback));
}
void ChromeAutofillClient::CloseVerifyPendingDialog() {
VerifyPendingDialogControllerImpl* controller =
autofill::VerifyPendingDialogControllerImpl::FromWebContents(
web_contents());
if (!controller)
return;
controller->OnCardVerificationCompleted();
}
#endif
void ChromeAutofillClient::ShowWebauthnOfferDialog( void ChromeAutofillClient::ShowWebauthnOfferDialog(
WebauthnOfferDialogCallback callback) { WebauthnOfferDialogCallback callback) {
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
......
...@@ -86,6 +86,11 @@ class ChromeAutofillClient ...@@ -86,6 +86,11 @@ class ChromeAutofillClient
const base::string16& tip_message, const base::string16& tip_message,
const std::vector<MigratableCreditCard>& migratable_credit_cards, const std::vector<MigratableCreditCard>& migratable_credit_cards,
MigrationDeleteCardCallback delete_local_card_callback) override; MigrationDeleteCardCallback delete_local_card_callback) override;
#if !defined(OS_ANDROID)
void ShowVerifyPendingDialog(
base::OnceClosure cancel_card_verification_callback) override;
void CloseVerifyPendingDialog() override;
#endif // !defined(OS_ANDROID)
void ShowWebauthnOfferDialog(WebauthnOfferDialogCallback callback) override; void ShowWebauthnOfferDialog(WebauthnOfferDialogCallback callback) override;
bool CloseWebauthnOfferDialog() override; bool CloseWebauthnOfferDialog() override;
void UpdateWebauthnOfferDialogWithError() override; void UpdateWebauthnOfferDialogWithError() override;
......
// Copyright 2019 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_PAYMENTS_VERIFY_PENDING_DIALOG_CONTROLLER_H_
#define CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_VERIFY_PENDING_DIALOG_CONTROLLER_H_
#include "base/macros.h"
#include "base/strings/string16.h"
namespace autofill {
// An interface that exposes necessary controller functionality to
// VerifyPendingDialogView.
class VerifyPendingDialogController {
public:
VerifyPendingDialogController() = default;
virtual ~VerifyPendingDialogController() = default;
virtual base::string16 GetDialogTitle() const = 0;
virtual base::string16 GetCancelButtonLabel() const = 0;
virtual void OnCancel() = 0;
virtual void OnDialogClosed() = 0;
private:
DISALLOW_COPY_AND_ASSIGN(VerifyPendingDialogController);
};
} // namespace autofill
#endif // CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_VERIFY_PENDING_DIALOG_CONTROLLER_H_
// Copyright 2019 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/payments/verify_pending_dialog_controller_impl.h"
#include "chrome/browser/ui/autofill/payments/verify_pending_dialog_view.h"
#include "components/strings/grit/components_strings.h"
#include "ui/base/l10n/l10n_util.h"
namespace autofill {
VerifyPendingDialogControllerImpl::VerifyPendingDialogControllerImpl(
content::WebContents* web_contents)
: content::WebContentsObserver(web_contents) {}
VerifyPendingDialogControllerImpl::~VerifyPendingDialogControllerImpl() {
// If browser tab is closed when dialog is visible, the controller is
// destroyed before the view is, so need to reset view's reference to
// controller.
if (dialog_view_)
dialog_view_->Hide();
}
void VerifyPendingDialogControllerImpl::ShowDialog(
base::OnceClosure cancel_card_verification_callback) {
DCHECK(!dialog_view_);
cancel_card_verification_callback_ =
std::move(cancel_card_verification_callback);
dialog_view_ =
VerifyPendingDialogView::CreateDialogAndShow(this, web_contents());
}
void VerifyPendingDialogControllerImpl::OnCardVerificationCompleted() {
if (!dialog_view_)
return;
cancel_card_verification_callback_.Reset();
dialog_view_->Hide();
}
base::string16 VerifyPendingDialogControllerImpl::GetDialogTitle() const {
return l10n_util::GetStringUTF16(IDS_AUTOFILL_VERIFY_PENDING_DIALOG_TITLE);
}
base::string16 VerifyPendingDialogControllerImpl::GetCancelButtonLabel() const {
return l10n_util::GetStringUTF16(
IDS_AUTOFILL_VERIFY_PENDING_DIALOG_CANCEL_BUTTON_LABEL);
}
void VerifyPendingDialogControllerImpl::OnCancel() {
if (cancel_card_verification_callback_)
std::move(cancel_card_verification_callback_).Run();
}
void VerifyPendingDialogControllerImpl::OnDialogClosed() {
dialog_view_ = nullptr;
cancel_card_verification_callback_.Reset();
}
WEB_CONTENTS_USER_DATA_KEY_IMPL(VerifyPendingDialogControllerImpl)
} // namespace autofill
// Copyright 2019 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_PAYMENTS_VERIFY_PENDING_DIALOG_CONTROLLER_IMPL_H_
#define CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_VERIFY_PENDING_DIALOG_CONTROLLER_IMPL_H_
#include "base/macros.h"
#include "chrome/browser/ui/autofill/payments/verify_pending_dialog_controller.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
namespace autofill {
class VerifyPendingDialogView;
// Implementation of the per-tab controller to control the
// VerifyPendingDialogView. Lazily initialized when used.
class VerifyPendingDialogControllerImpl
: public VerifyPendingDialogController,
public content::WebContentsObserver,
public content::WebContentsUserData<VerifyPendingDialogControllerImpl> {
public:
~VerifyPendingDialogControllerImpl() override;
void ShowDialog(base::OnceClosure cancel_card_verification_callback);
// Close the dialog when card verification is completed.
void OnCardVerificationCompleted();
// VerifyPendingDialogController:
base::string16 GetDialogTitle() const override;
base::string16 GetCancelButtonLabel() const override;
void OnCancel() override;
void OnDialogClosed() override;
VerifyPendingDialogView* dialog_view() { return dialog_view_; }
protected:
explicit VerifyPendingDialogControllerImpl(
content::WebContents* web_contents);
private:
friend class content::WebContentsUserData<VerifyPendingDialogControllerImpl>;
// Callback invoked when the cancel button in the dialog is clicked. Will
// cancel the card verification in progress.
base::OnceClosure cancel_card_verification_callback_;
VerifyPendingDialogView* dialog_view_ = nullptr;
WEB_CONTENTS_USER_DATA_KEY_DECL();
DISALLOW_COPY_AND_ASSIGN(VerifyPendingDialogControllerImpl);
};
} // namespace autofill
#endif // CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_VERIFY_PENDING_DIALOG_CONTROLLER_IMPL_H_
// Copyright 2019 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_PAYMENTS_VERIFY_PENDING_DIALOG_VIEW_H_
#define CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_VERIFY_PENDING_DIALOG_VIEW_H_
namespace content {
class WebContents;
}
namespace autofill {
class VerifyPendingDialogController;
// The dialog to show card verification is in progress.
class VerifyPendingDialogView {
public:
// Factory function implemented by dialog's view implementation.
static VerifyPendingDialogView* CreateDialogAndShow(
VerifyPendingDialogController* controller,
content::WebContents* web_contents);
// Close the dialog and prevent callbacks being invoked.
virtual void Hide() = 0;
};
} // namespace autofill
#endif // CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_VERIFY_PENDING_DIALOG_VIEW_H_
// Copyright 2019 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/payments/verify_pending_dialog_controller_impl.h"
#include "chrome/browser/ui/autofill/payments/verify_pending_dialog_view.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/test/test_browser_dialog.h"
#include "chrome/browser/ui/views/autofill/payments/verify_pending_dialog_view_impl.h"
#include "ui/views/window/dialog_client_view.h"
namespace autofill {
class VerifyPendingDialogViewBrowserTest : public DialogBrowserTest {
public:
VerifyPendingDialogViewBrowserTest() = default;
// DialogBrowserTest:
void ShowUi(const std::string& name) override {
content::WebContents* web_contents =
browser()->tab_strip_model()->GetActiveWebContents();
// Do lazy initialization of VerifyPendingDialogControllerImpl.
VerifyPendingDialogControllerImpl::CreateForWebContents(web_contents);
controller_ =
VerifyPendingDialogControllerImpl::FromWebContents(web_contents);
DCHECK(controller_);
controller_->ShowDialog(base::DoNothing());
}
VerifyPendingDialogViewImpl* GetVerifyPendingDialog() {
if (!controller_)
return nullptr;
VerifyPendingDialogView* verify_pending_dialog_view =
controller_->dialog_view();
if (!verify_pending_dialog_view)
return nullptr;
return static_cast<VerifyPendingDialogViewImpl*>(
verify_pending_dialog_view);
}
VerifyPendingDialogControllerImpl* controller() { return controller_; }
private:
VerifyPendingDialogControllerImpl* controller_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(VerifyPendingDialogViewBrowserTest);
};
IN_PROC_BROWSER_TEST_F(VerifyPendingDialogViewBrowserTest, InvokeUi_default) {
ShowAndVerifyUi();
}
// This test ensures an edge case (closing tab while dialog being visible) is
// correctly handled, otherwise this test will crash during web contents being
// closed.
IN_PROC_BROWSER_TEST_F(VerifyPendingDialogViewBrowserTest,
CanCloseTabWhileDialogShowing) {
ShowUi(std::string());
VerifyUi();
browser()->tab_strip_model()->GetActiveWebContents()->Close();
base::RunLoop().RunUntilIdle();
}
// Ensures closing browser while dialog being visible is correctly handled.
IN_PROC_BROWSER_TEST_F(VerifyPendingDialogViewBrowserTest,
CanCloseBrowserWhileDialogShowing) {
ShowUi(std::string());
VerifyUi();
browser()->window()->Close();
base::RunLoop().RunUntilIdle();
}
// Ensures dialog is closed when cancel button is clicked.
IN_PROC_BROWSER_TEST_F(VerifyPendingDialogViewBrowserTest, ClickCancelButton) {
ShowUi(std::string());
VerifyUi();
GetVerifyPendingDialog()->GetDialogClientView()->CancelWindow();
base::RunLoop().RunUntilIdle();
}
// TODO(crbug.com/991037): Add more browser tests:
// 1. Make sure callback runs if cancel button clicked.
} // namespace autofill
// Copyright 2019 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/views/autofill/payments/verify_pending_dialog_view_impl.h"
#include "chrome/browser/ui/autofill/payments/verify_pending_dialog_controller.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "components/constrained_window/constrained_window_views.h"
#include "ui/views/bubble/bubble_frame_view.h"
#include "ui/views/window/dialog_client_view.h"
namespace autofill {
VerifyPendingDialogViewImpl::VerifyPendingDialogViewImpl(
VerifyPendingDialogController* controller)
: controller_(controller) {
// TODO(crbug.com/1014278): Should get correct width automatically when
// snapping.
const int width = ChromeLayoutProvider::Get()->GetDistanceMetric(
DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH);
// TODO(crbug.com/1014334): Investigate why CalculatePreferredSize can not be
// overridden when there is no layout manager.
SetPreferredSize(gfx::Size(width, GetHeightForWidth(width)));
}
VerifyPendingDialogViewImpl::~VerifyPendingDialogViewImpl() {
if (controller_) {
controller_->OnDialogClosed();
controller_ = nullptr;
}
}
VerifyPendingDialogView* VerifyPendingDialogView::CreateDialogAndShow(
VerifyPendingDialogController* controller,
content::WebContents* web_contents) {
VerifyPendingDialogViewImpl* dialog =
new VerifyPendingDialogViewImpl(controller);
constrained_window::ShowWebModalDialogViews(dialog, web_contents);
return dialog;
}
void VerifyPendingDialogViewImpl::Hide() {
if (controller_) {
controller_->OnDialogClosed();
controller_ = nullptr;
}
GetWidget()->Close();
}
void VerifyPendingDialogViewImpl::AddedToWidget() {
GetBubbleFrameView()->SetProgress(/*Infinite animation*/ -1);
}
bool VerifyPendingDialogViewImpl::Cancel() {
controller_->OnCancel();
return true;
}
int VerifyPendingDialogViewImpl::GetDialogButtons() const {
return ui::DIALOG_BUTTON_CANCEL;
}
base::string16 VerifyPendingDialogViewImpl::GetDialogButtonLabel(
ui::DialogButton button) const {
DCHECK_EQ(button, ui::DIALOG_BUTTON_CANCEL);
return controller_->GetCancelButtonLabel();
}
ui::ModalType VerifyPendingDialogViewImpl::GetModalType() const {
return ui::MODAL_TYPE_CHILD;
}
base::string16 VerifyPendingDialogViewImpl::GetWindowTitle() const {
return controller_->GetDialogTitle();
}
bool VerifyPendingDialogViewImpl::ShouldShowCloseButton() const {
return false;
}
} // namespace autofill
// Copyright 2019 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_VIEWS_AUTOFILL_PAYMENTS_VERIFY_PENDING_DIALOG_VIEW_IMPL_H_
#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_VERIFY_PENDING_DIALOG_VIEW_IMPL_H_
#include "base/macros.h"
#include "chrome/browser/ui/autofill/payments/verify_pending_dialog_view.h"
#include "ui/views/window/dialog_delegate.h"
namespace autofill {
class VerifyPendingDialogController;
// The Views implementation of the dialog that shows the card verification is in
// progress. It is shown when card verification process starts only if WebAuthn
// has been enabled and opted in.
class VerifyPendingDialogViewImpl : public VerifyPendingDialogView,
public views::DialogDelegateView {
public:
explicit VerifyPendingDialogViewImpl(
VerifyPendingDialogController* controller);
~VerifyPendingDialogViewImpl() override;
// VerifyPendingDialogView:
void Hide() override;
// views::DialogDelegateView:
void AddedToWidget() override;
bool Cancel() override;
int GetDialogButtons() const override;
base::string16 GetDialogButtonLabel(ui::DialogButton button) const override;
ui::ModalType GetModalType() const override;
base::string16 GetWindowTitle() const override;
bool ShouldShowCloseButton() const override;
private:
VerifyPendingDialogController* controller_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(VerifyPendingDialogViewImpl);
};
} // namespace autofill
#endif // CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_VERIFY_PENDING_DIALOG_VIEW_IMPL_H_
...@@ -1271,6 +1271,7 @@ if (!is_android) { ...@@ -1271,6 +1271,7 @@ if (!is_android) {
"../browser/ui/toolbar/browser_actions_bar_browsertest.h", "../browser/ui/toolbar/browser_actions_bar_browsertest.h",
"../browser/ui/update_chrome_dialog_browsertest.cc", "../browser/ui/update_chrome_dialog_browsertest.cc",
"../browser/ui/views/apps/app_info_dialog/app_info_dialog_views_browsertest.cc", "../browser/ui/views/apps/app_info_dialog/app_info_dialog_views_browsertest.cc",
"../browser/ui/views/autofill/payments/verify_pending_dialog_view_browsertest.cc",
"../browser/ui/views/bookmarks/bookmark_bar_view_browsertest.cc", "../browser/ui/views/bookmarks/bookmark_bar_view_browsertest.cc",
"../browser/ui/views/chrome_cleaner_dialog_browsertest_win.cc", "../browser/ui/views/chrome_cleaner_dialog_browsertest_win.cc",
"../browser/ui/views/chrome_cleaner_reboot_dialog_browsertest_win.cc", "../browser/ui/views/chrome_cleaner_reboot_dialog_browsertest_win.cc",
......
...@@ -306,9 +306,21 @@ class AutofillClient : public RiskDataLoader { ...@@ -306,9 +306,21 @@ class AutofillClient : public RiskDataLoader {
const std::vector<MigratableCreditCard>& migratable_credit_cards, const std::vector<MigratableCreditCard>& migratable_credit_cards,
MigrationDeleteCardCallback delete_local_card_callback) = 0; MigrationDeleteCardCallback delete_local_card_callback) = 0;
#if !defined(OS_ANDROID) && !defined(OS_IOS)
// Will show a dialog indicating the card verification is in progress. It is
// shown after verification starts only if the WebAuthn is enabled.
// Implemented only on desktop.
virtual void ShowVerifyPendingDialog(
base::OnceClosure cancel_card_verification_callback) = 0;
// Close the verify pending dialog once the card verificiation is completed or
// verification falls back to CVC.
virtual void CloseVerifyPendingDialog() = 0;
#endif
// Will show a dialog offering the option to use device's platform // Will show a dialog offering the option to use device's platform
// authenticator in the future instead of CVC to verify the card being // authenticator in the future instead of CVC to verify the card being
// unmasked. Runs |callback| is the OK button or the cancel button in the // unmasked. Runs |callback| if the OK button or the cancel button in the
// dialog is clicked. This is only implemented on desktop. // dialog is clicked. This is only implemented on desktop.
virtual void ShowWebauthnOfferDialog( virtual void ShowWebauthnOfferDialog(
WebauthnOfferDialogCallback callback) = 0; WebauthnOfferDialogCallback callback) = 0;
......
...@@ -307,6 +307,11 @@ void CreditCardAccessManager::FetchCreditCard( ...@@ -307,6 +307,11 @@ void CreditCardAccessManager::FetchCreditCard(
} }
#endif #endif
if (AuthenticationRequiresUnmaskDetails() && !get_unmask_details_returned) { if (AuthenticationRequiresUnmaskDetails() && !get_unmask_details_returned) {
// On desktop, shows the verify pending dialog.
#if !defined(OS_ANDROID) && !defined(OS_IOS)
ShowVerifyPendingDialog();
#endif
// Wait for |ready_to_start_authentication_| to be signaled by // Wait for |ready_to_start_authentication_| to be signaled by
// OnDidGetUnmaskDetails() or until timeout before calling Authenticate(). // OnDidGetUnmaskDetails() or until timeout before calling Authenticate().
base::PostTaskAndReplyWithResult( base::PostTaskAndReplyWithResult(
...@@ -388,6 +393,11 @@ void CreditCardAccessManager::Authenticate(bool get_unmask_details_returned) { ...@@ -388,6 +393,11 @@ void CreditCardAccessManager::Authenticate(bool get_unmask_details_returned) {
std::move(unmask_details_.fido_request_options)); std::move(unmask_details_.fido_request_options));
#endif #endif
} else { } else {
#if !defined(OS_ANDROID) && !defined(OS_IOS)
// Close the verify pending dialog if it enters CVC authentication flow
// since the card unmask prompt will pop up.
client_->CloseVerifyPendingDialog();
#endif
GetOrCreateCVCAuthenticator()->Authenticate( GetOrCreateCVCAuthenticator()->Authenticate(
card_, weak_ptr_factory_.GetWeakPtr(), personal_data_manager_, card_, weak_ptr_factory_.GetWeakPtr(), personal_data_manager_,
form_parsed_timestamp_); form_parsed_timestamp_);
...@@ -467,6 +477,13 @@ void CreditCardAccessManager::OnCVCAuthenticationComplete( ...@@ -467,6 +477,13 @@ void CreditCardAccessManager::OnCVCAuthenticationComplete(
void CreditCardAccessManager::OnFIDOAuthenticationComplete( void CreditCardAccessManager::OnFIDOAuthenticationComplete(
bool did_succeed, bool did_succeed,
const CreditCard* card) { const CreditCard* card) {
#if !defined(OS_ANDROID)
// Close the verify pending dialog. If FIDO authentication succeeded, card is
// filled to the form, otherwise fall back to CVC authentication which does
// not need the verify pending dialog either.
client_->CloseVerifyPendingDialog();
#endif
if (did_succeed) { if (did_succeed) {
is_authentication_in_progress_ = false; is_authentication_in_progress_ = false;
accessor_->OnCreditCardFetched(did_succeed, card); accessor_->OnCreditCardFetched(did_succeed, card);
...@@ -481,6 +498,10 @@ void CreditCardAccessManager::OnFIDOAuthenticationComplete( ...@@ -481,6 +498,10 @@ void CreditCardAccessManager::OnFIDOAuthenticationComplete(
} }
#endif #endif
bool CreditCardAccessManager::IsLocalCard(const CreditCard* card) {
return card && card->record_type() == CreditCard::LOCAL_CARD;
}
bool CreditCardAccessManager::AuthenticationRequiresUnmaskDetails() { bool CreditCardAccessManager::AuthenticationRequiresUnmaskDetails() {
#if defined(OS_IOS) #if defined(OS_IOS)
return false; return false;
...@@ -490,8 +511,18 @@ bool CreditCardAccessManager::AuthenticationRequiresUnmaskDetails() { ...@@ -490,8 +511,18 @@ bool CreditCardAccessManager::AuthenticationRequiresUnmaskDetails() {
#endif #endif
} }
bool CreditCardAccessManager::IsLocalCard(const CreditCard* card) { #if !defined(OS_ANDROID) && !defined(OS_IOS)
return card && card->record_type() == CreditCard::LOCAL_CARD; void CreditCardAccessManager::ShowVerifyPendingDialog() {
client_->ShowVerifyPendingDialog(
base::BindOnce(&CreditCardAccessManager::OnDidCancelCardVerification,
weak_ptr_factory_.GetWeakPtr()));
}
void CreditCardAccessManager::OnDidCancelCardVerification() {
payments_client_->CancelRequest();
unmask_details_request_in_progress_ = false;
is_authentication_in_progress_ = false;
} }
#endif
} // namespace autofill } // namespace autofill
...@@ -161,6 +161,16 @@ class CreditCardAccessManager : public CreditCardCVCAuthenticator::Requester, ...@@ -161,6 +161,16 @@ class CreditCardAccessManager : public CreditCardCVCAuthenticator::Requester,
// immediately. // immediately.
bool AuthenticationRequiresUnmaskDetails(); bool AuthenticationRequiresUnmaskDetails();
#if !defined(OS_ANDROID) && !defined(OS_IOS)
// After card verification starts, shows the verify pending dialog if WebAuthn
// is enabled, indicating some verification steps are in progress.
void ShowVerifyPendingDialog();
// The callback function invoked when the cancel button in the verify pending
// dialog is clicked. Will cancel the attempt to fetch unmask details.
void OnDidCancelCardVerification();
#endif
// Is set to true only when waiting for the callback to // Is set to true only when waiting for the callback to
// OnCVCAuthenticationComplete() to be executed. // OnCVCAuthenticationComplete() to be executed.
bool is_authentication_in_progress_ = false; bool is_authentication_in_progress_ = false;
......
...@@ -107,6 +107,13 @@ void TestAutofillClient::ShowLocalCardMigrationResults( ...@@ -107,6 +107,13 @@ void TestAutofillClient::ShowLocalCardMigrationResults(
const std::vector<MigratableCreditCard>& migratable_credit_cards, const std::vector<MigratableCreditCard>& migratable_credit_cards,
MigrationDeleteCardCallback delete_local_card_callback) {} MigrationDeleteCardCallback delete_local_card_callback) {}
#if !defined(OS_ANDROID) && !defined(OS_IOS)
void TestAutofillClient::ShowVerifyPendingDialog(
base::OnceClosure cancel_card_verification_callback) {}
void TestAutofillClient::CloseVerifyPendingDialog() {}
#endif
void TestAutofillClient::ShowWebauthnOfferDialog( void TestAutofillClient::ShowWebauthnOfferDialog(
WebauthnOfferDialogCallback callback) {} WebauthnOfferDialogCallback callback) {}
......
...@@ -65,6 +65,11 @@ class TestAutofillClient : public AutofillClient { ...@@ -65,6 +65,11 @@ class TestAutofillClient : public AutofillClient {
const base::string16& tip_message, const base::string16& tip_message,
const std::vector<MigratableCreditCard>& migratable_credit_cards, const std::vector<MigratableCreditCard>& migratable_credit_cards,
MigrationDeleteCardCallback delete_local_card_callback) override; MigrationDeleteCardCallback delete_local_card_callback) override;
#if !defined(OS_ANDROID) && !defined(OS_IOS)
void ShowVerifyPendingDialog(
base::OnceClosure cancel_card_verification_callback) override;
void CloseVerifyPendingDialog() override;
#endif
void ShowWebauthnOfferDialog(WebauthnOfferDialogCallback callback) override; void ShowWebauthnOfferDialog(WebauthnOfferDialogCallback callback) override;
bool CloseWebauthnOfferDialog() override; bool CloseWebauthnOfferDialog() override;
void ConfirmSaveAutofillProfile(const AutofillProfile& profile, void ConfirmSaveAutofillProfile(const AutofillProfile& profile,
......
...@@ -502,6 +502,17 @@ ...@@ -502,6 +502,17 @@
</message> </message>
</if> </if>
<!-- Verify pending dialog (Desktop only) -->
<if expr="not is_ios and not is_android">
<message name="IDS_AUTOFILL_VERIFY_PENDING_DIALOG_TITLE" desc="Headline showing the card verification is in progress.">
Verifying your identity...
</message>
<message name="IDS_AUTOFILL_VERIFY_PENDING_DIALOG_CANCEL_BUTTON_LABEL" desc="Button that allows the user to cancel the card verification.">
Cancel
</message>
</if>
<message name="IDS_AUTOFILL_WALLET_MANAGEMENT_LINK_TEXT" desc="Text for link that allows users to see and edit their Wallet information." formatter_data="android_java"> <message name="IDS_AUTOFILL_WALLET_MANAGEMENT_LINK_TEXT" desc="Text for link that allows users to see and edit their Wallet information." formatter_data="android_java">
Edit Edit
</message> </message>
......
...@@ -460,12 +460,6 @@ void BubbleDialogDelegateView::SizeToContents() { ...@@ -460,12 +460,6 @@ void BubbleDialogDelegateView::SizeToContents() {
GetWidget()->SetBounds(bubble_bounds); GetWidget()->SetBounds(bubble_bounds);
} }
BubbleFrameView* BubbleDialogDelegateView::GetBubbleFrameView() const {
const NonClientView* view =
GetWidget() ? GetWidget()->non_client_view() : nullptr;
return view ? static_cast<BubbleFrameView*>(view->frame_view()) : nullptr;
}
void BubbleDialogDelegateView::UpdateColorsFromTheme() { void BubbleDialogDelegateView::UpdateColorsFromTheme() {
if (!color_explicitly_set_) if (!color_explicitly_set_)
color_ = GetNativeTheme()->GetSystemColor( color_ = GetNativeTheme()->GetSystemColor(
......
...@@ -36,7 +36,6 @@ class PageAgentViews; ...@@ -36,7 +36,6 @@ class PageAgentViews;
namespace views { namespace views {
class BubbleFrameView;
class Button; class Button;
// BubbleDialogDelegateView is a special DialogDelegateView for bubbles. // BubbleDialogDelegateView is a special DialogDelegateView for bubbles.
...@@ -187,8 +186,6 @@ class VIEWS_EXPORT BubbleDialogDelegateView : public DialogDelegateView, ...@@ -187,8 +186,6 @@ class VIEWS_EXPORT BubbleDialogDelegateView : public DialogDelegateView,
// Resize and potentially move the bubble to fit the content's preferred size. // Resize and potentially move the bubble to fit the content's preferred size.
virtual void SizeToContents(); virtual void SizeToContents();
BubbleFrameView* GetBubbleFrameView() const;
// Allows the up and down arrow keys to tab between items. // Allows the up and down arrow keys to tab between items.
void EnableUpDownKeyboardAccelerators(); void EnableUpDownKeyboardAccelerators();
......
...@@ -197,6 +197,7 @@ ClientView* DialogDelegate::CreateClientView(Widget* widget) { ...@@ -197,6 +197,7 @@ ClientView* DialogDelegate::CreateClientView(Widget* widget) {
NonClientFrameView* DialogDelegate::CreateNonClientFrameView(Widget* widget) { NonClientFrameView* DialogDelegate::CreateNonClientFrameView(Widget* widget) {
if (use_custom_frame()) if (use_custom_frame())
return CreateDialogFrameView(widget); return CreateDialogFrameView(widget);
return WidgetDelegate::CreateNonClientFrameView(widget); return WidgetDelegate::CreateNonClientFrameView(widget);
} }
...@@ -237,6 +238,15 @@ DialogClientView* DialogDelegate::GetDialogClientView() { ...@@ -237,6 +238,15 @@ DialogClientView* DialogDelegate::GetDialogClientView() {
return GetWidget()->client_view()->AsDialogClientView(); return GetWidget()->client_view()->AsDialogClientView();
} }
BubbleFrameView* DialogDelegate::GetBubbleFrameView() const {
if (!use_custom_frame())
return nullptr;
const NonClientView* view =
GetWidget() ? GetWidget()->non_client_view() : nullptr;
return view ? static_cast<BubbleFrameView*>(view->frame_view()) : nullptr;
}
views::LabelButton* DialogDelegate::GetOkButton() { views::LabelButton* DialogDelegate::GetOkButton() {
DCHECK(GetWidget()) << "Don't call this before OnDialogInitialized"; DCHECK(GetWidget()) << "Don't call this before OnDialogInitialized";
auto* client = GetDialogClientView(); auto* client = GetDialogClientView();
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
namespace views { namespace views {
class BubbleFrameView;
class DialogClientView; class DialogClientView;
class DialogObserver; class DialogObserver;
class LabelButton; class LabelButton;
...@@ -155,6 +156,10 @@ class VIEWS_EXPORT DialogDelegate : public WidgetDelegate { ...@@ -155,6 +156,10 @@ class VIEWS_EXPORT DialogDelegate : public WidgetDelegate {
const DialogClientView* GetDialogClientView() const; const DialogClientView* GetDialogClientView() const;
DialogClientView* GetDialogClientView(); DialogClientView* GetDialogClientView();
// Returns the BubbleFrameView of this dialog delegate. A bubble frame view
// will only be created when use_custom_frame() is true.
BubbleFrameView* GetBubbleFrameView() const;
// Helpers for accessing parts of the DialogClientView without needing to know // Helpers for accessing parts of the DialogClientView without needing to know
// about DialogClientView. Do not call these before OnDialogInitialized. // about DialogClientView. Do not call these before OnDialogInitialized.
views::LabelButton* GetOkButton(); views::LabelButton* GetOkButton();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment