Commit 9fc875c6 authored by Nick Burris's avatar Nick Burris Committed by Commit Bot

[SecurePaymentConfirmation] Add header view

Add the header icon and progress bar to the secure payment confirmation
dialog. Before this patch, the header icon was a property of the model.
Since the model lives in //components, but the icon comes from //chrome,
it's awkward for the controller to get the icon from the view just to
pass a pointer to the model for the view to dereference later. See patch
set 3 for what this looks like. Since the icon is specific to the
SecurePaymentConfirmationDialogView implementation anyway, this patch
removes the icon from the model and keeps the logic local to the view.

Bug: 1110322
Change-Id: I8681bc00c4d48d1b98f3c939f920b5ea44f0ff02
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2358821
Commit-Queue: Nick Burris <nburris@chromium.org>
Reviewed-by: default avatarRouslan Solomakhin <rouslan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#799873}
parent 2c5847f9
...@@ -4,11 +4,25 @@ ...@@ -4,11 +4,25 @@
#include "chrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view.h" #include "chrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view.h"
#include "chrome/app/vector_icons/vector_icons.h"
#include "chrome/browser/ui/views/accessibility/non_accessible_image_view.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "components/constrained_window/constrained_window_views.h" #include "components/constrained_window/constrained_window_views.h"
#include "components/payments/content/secure_payment_confirmation_model.h" #include "components/payments/content/secure_payment_confirmation_model.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/views/controls/progress_bar.h"
#include "ui/views/layout/box_layout.h"
namespace payments { namespace payments {
namespace {
// Height of the header icon.
constexpr int kHeaderIconHeight = 148;
// Height of the progress bar at the top of the dialog.
constexpr int kProgressBarHeight = 4;
} // namespace
SecurePaymentConfirmationDialogView::SecurePaymentConfirmationDialogView( SecurePaymentConfirmationDialogView::SecurePaymentConfirmationDialogView(
ObserverForTest* observer_for_test) ObserverForTest* observer_for_test)
...@@ -24,14 +38,9 @@ void SecurePaymentConfirmationDialogView::ShowDialog( ...@@ -24,14 +38,9 @@ void SecurePaymentConfirmationDialogView::ShowDialog(
DCHECK(model); DCHECK(model);
model_ = model; model_ = model;
OnModelUpdated(); InitChildViews();
// Set the dialog size. This is just for demonstration and will no longer be OnModelUpdated();
// necessary once the layout is complete.
const int dialog_width = ChromeLayoutProvider::Get()->GetDistanceMetric(
DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH);
const gfx::Size dialog_size(dialog_width, 300);
SetPreferredSize(dialog_size);
verify_callback_ = std::move(verify_callback); verify_callback_ = std::move(verify_callback);
cancel_callback_ = std::move(cancel_callback); cancel_callback_ = std::move(cancel_callback);
...@@ -79,6 +88,11 @@ void SecurePaymentConfirmationDialogView::OnDialogClosed() { ...@@ -79,6 +88,11 @@ void SecurePaymentConfirmationDialogView::OnDialogClosed() {
} }
void SecurePaymentConfirmationDialogView::OnModelUpdated() { void SecurePaymentConfirmationDialogView::OnModelUpdated() {
// Changing the progress bar visibility does not invalidate layout as it is
// absolutely positioned.
if (progress_bar_)
progress_bar_->SetVisible(model_->progress_bar_visible());
SetButtonLabel(ui::DIALOG_BUTTON_OK, model_->verify_button_label()); SetButtonLabel(ui::DIALOG_BUTTON_OK, model_->verify_button_label());
SetButtonEnabled(ui::DIALOG_BUTTON_OK, model_->verify_button_enabled()); SetButtonEnabled(ui::DIALOG_BUTTON_OK, model_->verify_button_enabled());
SetButtonLabel(ui::DIALOG_BUTTON_CANCEL, model_->cancel_button_label()); SetButtonLabel(ui::DIALOG_BUTTON_CANCEL, model_->cancel_button_label());
...@@ -86,7 +100,8 @@ void SecurePaymentConfirmationDialogView::OnModelUpdated() { ...@@ -86,7 +100,8 @@ void SecurePaymentConfirmationDialogView::OnModelUpdated() {
} }
void SecurePaymentConfirmationDialogView::HideDialog() { void SecurePaymentConfirmationDialogView::HideDialog() {
GetWidget()->Close(); if (GetWidget())
GetWidget()->Close();
} }
ui::ModalType SecurePaymentConfirmationDialogView::GetModalType() const { ui::ModalType SecurePaymentConfirmationDialogView::GetModalType() const {
...@@ -102,4 +117,58 @@ SecurePaymentConfirmationDialogView::GetWeakPtr() { ...@@ -102,4 +117,58 @@ SecurePaymentConfirmationDialogView::GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr(); return weak_ptr_factory_.GetWeakPtr();
} }
const gfx::VectorIcon&
SecurePaymentConfirmationDialogView::GetFingerprintIcon() {
return GetNativeTheme()->ShouldUseDarkColors() ? kWebauthnFingerprintDarkIcon
: kWebauthnFingerprintIcon;
}
void SecurePaymentConfirmationDialogView::InitChildViews() {
RemoveAllChildViews(true);
SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical, gfx::Insets(), 0));
std::unique_ptr<views::View> header_icon = CreateHeaderView();
AddChildView(header_icon.release());
InvalidateLayout();
}
std::unique_ptr<views::View>
SecurePaymentConfirmationDialogView::CreateHeaderView() {
const int header_width = ChromeLayoutProvider::Get()->GetDistanceMetric(
DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH);
const gfx::Size header_size(header_width, kHeaderIconHeight);
// The container view has no layout, so its preferred size is hardcoded to
// match the size of the image, and the progress bar overlay is absolutely
// positioned.
auto header_view = std::make_unique<views::View>();
header_view->SetPreferredSize(header_size);
// Fingerprint header icon
auto image_view = std::make_unique<NonAccessibleImageView>();
gfx::IconDescription icon_description(GetFingerprintIcon());
image_view->SetImage(gfx::CreateVectorIcon(icon_description));
image_view->SetSize(header_size);
image_view->SetVerticalAlignment(views::ImageView::Alignment::kLeading);
image_view->SetID(DialogViewID::HEADER_ICON);
header_view->AddChildView(image_view.release());
// Progress bar
auto progress_bar = std::make_unique<views::ProgressBar>(
kProgressBarHeight, /*allow_round_corner=*/false);
progress_bar->SetValue(-1); // infinite animation.
progress_bar->SetBackgroundColor(SK_ColorTRANSPARENT);
progress_bar->SetPreferredSize(gfx::Size(header_width, kProgressBarHeight));
progress_bar->SizeToPreferredSize();
progress_bar->SetID(DialogViewID::PROGRESS_BAR);
progress_bar->SetVisible(model_->progress_bar_visible());
progress_bar_ = progress_bar.get();
header_view->AddChildView(progress_bar.release());
return header_view;
}
} // namespace payments } // namespace payments
...@@ -7,8 +7,17 @@ ...@@ -7,8 +7,17 @@
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "components/payments/content/secure_payment_confirmation_view.h" #include "components/payments/content/secure_payment_confirmation_view.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/window/dialog_delegate.h" #include "ui/views/window/dialog_delegate.h"
namespace gfx {
struct VectorIcon;
}
namespace views {
class ProgressBar;
}
namespace payments { namespace payments {
// Draws the user interface in the secure payment confirmation flow. Owned by // Draws the user interface in the secure payment confirmation flow. Owned by
...@@ -25,6 +34,10 @@ class SecurePaymentConfirmationDialogView ...@@ -25,6 +34,10 @@ class SecurePaymentConfirmationDialogView
virtual void OnCancelButtonPressed() = 0; virtual void OnCancelButtonPressed() = 0;
}; };
// IDs that identify a view within the secure payment confirmation dialog.
// Used to validate views in browsertests.
enum DialogViewID : int { VIEW_ID_NONE = 0, HEADER_ICON, PROGRESS_BAR };
explicit SecurePaymentConfirmationDialogView( explicit SecurePaymentConfirmationDialogView(
ObserverForTest* observer_for_test); ObserverForTest* observer_for_test);
~SecurePaymentConfirmationDialogView() override; ~SecurePaymentConfirmationDialogView() override;
...@@ -50,12 +63,20 @@ class SecurePaymentConfirmationDialogView ...@@ -50,12 +63,20 @@ class SecurePaymentConfirmationDialogView
void OnDialogCancelled(); void OnDialogCancelled();
void OnDialogClosed(); void OnDialogClosed();
const gfx::VectorIcon& GetFingerprintIcon();
void InitChildViews();
std::unique_ptr<views::View> CreateHeaderView();
// May be null. // May be null.
ObserverForTest* observer_for_test_; ObserverForTest* observer_for_test_ = nullptr;
VerifyCallback verify_callback_; VerifyCallback verify_callback_;
CancelCallback cancel_callback_; CancelCallback cancel_callback_;
views::ProgressBar* progress_bar_ = nullptr;
base::WeakPtrFactory<SecurePaymentConfirmationDialogView> weak_ptr_factory_{ base::WeakPtrFactory<SecurePaymentConfirmationDialogView> weak_ptr_factory_{
this}; this};
}; };
......
...@@ -57,14 +57,23 @@ class SecurePaymentConfirmationDialogViewTest ...@@ -57,14 +57,23 @@ class SecurePaymentConfirmationDialogViewTest
void ExpectViewMatchesModel() { void ExpectViewMatchesModel() {
ASSERT_NE(test_delegate_->dialog_view(), nullptr); ASSERT_NE(test_delegate_->dialog_view(), nullptr);
EXPECT_EQ(l10n_util::GetStringUTF16( EXPECT_EQ(model_.verify_button_label(),
IDS_SECURE_PAYMENT_CONFIRMATION_VERIFY_BUTTON_LABEL),
test_delegate_->dialog_view()->GetDialogButtonLabel( test_delegate_->dialog_view()->GetDialogButtonLabel(
ui::DIALOG_BUTTON_OK)); ui::DIALOG_BUTTON_OK));
EXPECT_EQ(l10n_util::GetStringUTF16(IDS_CANCEL), EXPECT_EQ(model_.cancel_button_label(),
test_delegate_->dialog_view()->GetDialogButtonLabel( test_delegate_->dialog_view()->GetDialogButtonLabel(
ui::DIALOG_BUTTON_CANCEL)); ui::DIALOG_BUTTON_CANCEL));
EXPECT_TRUE(test_delegate_->dialog_view()->GetViewByID(
SecurePaymentConfirmationDialogView::DialogViewID::HEADER_ICON));
EXPECT_EQ(
model_.progress_bar_visible(),
test_delegate_->dialog_view()
->GetViewByID(
SecurePaymentConfirmationDialogView::DialogViewID::PROGRESS_BAR)
->GetVisible());
} }
void ClickAcceptAndWait() { void ClickAcceptAndWait() {
...@@ -161,4 +170,34 @@ IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationDialogViewTest, ...@@ -161,4 +170,34 @@ IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationDialogViewTest,
CloseDialogAndWait(); CloseDialogAndWait();
} }
IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationDialogViewTest,
ProgressBarVisible) {
CreateModel();
model_.set_progress_bar_visible(true);
InvokeSecurePaymentConfirmationUI();
ExpectViewMatchesModel();
CloseDialogAndWait();
}
IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationDialogViewTest,
ShowProgressBar) {
CreateModel();
ASSERT_FALSE(model_.progress_bar_visible());
InvokeSecurePaymentConfirmationUI();
ExpectViewMatchesModel();
model_.set_progress_bar_visible(true);
test_delegate_->dialog_view()->OnModelUpdated();
ExpectViewMatchesModel();
CloseDialogAndWait();
}
} // namespace payments } // namespace payments
...@@ -32,6 +32,7 @@ void SecurePaymentConfirmationController::ShowDialog( ...@@ -32,6 +32,7 @@ void SecurePaymentConfirmationController::ShowDialog(
model_.set_verify_button_label(l10n_util::GetStringUTF16( model_.set_verify_button_label(l10n_util::GetStringUTF16(
IDS_SECURE_PAYMENT_CONFIRMATION_VERIFY_BUTTON_LABEL)); IDS_SECURE_PAYMENT_CONFIRMATION_VERIFY_BUTTON_LABEL));
model_.set_cancel_button_label(l10n_util::GetStringUTF16(IDS_CANCEL)); model_.set_cancel_button_label(l10n_util::GetStringUTF16(IDS_CANCEL));
model_.set_progress_bar_visible(false);
view_->ShowDialog( view_->ShowDialog(
request->web_contents(), model_.GetWeakPtr(), request->web_contents(), model_.GetWeakPtr(),
...@@ -42,10 +43,19 @@ void SecurePaymentConfirmationController::ShowDialog( ...@@ -42,10 +43,19 @@ void SecurePaymentConfirmationController::ShowDialog(
} }
void SecurePaymentConfirmationController::CloseDialog() { void SecurePaymentConfirmationController::CloseDialog() {
if (!view_)
return;
view_->HideDialog(); view_->HideDialog();
} }
void SecurePaymentConfirmationController::ShowProcessingSpinner() {} void SecurePaymentConfirmationController::ShowProcessingSpinner() {
if (!view_)
return;
model_.set_progress_bar_visible(true);
view_->OnModelUpdated();
}
void SecurePaymentConfirmationController::OnDismiss() {} void SecurePaymentConfirmationController::OnDismiss() {}
......
...@@ -9,10 +9,6 @@ ...@@ -9,10 +9,6 @@
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkBitmap.h"
namespace gfx {
struct VectorIcon;
}
namespace payments { namespace payments {
// The data model for the secure payment confirmation flow. Owned by the // The data model for the secure payment confirmation flow. Owned by the
...@@ -28,12 +24,6 @@ class SecurePaymentConfirmationModel { ...@@ -28,12 +24,6 @@ class SecurePaymentConfirmationModel {
SecurePaymentConfirmationModel& operator=( SecurePaymentConfirmationModel& operator=(
const SecurePaymentConfirmationModel& other) = delete; const SecurePaymentConfirmationModel& other) = delete;
// The header icon to be displayed, e.g. a fingerprint icon.
const gfx::VectorIcon* header_icon() const { return header_icon_; }
void set_header_icon(const gfx::VectorIcon* header_icon) {
header_icon_ = header_icon;
}
// Title, e.g. "Use TouchID to verify and complete your purchase?" // Title, e.g. "Use TouchID to verify and complete your purchase?"
const base::string16& title() const { return title_; } const base::string16& title() const { return title_; }
void set_title(const base::string16& title) { title_ = title; } void set_title(const base::string16& title) { title_ = title; }
...@@ -129,8 +119,6 @@ class SecurePaymentConfirmationModel { ...@@ -129,8 +119,6 @@ class SecurePaymentConfirmationModel {
base::WeakPtr<SecurePaymentConfirmationModel> GetWeakPtr(); base::WeakPtr<SecurePaymentConfirmationModel> GetWeakPtr();
private: private:
const gfx::VectorIcon* header_icon_ = nullptr;
base::string16 title_; base::string16 title_;
base::string16 merchant_label_; base::string16 merchant_label_;
......
...@@ -17,7 +17,6 @@ class SecurePaymentConfirmationModelTest : public testing::Test {}; ...@@ -17,7 +17,6 @@ class SecurePaymentConfirmationModelTest : public testing::Test {};
TEST_F(SecurePaymentConfirmationModelTest, SmokeTest) { TEST_F(SecurePaymentConfirmationModelTest, SmokeTest) {
SecurePaymentConfirmationModel model; SecurePaymentConfirmationModel model;
gfx::VectorIcon header_icon;
base::string16 title( base::string16 title(
base::UTF8ToUTF16("Use Touch ID to verify and complete your purchase?")); base::UTF8ToUTF16("Use Touch ID to verify and complete your purchase?"));
base::string16 merchant_label(base::UTF8ToUTF16("Store")); base::string16 merchant_label(base::UTF8ToUTF16("Store"));
...@@ -30,9 +29,6 @@ TEST_F(SecurePaymentConfirmationModelTest, SmokeTest) { ...@@ -30,9 +29,6 @@ TEST_F(SecurePaymentConfirmationModelTest, SmokeTest) {
base::string16 verify_button_label(base::UTF8ToUTF16("Verify")); base::string16 verify_button_label(base::UTF8ToUTF16("Verify"));
base::string16 cancel_button_label(base::UTF8ToUTF16("Cancel")); base::string16 cancel_button_label(base::UTF8ToUTF16("Cancel"));
model.set_header_icon(&header_icon);
EXPECT_EQ(model.header_icon(), &header_icon);
model.set_title(title); model.set_title(title);
EXPECT_EQ(title, model.title()); EXPECT_EQ(title, model.title());
......
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