Commit ad392fff authored by Peter Kasting's avatar Peter Kasting Committed by Commit Bot

Use callbacks instead of ButtonPressed overrides: c/b/ui/views/infobars/

Bug: 772945
Change-Id: I81bdb9ed1de679f6b726c672bbd1519c0fcb2c7b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2436413
Commit-Queue: Peter Kasting <pkasting@chromium.org>
Reviewed-by: default avatarEvan Stade <estade@chromium.org>
Cr-Commit-Position: refs/heads/master@{#811514}
parent 897eea9d
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/views/chrome_test_views_delegate.h" #include "chrome/test/views/chrome_test_views_delegate.h"
#include "ui/events/event.h" #include "ui/events/event.h"
#include "ui/views/controls/button/md_text_button.h"
#include "ui/views/test/button_test_api.h"
class HungPluginInfoBarObserver : public infobars::InfoBarManager::Observer { class HungPluginInfoBarObserver : public infobars::InfoBarManager::Observer {
public: public:
...@@ -38,59 +40,15 @@ void HungPluginInfoBarObserver::OnInfoBarRemoved(infobars::InfoBar* infobar, ...@@ -38,59 +40,15 @@ void HungPluginInfoBarObserver::OnInfoBarRemoved(infobars::InfoBar* infobar,
seen_removal_ = true; seen_removal_ = true;
} }
class HungPluginMockInfoBar : public ConfirmInfoBar { void RemoveOnlyOnce(ConfirmInfoBar* infobar) {
public: DCHECK(infobar->owner());
explicit HungPluginMockInfoBar( HungPluginInfoBarObserver observer(infobar->owner());
std::unique_ptr<ConfirmInfoBarDelegate> delegate); if (infobar->GetDelegate()->Accept()) {
private:
// ConfirmInfoBar:
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
};
HungPluginMockInfoBar::HungPluginMockInfoBar(
std::unique_ptr<ConfirmInfoBarDelegate> delegate)
: ConfirmInfoBar(std::move(delegate)) {}
void HungPluginMockInfoBar::ButtonPressed(views::Button* sender,
const ui::Event& event) {
DCHECK(owner());
HungPluginInfoBarObserver observer(owner());
if (GetDelegate()->Accept()) {
ASSERT_FALSE(observer.seen_removal()); ASSERT_FALSE(observer.seen_removal());
RemoveSelf(); infobar->RemoveSelf();
} }
} }
class HungPluginMockInfoBarService : public InfoBarService {
public:
// Creates a HungPluginMockInfoBarService and attaches it as the
// InfoBarService for |web_contents|.
static void CreateForWebContents(content::WebContents* web_contents);
std::unique_ptr<infobars::InfoBar> CreateConfirmInfoBar(
std::unique_ptr<ConfirmInfoBarDelegate> delegate) override;
private:
using InfoBarService::InfoBarService;
};
void HungPluginMockInfoBarService::CreateForWebContents(
content::WebContents* web_contents) {
DCHECK(web_contents);
const void* user_data_key = UserDataKey();
DCHECK(!web_contents->GetUserData(user_data_key));
web_contents->SetUserData(
user_data_key,
base::WrapUnique(new HungPluginMockInfoBarService(web_contents)));
}
std::unique_ptr<infobars::InfoBar>
HungPluginMockInfoBarService::CreateConfirmInfoBar(
std::unique_ptr<ConfirmInfoBarDelegate> delegate) {
return std::make_unique<HungPluginMockInfoBar>(std::move(delegate));
}
class HungPluginTabHelperTest : public ChromeRenderViewHostTestHarness { class HungPluginTabHelperTest : public ChromeRenderViewHostTestHarness {
public: public:
void SetUp() override; void SetUp() override;
...@@ -103,24 +61,26 @@ void HungPluginTabHelperTest::SetUp() { ...@@ -103,24 +61,26 @@ void HungPluginTabHelperTest::SetUp() {
ChromeRenderViewHostTestHarness::SetUp(); ChromeRenderViewHostTestHarness::SetUp();
HungPluginTabHelper::CreateForWebContents(web_contents()); HungPluginTabHelper::CreateForWebContents(web_contents());
HungPluginMockInfoBarService::CreateForWebContents(web_contents()); InfoBarService::CreateForWebContents(web_contents());
} }
class DummyEvent : public ui::Event { class DummyEvent : public ui::Event {
public: public:
DummyEvent(); DummyEvent() : Event(ui::ET_UNKNOWN, base::TimeTicks(), ui::EF_NONE) {}
}; };
DummyEvent::DummyEvent() : Event(ui::ET_UNKNOWN, base::TimeTicks(), 0) {}
// Regression test for https://crbug.com/969099 . // Regression test for https://crbug.com/969099 .
TEST_F(HungPluginTabHelperTest, DontRemoveTwice) { TEST_F(HungPluginTabHelperTest, DontRemoveTwice) {
HungPluginTabHelper::FromWebContents(web_contents()) HungPluginTabHelper::FromWebContents(web_contents())
->PluginHungStatusChanged(0, base::FilePath(), true); ->PluginHungStatusChanged(0, base::FilePath(), true);
InfoBarService* infobar_service = InfoBarService* infobar_service =
InfoBarService::FromWebContents(web_contents()); InfoBarService::FromWebContents(web_contents());
ASSERT_TRUE(infobar_service);
ASSERT_EQ(1u, infobar_service->infobar_count()); ASSERT_EQ(1u, infobar_service->infobar_count());
static_cast<InfoBarView*>(infobar_service->infobar_at(0)) auto* infobar = static_cast<ConfirmInfoBar*>(infobar_service->infobar_at(0));
->ButtonPressed(nullptr, DummyEvent()); views::MdTextButton* ok_button = infobar->ok_button_for_testing();
ok_button->set_callback(
base::BindRepeating(&RemoveOnlyOnce, base::Unretained(infobar)));
views::test::ButtonTestApi(ok_button).NotifyClick(DummyEvent());
EXPECT_EQ(0u, infobar_service->infobar_count()); EXPECT_EQ(0u, infobar_service->infobar_count());
} }
...@@ -36,9 +36,24 @@ ConfirmInfoBar::ConfirmInfoBar(std::unique_ptr<ConfirmInfoBarDelegate> delegate) ...@@ -36,9 +36,24 @@ ConfirmInfoBar::ConfirmInfoBar(std::unique_ptr<ConfirmInfoBarDelegate> delegate)
label_->SetElideBehavior(delegate_ptr->GetMessageElideBehavior()); label_->SetElideBehavior(delegate_ptr->GetMessageElideBehavior());
AddChildView(label_); AddChildView(label_);
const auto create_button = [this](ConfirmInfoBarDelegate::InfoBarButton type,
void (ConfirmInfoBar::*click_function)()) {
auto* button = AddChildView(std::make_unique<views::MdTextButton>(
base::BindRepeating(click_function, base::Unretained(this)),
GetDelegate()->GetButtonLabel(type)));
button->SetProperty(
views::kMarginsKey,
gfx::Insets(ChromeLayoutProvider::Get()->GetDistanceMetric(
DISTANCE_TOAST_CONTROL_VERTICAL),
0));
button->SizeToPreferredSize();
return button;
};
const auto buttons = delegate_ptr->GetButtons(); const auto buttons = delegate_ptr->GetButtons();
if (buttons & ConfirmInfoBarDelegate::BUTTON_OK) { if (buttons & ConfirmInfoBarDelegate::BUTTON_OK) {
ok_button_ = CreateButton(ConfirmInfoBarDelegate::BUTTON_OK); ok_button_ = create_button(ConfirmInfoBarDelegate::BUTTON_OK,
&ConfirmInfoBar::OkButtonPressed);
ok_button_->SetProminent(true); ok_button_->SetProminent(true);
if (delegate_ptr->OKButtonTriggersUACPrompt()) { if (delegate_ptr->OKButtonTriggersUACPrompt()) {
elevation_icon_setter_ = std::make_unique<ElevationIconSetter>( elevation_icon_setter_ = std::make_unique<ElevationIconSetter>(
...@@ -48,7 +63,8 @@ ConfirmInfoBar::ConfirmInfoBar(std::unique_ptr<ConfirmInfoBarDelegate> delegate) ...@@ -48,7 +63,8 @@ ConfirmInfoBar::ConfirmInfoBar(std::unique_ptr<ConfirmInfoBarDelegate> delegate)
} }
if (buttons & ConfirmInfoBarDelegate::BUTTON_CANCEL) { if (buttons & ConfirmInfoBarDelegate::BUTTON_CANCEL) {
cancel_button_ = CreateButton(ConfirmInfoBarDelegate::BUTTON_CANCEL); cancel_button_ = create_button(ConfirmInfoBarDelegate::BUTTON_CANCEL,
&ConfirmInfoBar::CancelButtonPressed);
if (buttons == ConfirmInfoBarDelegate::BUTTON_CANCEL) if (buttons == ConfirmInfoBarDelegate::BUTTON_CANCEL)
cancel_button_->SetProminent(true); cancel_button_->SetProminent(true);
} }
...@@ -92,43 +108,27 @@ void ConfirmInfoBar::Layout() { ...@@ -92,43 +108,27 @@ void ConfirmInfoBar::Layout() {
link_->SetPosition(gfx::Point(EndX() - link_->width(), OffsetY(link_))); link_->SetPosition(gfx::Point(EndX() - link_->width(), OffsetY(link_)));
} }
void ConfirmInfoBar::ButtonPressed(views::Button* sender, void ConfirmInfoBar::OkButtonPressed() {
const ui::Event& event) {
if (!owner()) if (!owner())
return; // We're closing; don't call anything, it might access the owner. return; // We're closing; don't call anything, it might access the owner.
ConfirmInfoBarDelegate* delegate = GetDelegate(); if (GetDelegate()->Accept())
if (sender == ok_button_) { RemoveSelf();
if (delegate->Accept())
RemoveSelf();
} else if (sender == cancel_button_) {
if (delegate->Cancel())
RemoveSelf();
} else {
InfoBarView::ButtonPressed(sender, event);
}
} }
int ConfirmInfoBar::ContentMinimumWidth() const { void ConfirmInfoBar::CancelButtonPressed() {
return label_->GetMinimumSize().width() + link_->GetMinimumSize().width() + if (!owner())
NonLabelWidth(); return; // We're closing; don't call anything, it might access the owner.
if (GetDelegate()->Cancel())
RemoveSelf();
} }
ConfirmInfoBarDelegate* ConfirmInfoBar::GetDelegate() { ConfirmInfoBarDelegate* ConfirmInfoBar::GetDelegate() {
return delegate()->AsConfirmInfoBarDelegate(); return delegate()->AsConfirmInfoBarDelegate();
} }
views::MdTextButton* ConfirmInfoBar::CreateButton( int ConfirmInfoBar::ContentMinimumWidth() const {
ConfirmInfoBarDelegate::InfoBarButton type) { return label_->GetMinimumSize().width() + link_->GetMinimumSize().width() +
auto button = std::make_unique<views::MdTextButton>( NonLabelWidth();
this, GetDelegate()->GetButtonLabel(type));
button->SetProperty(
views::kMarginsKey,
gfx::Insets(ChromeLayoutProvider::Get()->GetDistanceMetric(
DISTANCE_TOAST_CONTROL_VERTICAL),
0));
auto* button_ptr = AddChildView(std::move(button));
button_ptr->SizeToPreferredSize();
return button_ptr;
} }
int ConfirmInfoBar::NonLabelWidth() const { int ConfirmInfoBar::NonLabelWidth() const {
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
class ElevationIconSetter; class ElevationIconSetter;
namespace views { namespace views {
class Button;
class Label; class Label;
class MdTextButton; class MdTextButton;
} }
...@@ -28,17 +27,18 @@ class ConfirmInfoBar : public InfoBarView { ...@@ -28,17 +27,18 @@ class ConfirmInfoBar : public InfoBarView {
// InfoBarView: // InfoBarView:
void Layout() override; void Layout() override;
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
ConfirmInfoBarDelegate* GetDelegate();
views::MdTextButton* ok_button_for_testing() { return ok_button_; }
protected: protected:
// InfoBarView: // InfoBarView:
int ContentMinimumWidth() const override; int ContentMinimumWidth() const override;
ConfirmInfoBarDelegate* GetDelegate();
private: private:
// Creates a button suitable for use as either OK or Cancel. void OkButtonPressed();
views::MdTextButton* CreateButton(ConfirmInfoBarDelegate::InfoBarButton type); void CancelButtonPressed();
// Returns the width of all content other than the label and link. Layout() // Returns the width of all content other than the label and link. Layout()
// uses this to determine how much space the label and link can take. // uses this to determine how much space the label and link can take.
......
...@@ -116,7 +116,8 @@ InfoBarView::InfoBarView(std::unique_ptr<infobars::InfoBarDelegate> delegate) ...@@ -116,7 +116,8 @@ InfoBarView::InfoBarView(std::unique_ptr<infobars::InfoBarDelegate> delegate)
} }
if (this->delegate()->IsCloseable()) { if (this->delegate()->IsCloseable()) {
auto close_button = views::CreateVectorImageButton(this); auto close_button = views::CreateVectorImageButton(base::BindRepeating(
&InfoBarView::CloseButtonPressed, base::Unretained(this)));
// This is the wrong color, but allows the button's size to be computed // This is the wrong color, but allows the button's size to be computed
// correctly. We'll reset this with the correct color in OnThemeChanged(). // correctly. We'll reset this with the correct color in OnThemeChanged().
views::SetImageFromVectorIcon(close_button.get(), views::SetImageFromVectorIcon(close_button.get(),
...@@ -250,16 +251,6 @@ void InfoBarView::OnThemeChanged() { ...@@ -250,16 +251,6 @@ void InfoBarView::OnThemeChanged() {
RecalculateHeight(); RecalculateHeight();
} }
void InfoBarView::ButtonPressed(views::Button* sender,
const ui::Event& event) {
if (!owner())
return; // We're closing; don't call anything, it might access the owner.
if (sender == close_button_) {
delegate()->InfoBarDismissed();
RemoveSelf();
}
}
void InfoBarView::OnWillChangeFocus(View* focused_before, View* focused_now) { void InfoBarView::OnWillChangeFocus(View* focused_before, View* focused_now) {
views::ExternalFocusTracker::OnWillChangeFocus(focused_before, focused_now); views::ExternalFocusTracker::OnWillChangeFocus(focused_before, focused_now);
...@@ -408,3 +399,10 @@ void InfoBarView::LinkClicked(const ui::Event& event) { ...@@ -408,3 +399,10 @@ void InfoBarView::LinkClicked(const ui::Event& event) {
if (delegate()->LinkClicked(ui::DispositionFromEventFlags(event.flags()))) if (delegate()->LinkClicked(ui::DispositionFromEventFlags(event.flags())))
RemoveSelf(); RemoveSelf();
} }
void InfoBarView::CloseButtonPressed() {
if (!owner())
return; // We're closing; don't call anything, it might access the owner.
delegate()->InfoBarDismissed();
RemoveSelf();
}
...@@ -10,9 +10,9 @@ ...@@ -10,9 +10,9 @@
#include "components/infobars/core/infobar.h" #include "components/infobars/core/infobar.h"
#include "components/infobars/core/infobar_container.h" #include "components/infobars/core/infobar_container.h"
#include "third_party/skia/include/core/SkPath.h" #include "third_party/skia/include/core/SkPath.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/menu/menu_types.h" #include "ui/views/controls/menu/menu_types.h"
#include "ui/views/focus/external_focus_tracker.h" #include "ui/views/focus/external_focus_tracker.h"
#include "ui/views/view.h"
namespace views { namespace views {
class ImageButton; class ImageButton;
...@@ -24,7 +24,6 @@ class MenuRunner; ...@@ -24,7 +24,6 @@ class MenuRunner;
class InfoBarView : public infobars::InfoBar, class InfoBarView : public infobars::InfoBar,
public views::View, public views::View,
public views::ButtonListener,
public views::ExternalFocusTracker { public views::ExternalFocusTracker {
public: public:
explicit InfoBarView(std::unique_ptr<infobars::InfoBarDelegate> delegate); explicit InfoBarView(std::unique_ptr<infobars::InfoBarDelegate> delegate);
...@@ -42,11 +41,6 @@ class InfoBarView : public infobars::InfoBar, ...@@ -42,11 +41,6 @@ class InfoBarView : public infobars::InfoBar,
void OnPaint(gfx::Canvas* canvas) override; void OnPaint(gfx::Canvas* canvas) override;
void OnThemeChanged() override; void OnThemeChanged() override;
// views::ButtonListener:
// NOTE: This must not be called if we're unowned. (Subclasses should ignore
// calls to ButtonPressed() in this case.)
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
// views::ExternalFocusTracker: // views::ExternalFocusTracker:
void OnWillChangeFocus(View* focused_before, View* focused_now) override; void OnWillChangeFocus(View* focused_before, View* focused_now) override;
...@@ -111,6 +105,8 @@ class InfoBarView : public infobars::InfoBar, ...@@ -111,6 +105,8 @@ class InfoBarView : public infobars::InfoBar,
// Callback used by the link created by CreateLink(). // Callback used by the link created by CreateLink().
void LinkClicked(const ui::Event& event); void LinkClicked(const ui::Event& event);
void CloseButtonPressed();
// The optional icon at the left edge of the InfoBar. // The optional icon at the left edge of the InfoBar.
views::ImageView* icon_ = nullptr; views::ImageView* icon_ = nullptr;
......
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