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 @@
#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 "components/constrained_window/constrained_window_views.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 {
// 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(
ObserverForTest* observer_for_test)
......@@ -24,14 +38,9 @@ void SecurePaymentConfirmationDialogView::ShowDialog(
DCHECK(model);
model_ = model;
OnModelUpdated();
InitChildViews();
// Set the dialog size. This is just for demonstration and will no longer be
// 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);
OnModelUpdated();
verify_callback_ = std::move(verify_callback);
cancel_callback_ = std::move(cancel_callback);
......@@ -79,6 +88,11 @@ void SecurePaymentConfirmationDialogView::OnDialogClosed() {
}
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());
SetButtonEnabled(ui::DIALOG_BUTTON_OK, model_->verify_button_enabled());
SetButtonLabel(ui::DIALOG_BUTTON_CANCEL, model_->cancel_button_label());
......@@ -86,7 +100,8 @@ void SecurePaymentConfirmationDialogView::OnModelUpdated() {
}
void SecurePaymentConfirmationDialogView::HideDialog() {
GetWidget()->Close();
if (GetWidget())
GetWidget()->Close();
}
ui::ModalType SecurePaymentConfirmationDialogView::GetModalType() const {
......@@ -102,4 +117,58 @@ SecurePaymentConfirmationDialogView::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
......@@ -7,8 +7,17 @@
#include "base/memory/weak_ptr.h"
#include "components/payments/content/secure_payment_confirmation_view.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/window/dialog_delegate.h"
namespace gfx {
struct VectorIcon;
}
namespace views {
class ProgressBar;
}
namespace payments {
// Draws the user interface in the secure payment confirmation flow. Owned by
......@@ -25,6 +34,10 @@ class SecurePaymentConfirmationDialogView
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(
ObserverForTest* observer_for_test);
~SecurePaymentConfirmationDialogView() override;
......@@ -50,12 +63,20 @@ class SecurePaymentConfirmationDialogView
void OnDialogCancelled();
void OnDialogClosed();
const gfx::VectorIcon& GetFingerprintIcon();
void InitChildViews();
std::unique_ptr<views::View> CreateHeaderView();
// May be null.
ObserverForTest* observer_for_test_;
ObserverForTest* observer_for_test_ = nullptr;
VerifyCallback verify_callback_;
CancelCallback cancel_callback_;
views::ProgressBar* progress_bar_ = nullptr;
base::WeakPtrFactory<SecurePaymentConfirmationDialogView> weak_ptr_factory_{
this};
};
......
......@@ -57,14 +57,23 @@ class SecurePaymentConfirmationDialogViewTest
void ExpectViewMatchesModel() {
ASSERT_NE(test_delegate_->dialog_view(), nullptr);
EXPECT_EQ(l10n_util::GetStringUTF16(
IDS_SECURE_PAYMENT_CONFIRMATION_VERIFY_BUTTON_LABEL),
EXPECT_EQ(model_.verify_button_label(),
test_delegate_->dialog_view()->GetDialogButtonLabel(
ui::DIALOG_BUTTON_OK));
EXPECT_EQ(l10n_util::GetStringUTF16(IDS_CANCEL),
EXPECT_EQ(model_.cancel_button_label(),
test_delegate_->dialog_view()->GetDialogButtonLabel(
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() {
......@@ -161,4 +170,34 @@ IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationDialogViewTest,
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
......@@ -32,6 +32,7 @@ void SecurePaymentConfirmationController::ShowDialog(
model_.set_verify_button_label(l10n_util::GetStringUTF16(
IDS_SECURE_PAYMENT_CONFIRMATION_VERIFY_BUTTON_LABEL));
model_.set_cancel_button_label(l10n_util::GetStringUTF16(IDS_CANCEL));
model_.set_progress_bar_visible(false);
view_->ShowDialog(
request->web_contents(), model_.GetWeakPtr(),
......@@ -42,10 +43,19 @@ void SecurePaymentConfirmationController::ShowDialog(
}
void SecurePaymentConfirmationController::CloseDialog() {
if (!view_)
return;
view_->HideDialog();
}
void SecurePaymentConfirmationController::ShowProcessingSpinner() {}
void SecurePaymentConfirmationController::ShowProcessingSpinner() {
if (!view_)
return;
model_.set_progress_bar_visible(true);
view_->OnModelUpdated();
}
void SecurePaymentConfirmationController::OnDismiss() {}
......
......@@ -9,10 +9,6 @@
#include "base/strings/string16.h"
#include "third_party/skia/include/core/SkBitmap.h"
namespace gfx {
struct VectorIcon;
}
namespace payments {
// The data model for the secure payment confirmation flow. Owned by the
......@@ -28,12 +24,6 @@ class SecurePaymentConfirmationModel {
SecurePaymentConfirmationModel& operator=(
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?"
const base::string16& title() const { return title_; }
void set_title(const base::string16& title) { title_ = title; }
......@@ -129,8 +119,6 @@ class SecurePaymentConfirmationModel {
base::WeakPtr<SecurePaymentConfirmationModel> GetWeakPtr();
private:
const gfx::VectorIcon* header_icon_ = nullptr;
base::string16 title_;
base::string16 merchant_label_;
......
......@@ -17,7 +17,6 @@ class SecurePaymentConfirmationModelTest : public testing::Test {};
TEST_F(SecurePaymentConfirmationModelTest, SmokeTest) {
SecurePaymentConfirmationModel model;
gfx::VectorIcon header_icon;
base::string16 title(
base::UTF8ToUTF16("Use Touch ID to verify and complete your purchase?"));
base::string16 merchant_label(base::UTF8ToUTF16("Store"));
......@@ -30,9 +29,6 @@ TEST_F(SecurePaymentConfirmationModelTest, SmokeTest) {
base::string16 verify_button_label(base::UTF8ToUTF16("Verify"));
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);
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