Commit 59b051e4 authored by siyua's avatar siyua Committed by Commit Bot

[Upstream Feedback] Add loading indicator to local card migration icon

Add existing functionality to local card migration icon. Previously it
has a label fade-in/-out animation. Disable that and replace with the
new animation when experiment is enabled.

Also move loading indicator to PageActionIconView so that child view does
not need to know.

Bug: 964127
Change-Id: I2024c6d9ed23eea261b733dece833a9072faeced
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1828345
Commit-Queue: Siyu An <siyua@chromium.org>
Reviewed-by: default avatarPeter Boström <pbos@chromium.org>
Reviewed-by: default avatarJared Saul <jsaul@google.com>
Cr-Commit-Position: refs/heads/master@{#701691}
parent 016a5bf9
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/location_bar/location_bar_view.h" #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
#include "chrome/browser/ui/views/page_action/page_action_icon_container_view.h" #include "chrome/browser/ui/views/page_action/page_action_icon_container_view.h"
#include "chrome/browser/ui/views/page_action/page_action_icon_loading_indicator_view.h"
#include "chrome/browser/ui/views/page_action/page_action_icon_view.h" #include "chrome/browser/ui/views/page_action/page_action_icon_view.h"
#include "chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.h" #include "chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.h"
#include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
...@@ -535,8 +536,11 @@ class LocalCardMigrationBrowserTestForStatusChip ...@@ -535,8 +536,11 @@ class LocalCardMigrationBrowserTestForStatusChip
void SetUp() override { void SetUp() override {
base::test::ScopedFeatureList scoped_feature_list; base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature( scoped_feature_list.InitWithFeatures(
features::kAutofillEnableToolbarStatusChip); /*enabled_features=*/{features::kAutofillCreditCardUploadFeedback,
features::kAutofillEnableToolbarStatusChip,
features::kAutofillUpstream},
/*disabled_features=*/{});
LocalCardMigrationBrowserTest::SetUp(); LocalCardMigrationBrowserTest::SetUp();
} }
...@@ -1075,6 +1079,44 @@ IN_PROC_BROWSER_TEST_F(LocalCardMigrationBrowserTestForStatusChip, ...@@ -1075,6 +1079,44 @@ IN_PROC_BROWSER_TEST_F(LocalCardMigrationBrowserTestForStatusChip,
EXPECT_TRUE(GetLocalCardMigrationIconView()->GetVisible()); EXPECT_TRUE(GetLocalCardMigrationIconView()->GetVisible());
EXPECT_FALSE(GetLocalCardMigrationOfferBubbleViews()); EXPECT_FALSE(GetLocalCardMigrationOfferBubbleViews());
} }
IN_PROC_BROWSER_TEST_F(LocalCardMigrationBrowserTestForStatusChip,
Feedback_CardSavingAnimation) {
SaveLocalCard(kFirstCardNumber);
SaveLocalCard(kSecondCardNumber);
UseCardAndWaitForMigrationOffer(kFirstCardNumber);
// Click the [Continue] button in the bubble.
ClickOnOkButton(GetLocalCardMigrationOfferBubbleViews());
test_url_loader_factory()->ClearResponses();
EXPECT_TRUE(GetLocalCardMigrationIconView()->GetVisible());
EXPECT_FALSE(GetLocalCardMigrationIconView()
->loading_indicator_for_testing()
->IsAnimating());
// Click the [Save] button in the dialog.
ResetEventWaiterForSequence({DialogEvent::SENT_MIGRATE_CARDS_REQUEST});
ClickOnOkButton(GetLocalCardMigrationMainDialogView());
WaitForObservedEvent();
// No dialog should be showing, but icon should display throbber animation.
EXPECT_EQ(nullptr, GetLocalCardMigrationMainDialogView());
EXPECT_TRUE(GetLocalCardMigrationIconView()->GetVisible());
EXPECT_TRUE(GetLocalCardMigrationIconView()
->loading_indicator_for_testing()
->IsAnimating());
SetUpMigrateCardsRpcPaymentsAccepts();
ResetEventWaiterForSequence({DialogEvent::RECEIVED_MIGRATE_CARDS_RESPONSE});
WaitForObservedEvent();
// Icon animation should stop. Dialog stays hidden.
EXPECT_TRUE(GetLocalCardMigrationIconView()->GetVisible());
EXPECT_FALSE(GetLocalCardMigrationIconView()
->loading_indicator_for_testing()
->IsAnimating());
}
#endif // !defined(OS_CHROMEOS) #endif // !defined(OS_CHROMEOS)
// TODO(crbug.com/897998): // TODO(crbug.com/897998):
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "chrome/browser/ui/views/autofill/payments/local_card_migration_bubble_views.h" #include "chrome/browser/ui/views/autofill/payments/local_card_migration_bubble_views.h"
#include "chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.h" #include "chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.h"
#include "chrome/grit/generated_resources.h" #include "chrome/grit/generated_resources.h"
#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/strings/grit/components_strings.h" #include "components/strings/grit/components_strings.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/paint_vector_icon.h" #include "ui/gfx/paint_vector_icon.h"
...@@ -27,7 +28,12 @@ LocalCardMigrationIconView::LocalCardMigrationIconView( ...@@ -27,7 +28,12 @@ LocalCardMigrationIconView::LocalCardMigrationIconView(
delegate) { delegate) {
DCHECK(delegate); DCHECK(delegate);
SetID(VIEW_ID_MIGRATE_LOCAL_CREDIT_CARD_BUTTON); SetID(VIEW_ID_MIGRATE_LOCAL_CREDIT_CARD_BUTTON);
SetUpForInOutAnimation(); if (base::FeatureList::IsEnabled(
features::kAutofillCreditCardUploadFeedback)) {
InstallLoadingIndicator();
} else {
SetUpForInOutAnimation();
}
} }
LocalCardMigrationIconView::~LocalCardMigrationIconView() {} LocalCardMigrationIconView::~LocalCardMigrationIconView() {}
...@@ -78,16 +84,32 @@ bool LocalCardMigrationIconView::Update() { ...@@ -78,16 +84,32 @@ bool LocalCardMigrationIconView::Update() {
// Disable the credit card icon so it does not update if user clicks // Disable the credit card icon so it does not update if user clicks
// on it. // on it.
SetEnabled(false); SetEnabled(false);
AnimateIn(IDS_AUTOFILL_LOCAL_CARD_MIGRATION_ANIMATION_LABEL); if (base::FeatureList::IsEnabled(
features::kAutofillCreditCardUploadFeedback)) {
SetIsLoading(/*is_loading=*/true);
} else {
AnimateIn(IDS_AUTOFILL_LOCAL_CARD_MIGRATION_ANIMATION_LABEL);
}
break; break;
} }
case LocalCardMigrationFlowStep::MIGRATION_FINISHED: { case LocalCardMigrationFlowStep::MIGRATION_FINISHED: {
UnpauseAnimation(); if (base::FeatureList::IsEnabled(
features::kAutofillCreditCardUploadFeedback)) {
SetIsLoading(/*is_loading=*/false);
} else {
UnpauseAnimation();
}
SetEnabled(true); SetEnabled(true);
break; break;
} }
case LocalCardMigrationFlowStep::MIGRATION_FAILED: { case LocalCardMigrationFlowStep::MIGRATION_FAILED: {
UnpauseAnimation(); if (base::FeatureList::IsEnabled(
features::kAutofillCreditCardUploadFeedback)) {
UpdateIconImage();
SetIsLoading(/*is_loading=*/false);
} else {
UnpauseAnimation();
}
SetEnabled(true); SetEnabled(true);
break; break;
} }
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/location_bar/location_bar_view.h" #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
#include "chrome/browser/ui/views/page_action/page_action_icon_container_view.h" #include "chrome/browser/ui/views/page_action/page_action_icon_container_view.h"
#include "chrome/browser/ui/views/page_action/page_action_icon_loading_indicator_view.h"
#include "chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.h" #include "chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.h"
#include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
#include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/in_process_browser_test.h"
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/view_ids.h"
#include "chrome/browser/ui/views/autofill/payments/save_card_bubble_views.h" #include "chrome/browser/ui/views/autofill/payments/save_card_bubble_views.h"
#include "chrome/grit/generated_resources.h" #include "chrome/grit/generated_resources.h"
#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/strings/grit/components_strings.h" #include "components/strings/grit/components_strings.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/paint_vector_icon.h" #include "ui/gfx/paint_vector_icon.h"
...@@ -26,17 +27,14 @@ SaveCardIconView::SaveCardIconView(CommandUpdater* command_updater, ...@@ -26,17 +27,14 @@ SaveCardIconView::SaveCardIconView(CommandUpdater* command_updater,
DCHECK(delegate); DCHECK(delegate);
SetID(VIEW_ID_SAVE_CREDIT_CARD_BUTTON); SetID(VIEW_ID_SAVE_CREDIT_CARD_BUTTON);
if (base::FeatureList::IsEnabled(
features::kAutofillCreditCardUploadFeedback)) {
InstallLoadingIndicator();
}
SetUpForInOutAnimation(); SetUpForInOutAnimation();
loading_indicator_ =
AddChildView(std::make_unique<PageActionIconLoadingIndicatorView>());
loading_indicator_->SetVisible(false);
AddObserver(loading_indicator_);
} }
SaveCardIconView::~SaveCardIconView() { SaveCardIconView::~SaveCardIconView() = default;
RemoveObserver(loading_indicator_);
}
views::BubbleDialogDelegateView* SaveCardIconView::GetBubble() const { views::BubbleDialogDelegateView* SaveCardIconView::GetBubble() const {
SaveCardBubbleController* controller = GetController(); SaveCardBubbleController* controller = GetController();
...@@ -62,9 +60,9 @@ bool SaveCardIconView::Update() { ...@@ -62,9 +60,9 @@ bool SaveCardIconView::Update() {
if (command_enabled && controller->ShouldShowSavingCardAnimation()) { if (command_enabled && controller->ShouldShowSavingCardAnimation()) {
SetEnabled(false); SetEnabled(false);
loading_indicator_->ShowAnimation(); SetIsLoading(/*is_loading=*/true);
} else { } else {
loading_indicator_->StopAnimation(); SetIsLoading(/*is_loading=*/false);
UpdateIconImage(); UpdateIconImage();
SetEnabled(true); SetEnabled(true);
} }
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_SAVE_CARD_ICON_VIEW_H_ #define CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_SAVE_CARD_ICON_VIEW_H_
#include "base/macros.h" #include "base/macros.h"
#include "chrome/browser/ui/views/page_action/page_action_icon_loading_indicator_view.h"
#include "chrome/browser/ui/views/page_action/page_action_icon_view.h" #include "chrome/browser/ui/views/page_action/page_action_icon_view.h"
class CommandUpdater; class CommandUpdater;
...@@ -29,10 +28,6 @@ class SaveCardIconView : public PageActionIconView { ...@@ -29,10 +28,6 @@ class SaveCardIconView : public PageActionIconView {
bool Update() override; bool Update() override;
base::string16 GetTextForTooltipAndAccessibleName() const override; base::string16 GetTextForTooltipAndAccessibleName() const override;
PageActionIconLoadingIndicatorView* loading_indicator_for_testing() {
return loading_indicator_;
}
protected: protected:
// PageActionIconView: // PageActionIconView:
void OnExecuting(PageActionIconView::ExecuteSource execute_source) override; void OnExecuting(PageActionIconView::ExecuteSource execute_source) override;
...@@ -45,10 +40,6 @@ class SaveCardIconView : public PageActionIconView { ...@@ -45,10 +40,6 @@ class SaveCardIconView : public PageActionIconView {
// gfx::AnimationDelegate: // gfx::AnimationDelegate:
void AnimationEnded(const gfx::Animation* animation) override; void AnimationEnded(const gfx::Animation* animation) override;
// The loading indicator. Its animation will be triggered when upload save is
// in progress.
PageActionIconLoadingIndicatorView* loading_indicator_;
DISALLOW_COPY_AND_ASSIGN(SaveCardIconView); DISALLOW_COPY_AND_ASSIGN(SaveCardIconView);
}; };
......
...@@ -7,19 +7,24 @@ ...@@ -7,19 +7,24 @@
#include "base/location.h" #include "base/location.h"
#include "base/time/default_tick_clock.h" #include "base/time/default_tick_clock.h"
#include "chrome/browser/themes/theme_properties.h" #include "chrome/browser/themes/theme_properties.h"
#include "chrome/browser/ui/views/page_action/page_action_icon_view.h"
#include "ui/base/theme_provider.h" #include "ui/base/theme_provider.h"
#include "ui/gfx/canvas.h" #include "ui/gfx/canvas.h"
#include "ui/gfx/color_palette.h" #include "ui/gfx/color_palette.h"
#include "ui/gfx/paint_throbber.h" #include "ui/gfx/paint_throbber.h"
PageActionIconLoadingIndicatorView::PageActionIconLoadingIndicatorView() = PageActionIconLoadingIndicatorView::PageActionIconLoadingIndicatorView(
default; PageActionIconView* parent)
: parent_(parent) {
parent_->AddObserver(this);
}
PageActionIconLoadingIndicatorView::~PageActionIconLoadingIndicatorView() = PageActionIconLoadingIndicatorView::~PageActionIconLoadingIndicatorView() {
default; parent_->RemoveObserver(this);
}
void PageActionIconLoadingIndicatorView::ShowAnimation() { void PageActionIconLoadingIndicatorView::ShowAnimation() {
if (!throbber_start_time_.has_value()) if (!throbber_start_time_)
throbber_start_time_ = base::TimeTicks::Now(); throbber_start_time_ = base::TimeTicks::Now();
SetVisible(true); SetVisible(true);
...@@ -37,13 +42,15 @@ bool PageActionIconLoadingIndicatorView::IsAnimating() { ...@@ -37,13 +42,15 @@ bool PageActionIconLoadingIndicatorView::IsAnimating() {
} }
void PageActionIconLoadingIndicatorView::OnPaint(gfx::Canvas* canvas) { void PageActionIconLoadingIndicatorView::OnPaint(gfx::Canvas* canvas) {
if (!throbber_start_time_)
return;
const SkColor color = GetThemeProvider()->GetColor( const SkColor color = GetThemeProvider()->GetColor(
ThemeProperties::COLOR_TAB_THROBBER_SPINNING); ThemeProperties::COLOR_TAB_THROBBER_SPINNING);
constexpr int kThrobberStrokeWidth = 2; constexpr int kThrobberStrokeWidth = 2;
gfx::PaintThrobberSpinning( gfx::PaintThrobberSpinning(canvas, GetLocalBounds(), color,
canvas, GetLocalBounds(), color, base::TimeTicks::Now() - *throbber_start_time_,
base::TimeTicks::Now() - throbber_start_time_.value_or(base::TimeTicks()), kThrobberStrokeWidth);
kThrobberStrokeWidth);
} }
void PageActionIconLoadingIndicatorView::OnViewBoundsChanged( void PageActionIconLoadingIndicatorView::OnViewBoundsChanged(
......
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
#include "ui/views/view.h" #include "ui/views/view.h"
#include "ui/views/view_observer.h" #include "ui/views/view_observer.h"
class PageActionIconView;
// The view that contains a throbber animation. It is shown when the action // The view that contains a throbber animation. It is shown when the action
// related to the page action icon is in progress. // related to the page action icon is in progress.
// TODO(crbug.com/932818): Investigate the possibility of making this a layer // TODO(crbug.com/932818): Investigate the possibility of making this a layer
...@@ -21,7 +23,7 @@ class PageActionIconLoadingIndicatorView : public views::View, ...@@ -21,7 +23,7 @@ class PageActionIconLoadingIndicatorView : public views::View,
public views::ViewObserver, public views::ViewObserver,
public gfx::AnimationDelegate { public gfx::AnimationDelegate {
public: public:
PageActionIconLoadingIndicatorView(); explicit PageActionIconLoadingIndicatorView(PageActionIconView* parent);
~PageActionIconLoadingIndicatorView() override; ~PageActionIconLoadingIndicatorView() override;
void ShowAnimation(); void ShowAnimation();
...@@ -38,10 +40,12 @@ class PageActionIconLoadingIndicatorView : public views::View, ...@@ -38,10 +40,12 @@ class PageActionIconLoadingIndicatorView : public views::View,
void AnimationProgressed(const gfx::Animation* animation) override; void AnimationProgressed(const gfx::Animation* animation) override;
private: private:
base::Optional<base::TimeTicks> throbber_start_time_ = base::nullopt; base::Optional<base::TimeTicks> throbber_start_time_;
gfx::ThrobAnimation animation_{this}; gfx::ThrobAnimation animation_{this};
PageActionIconView* const parent_;
DISALLOW_COPY_AND_ASSIGN(PageActionIconLoadingIndicatorView); DISALLOW_COPY_AND_ASSIGN(PageActionIconLoadingIndicatorView);
}; };
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "chrome/browser/command_updater.h" #include "chrome/browser/command_updater.h"
#include "chrome/browser/ui/omnibox/omnibox_theme.h" #include "chrome/browser/ui/omnibox/omnibox_theme.h"
#include "chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h" #include "chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h"
#include "chrome/browser/ui/views/page_action/page_action_icon_loading_indicator_view.h"
#include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_node_data.h" #include "ui/accessibility/ax_node_data.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
...@@ -62,7 +63,7 @@ PageActionIconView::PageActionIconView(CommandUpdater* command_updater, ...@@ -62,7 +63,7 @@ PageActionIconView::PageActionIconView(CommandUpdater* command_updater,
UpdateBorder(); UpdateBorder();
} }
PageActionIconView::~PageActionIconView() {} PageActionIconView::~PageActionIconView() = default;
bool PageActionIconView::IsBubbleShowing() const { bool PageActionIconView::IsBubbleShowing() const {
// If the bubble is being destroyed, it's considered showing though it may be // If the bubble is being destroyed, it's considered showing though it may be
...@@ -211,6 +212,23 @@ void PageActionIconView::UpdateIconImage() { ...@@ -211,6 +212,23 @@ void PageActionIconView::UpdateIconImage() {
icon_color, GetVectorIconBadge())); icon_color, GetVectorIconBadge()));
} }
void PageActionIconView::InstallLoadingIndicator() {
if (loading_indicator_)
return;
loading_indicator_ =
AddChildView(std::make_unique<PageActionIconLoadingIndicatorView>(this));
loading_indicator_->SetVisible(false);
}
void PageActionIconView::SetIsLoading(bool is_loading) {
if (!loading_indicator_)
return;
is_loading ? loading_indicator_->ShowAnimation()
: loading_indicator_->StopAnimation();
}
content::WebContents* PageActionIconView::GetWebContents() const { content::WebContents* PageActionIconView::GetWebContents() const {
return delegate_->GetWebContentsForPageActionIconView(); return delegate_->GetWebContentsForPageActionIconView();
} }
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
class CommandUpdater; class CommandUpdater;
class OmniboxView; class OmniboxView;
class PageActionIconLoadingIndicatorView;
namespace content { namespace content {
class WebContents; class WebContents;
...@@ -80,6 +81,10 @@ class PageActionIconView : public IconLabelBubbleView { ...@@ -80,6 +81,10 @@ class PageActionIconView : public IconLabelBubbleView {
void ExecuteForTesting(); void ExecuteForTesting();
PageActionIconLoadingIndicatorView* loading_indicator_for_testing() {
return loading_indicator_;
}
protected: protected:
enum ExecuteSource { enum ExecuteSource {
EXECUTE_SOURCE_MOUSE, EXECUTE_SOURCE_MOUSE,
...@@ -138,6 +143,15 @@ class PageActionIconView : public IconLabelBubbleView { ...@@ -138,6 +143,15 @@ class PageActionIconView : public IconLabelBubbleView {
// Updates the icon image after some state has changed. // Updates the icon image after some state has changed.
virtual void UpdateIconImage(); virtual void UpdateIconImage();
// Creates and updates the loading indicator.
// TODO(crbug.com/964127): Ideally this should be lazily initialized in
// SetIsLoading(), but local card migration icon has a weird behavior that
// doing so will cause the indicator being invisible. Investigate and fix.
void InstallLoadingIndicator();
// Set if the page action icon is in the loading state.
void SetIsLoading(bool is_loading);
// Returns the associated web contents from the delegate. // Returns the associated web contents from the delegate.
content::WebContents* GetWebContents() const; content::WebContents* GetWebContents() const;
...@@ -169,6 +183,9 @@ class PageActionIconView : public IconLabelBubbleView { ...@@ -169,6 +183,9 @@ class PageActionIconView : public IconLabelBubbleView {
// the web page. // the web page.
bool active_ = false; bool active_ = false;
// The loading indicator, showing a throbber animation on top of the icon.
PageActionIconLoadingIndicatorView* loading_indicator_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(PageActionIconView); DISALLOW_COPY_AND_ASSIGN(PageActionIconView);
}; };
......
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