Commit 88c6cae3 authored by Peter Kasting's avatar Peter Kasting Committed by Commit Bot

Change ButtonPressed overrides to callbacks: ui/views/controls/button/

Bug: 772945
Change-Id: I5b0720ca91cee30529e893ffa5924a9ada68f451
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2490324
Commit-Queue: Peter Kasting <pkasting@chromium.org>
Auto-Submit: Peter Kasting <pkasting@chromium.org>
Reviewed-by: default avatarPeter Boström <pbos@chromium.org>
Cr-Commit-Position: refs/heads/master@{#819666}
parent 95977058
...@@ -70,9 +70,11 @@ class TestContextMenuController : public ContextMenuController { ...@@ -70,9 +70,11 @@ class TestContextMenuController : public ContextMenuController {
DISALLOW_COPY_AND_ASSIGN(TestContextMenuController); DISALLOW_COPY_AND_ASSIGN(TestContextMenuController);
}; };
class TestButton : public Button, public ButtonListener { class TestButton : public Button {
public: public:
explicit TestButton(bool has_ink_drop_action_on_click) : Button(this) { explicit TestButton(bool has_ink_drop_action_on_click)
: Button(base::BindRepeating([](bool* pressed) { *pressed = true; },
&pressed_)) {
SetHasInkDropActionOnClick(has_ink_drop_action_on_click); SetHasInkDropActionOnClick(has_ink_drop_action_on_click);
} }
...@@ -84,13 +86,6 @@ class TestButton : public Button, public ButtonListener { ...@@ -84,13 +86,6 @@ class TestButton : public Button, public ButtonListener {
return custom_key_click_action_; return custom_key_click_action_;
} }
void ButtonPressed(Button* sender, const ui::Event& event) override {
pressed_ = true;
if (!on_button_pressed_handler_.is_null())
on_button_pressed_handler_.Run();
}
void OnClickCanceled(const ui::Event& event) override { canceled_ = true; } void OnClickCanceled(const ui::Event& event) override { canceled_ = true; }
// Button: // Button:
...@@ -103,19 +98,17 @@ class TestButton : public Button, public ButtonListener { ...@@ -103,19 +98,17 @@ class TestButton : public Button, public ButtonListener {
Button::RemoveInkDropLayer(ink_drop_layer); Button::RemoveInkDropLayer(ink_drop_layer);
} }
bool pressed() { return pressed_; } bool pressed() const { return pressed_; }
bool canceled() { return canceled_; } bool canceled() const { return canceled_; }
int ink_drop_layer_add_count() { return ink_drop_layer_add_count_; } int ink_drop_layer_add_count() const { return ink_drop_layer_add_count_; }
int ink_drop_layer_remove_count() { return ink_drop_layer_remove_count_; } int ink_drop_layer_remove_count() const {
return ink_drop_layer_remove_count_;
}
void set_custom_key_click_action(KeyClickAction custom_key_click_action) { void set_custom_key_click_action(KeyClickAction custom_key_click_action) {
custom_key_click_action_ = custom_key_click_action; custom_key_click_action_ = custom_key_click_action;
} }
void set_on_button_pressed_handler(const base::RepeatingClosure& callback) {
on_button_pressed_handler_ = callback;
}
void Reset() { void Reset() {
pressed_ = false; pressed_ = false;
canceled_ = false; canceled_ = false;
...@@ -133,9 +126,6 @@ class TestButton : public Button, public ButtonListener { ...@@ -133,9 +126,6 @@ class TestButton : public Button, public ButtonListener {
KeyClickAction custom_key_click_action_ = KeyClickAction::kNone; KeyClickAction custom_key_click_action_ = KeyClickAction::kNone;
// If available, will be triggered when the button is pressed.
base::RepeatingClosure on_button_pressed_handler_;
DISALLOW_COPY_AND_ASSIGN(TestButton); DISALLOW_COPY_AND_ASSIGN(TestButton);
}; };
...@@ -171,21 +161,6 @@ class TestButtonObserver { ...@@ -171,21 +161,6 @@ class TestButtonObserver {
DISALLOW_COPY_AND_ASSIGN(TestButtonObserver); DISALLOW_COPY_AND_ASSIGN(TestButtonObserver);
}; };
class TestButtonListener : public ButtonListener {
public:
void ButtonPressed(Button* sender, const ui::Event& event) override {
pressed_ = true;
sender_ = sender;
}
bool pressed() const { return pressed_; }
Button* sender() const { return sender_; }
private:
bool pressed_ = false;
Button* sender_ = nullptr;
};
TestInkDrop* AddTestInkDrop(TestButton* button) { TestInkDrop* AddTestInkDrop(TestButton* button) {
auto owned_ink_drop = std::make_unique<TestInkDrop>(); auto owned_ink_drop = std::make_unique<TestInkDrop>();
TestInkDrop* ink_drop = owned_ink_drop.get(); TestInkDrop* ink_drop = owned_ink_drop.get();
...@@ -446,7 +421,7 @@ TEST_F(ButtonTest, GestureEventsSetState) { ...@@ -446,7 +421,7 @@ TEST_F(ButtonTest, GestureEventsSetState) {
// events will not revert the disabled state back to normal. // events will not revert the disabled state back to normal.
// https://crbug.com/1084241. // https://crbug.com/1084241.
TEST_F(ButtonTest, GestureEventsRespectDisabledState) { TEST_F(ButtonTest, GestureEventsRespectDisabledState) {
button()->set_on_button_pressed_handler(base::BindRepeating( button()->SetCallback(base::BindRepeating(
[](TestButton* button) { button->SetEnabled(false); }, button())); [](TestButton* button) { button->SetEnabled(false); }, button()));
EXPECT_EQ(Button::STATE_NORMAL, button()->GetState()); EXPECT_EQ(Button::STATE_NORMAL, button()->GetState());
...@@ -754,8 +729,9 @@ TEST_F(ButtonTest, InkDropStaysHiddenWhileDragging) { ...@@ -754,8 +729,9 @@ TEST_F(ButtonTest, InkDropStaysHiddenWhileDragging) {
// Ensure PressedCallback is dynamically settable. // Ensure PressedCallback is dynamically settable.
TEST_F(ButtonTest, SetCallback) { TEST_F(ButtonTest, SetCallback) {
TestButtonListener listener; bool pressed = false;
button()->SetCallback(Button::PressedCallback(&listener, button())); button()->SetCallback(
base::BindRepeating([](bool* pressed) { *pressed = true; }, &pressed));
const gfx::Point center(10, 10); const gfx::Point center(10, 10);
button()->OnMousePressed(ui::MouseEvent( button()->OnMousePressed(ui::MouseEvent(
...@@ -765,8 +741,7 @@ TEST_F(ButtonTest, SetCallback) { ...@@ -765,8 +741,7 @@ TEST_F(ButtonTest, SetCallback) {
button()->OnMouseReleased(ui::MouseEvent( button()->OnMouseReleased(ui::MouseEvent(
ui::ET_MOUSE_RELEASED, center, center, ui::EventTimeForNow(), ui::ET_MOUSE_RELEASED, center, center, ui::EventTimeForNow(),
ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON));
EXPECT_TRUE(listener.pressed()); EXPECT_TRUE(pressed);
EXPECT_EQ(button(), listener.sender());
} }
// VisibilityTestButton tests to see if an ink drop or a layer has been added to // VisibilityTestButton tests to see if an ink drop or a layer has been added to
......
...@@ -90,14 +90,6 @@ MenuButtonController::MenuButtonController( ...@@ -90,14 +90,6 @@ MenuButtonController::MenuButtonController(
set_notify_action(ButtonController::NotifyAction::kOnPress); set_notify_action(ButtonController::NotifyAction::kOnPress);
} }
MenuButtonController::MenuButtonController(
Button* button,
ButtonListener* listener,
std::unique_ptr<ButtonControllerDelegate> delegate)
: MenuButtonController(button,
Button::PressedCallback(listener, button),
std::move(delegate)) {}
MenuButtonController::~MenuButtonController() = default; MenuButtonController::~MenuButtonController() = default;
bool MenuButtonController::OnMousePressed(const ui::MouseEvent& event) { bool MenuButtonController::OnMousePressed(const ui::MouseEvent& event) {
...@@ -239,7 +231,7 @@ bool MenuButtonController::Activate(const ui::Event* event) { ...@@ -239,7 +231,7 @@ bool MenuButtonController::Activate(const ui::Event* event) {
bool increment_pressed_lock_called = false; bool increment_pressed_lock_called = false;
increment_pressed_lock_called_ = &increment_pressed_lock_called; increment_pressed_lock_called_ = &increment_pressed_lock_called;
// Allow for ButtonPressed() to delete this. // Allow for the button callback to delete this.
auto ref = weak_factory_.GetWeakPtr(); auto ref = weak_factory_.GetWeakPtr();
// TODO(pbos): Make sure we always propagate an event. This requires changes // TODO(pbos): Make sure we always propagate an event. This requires changes
......
...@@ -42,9 +42,6 @@ class VIEWS_EXPORT MenuButtonController : public ButtonController { ...@@ -42,9 +42,6 @@ class VIEWS_EXPORT MenuButtonController : public ButtonController {
MenuButtonController(Button* button, MenuButtonController(Button* button,
Button::PressedCallback callback, Button::PressedCallback callback,
std::unique_ptr<ButtonControllerDelegate> delegate); std::unique_ptr<ButtonControllerDelegate> delegate);
MenuButtonController(Button* button,
ButtonListener* listener,
std::unique_ptr<ButtonControllerDelegate> delegate);
~MenuButtonController() override; ~MenuButtonController() override;
// view::ButtonController // view::ButtonController
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <memory> #include <memory>
#include <utility> #include <utility>
#include "base/macros.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "build/build_config.h" #include "build/build_config.h"
...@@ -35,28 +34,45 @@ using base::ASCIIToUTF16; ...@@ -35,28 +34,45 @@ using base::ASCIIToUTF16;
namespace views { namespace views {
using test::InkDropHostViewTestApi;
using test::TestInkDrop;
// A MenuButton subclass that provides access to some MenuButton internals.
class TestMenuButton : public MenuButton { class TestMenuButton : public MenuButton {
public: public:
explicit TestMenuButton(ButtonListener* button_listener) TestMenuButton()
: MenuButton(button_listener, base::string16(ASCIIToUTF16("button"))) {} : TestMenuButton(base::BindRepeating(&TestMenuButton::ButtonPressed,
base::Unretained(this))) {}
explicit TestMenuButton(PressedCallback callback)
: MenuButton(std::move(callback),
base::string16(ASCIIToUTF16("button"))) {}
TestMenuButton(const TestMenuButton&) = delete;
TestMenuButton& operator=(const TestMenuButton&) = delete;
~TestMenuButton() override = default; ~TestMenuButton() override = default;
void SetInkDrop(std::unique_ptr<InkDrop> ink_drop) { bool clicked() const { return clicked_; }
InkDropHostViewTestApi(this).SetInkDrop(std::move(ink_drop)); Button::ButtonState last_state() const { return last_state_; }
ui::EventType last_event_type() const { return last_event_type_; }
void Reset() {
clicked_ = false;
last_state_ = Button::STATE_NORMAL;
last_event_type_ = ui::ET_UNKNOWN;
} }
private: private:
DISALLOW_COPY_AND_ASSIGN(TestMenuButton); void ButtonPressed(const ui::Event& event) {
clicked_ = true;
last_state_ = GetState();
last_event_type_ = event.type();
}
bool clicked_ = false;
Button::ButtonState last_state_ = Button::STATE_NORMAL;
ui::EventType last_event_type_ = ui::ET_UNKNOWN;
}; };
class MenuButtonTest : public ViewsTestBase { class MenuButtonTest : public ViewsTestBase {
public: public:
MenuButtonTest() = default; MenuButtonTest() = default;
MenuButtonTest(const MenuButtonTest&) = delete;
MenuButtonTest& operator=(const MenuButtonTest&) = delete;
~MenuButtonTest() override = default; ~MenuButtonTest() override = default;
void TearDown() override { void TearDown() override {
...@@ -67,46 +83,16 @@ class MenuButtonTest : public ViewsTestBase { ...@@ -67,46 +83,16 @@ class MenuButtonTest : public ViewsTestBase {
ViewsTestBase::TearDown(); ViewsTestBase::TearDown();
} }
protected:
Widget* widget() { return widget_; } Widget* widget() { return widget_; }
TestMenuButton* button() { return button_; } TestMenuButton* button() { return button_; }
ui::test::EventGenerator* generator() { return generator_.get(); } ui::test::EventGenerator* generator() { return generator_.get(); }
test::TestInkDrop* ink_drop() { return ink_drop_; }
protected:
TestInkDrop* ink_drop() { return ink_drop_; }
// Creates a MenuButton with no button listener.
void CreateMenuButtonWithNoListener() { CreateMenuButton(nullptr); }
// Creates a MenuButton with a ButtonListener. In this case, when the
// MenuButton is pushed, it notifies the ButtonListener to open a
// drop-down menu.
void CreateMenuButtonWithButtonListener(ButtonListener* button_listener) {
CreateMenuButton(button_listener);
}
gfx::Point GetOutOfButtonLocation() const { gfx::Point GetOutOfButtonLocation() const {
return gfx::Point(button_->x() - 1, button_->y() - 1); return gfx::Point(button_->x() - 1, button_->y() - 1);
} }
void CreateMenuButton(ButtonListener* button_listener) {
CreateWidget();
generator_ =
std::make_unique<ui::test::EventGenerator>(GetRootWindow(widget_));
// Set initial mouse location in a consistent way so that the menu button we
// are about to create initializes its hover state in a consistent manner.
generator_->set_current_screen_location(gfx::Point(10, 10));
button_ = widget_->SetContentsView(
std::make_unique<TestMenuButton>(button_listener));
button_->SetBoundsRect(gfx::Rect(0, 0, 200, 20));
ink_drop_ = new test::TestInkDrop();
test::InkDropHostViewTestApi(button_).SetInkDrop(
base::WrapUnique(ink_drop_));
widget_->Show();
}
void CreateWidget() { void CreateWidget() {
DCHECK(!widget_); DCHECK(!widget_);
...@@ -117,75 +103,54 @@ class MenuButtonTest : public ViewsTestBase { ...@@ -117,75 +103,54 @@ class MenuButtonTest : public ViewsTestBase {
widget_->Init(std::move(params)); widget_->Init(std::move(params));
} }
Widget* widget_ = nullptr; void ConfigureMenuButton(std::unique_ptr<TestMenuButton> button) {
TestMenuButton* button_ = nullptr; CreateWidget();
std::unique_ptr<ui::test::EventGenerator> generator_; generator_ =
std::make_unique<ui::test::EventGenerator>(GetRootWindow(widget_));
// Weak ptr, |button_| owns the instance. // Set initial mouse location in a consistent way so that the menu button we
TestInkDrop* ink_drop_ = nullptr; // are about to create initializes its hover state in a consistent manner.
generator_->set_current_screen_location(gfx::Point(10, 10));
DISALLOW_COPY_AND_ASSIGN(MenuButtonTest); button_ = widget_->SetContentsView(std::move(button));
}; button_->SetBoundsRect(gfx::Rect(0, 0, 200, 20));
class TestButtonListener : public ButtonListener { auto ink_drop = std::make_unique<test::TestInkDrop>();
public: ink_drop_ = ink_drop.get();
TestButtonListener() = default; test::InkDropHostViewTestApi(button_).SetInkDrop(std::move(ink_drop));
~TestButtonListener() override = default;
void ButtonPressed(Button* sender, const ui::Event& event) override {
last_sender_ = sender;
Button* button = Button::AsButton(sender);
DCHECK(button);
last_sender_state_ = button->GetState();
last_event_type_ = event.type();
}
void Reset() { widget_->Show();
last_sender_ = nullptr;
last_sender_state_ = Button::STATE_NORMAL;
last_event_type_ = ui::ET_UNKNOWN;
} }
Button* last_sender() { return last_sender_; }
Button::ButtonState last_sender_GetState() { return last_sender_state_; }
ui::EventType last_event_type() { return last_event_type_; }
private: private:
Button* last_sender_ = nullptr; Widget* widget_ = nullptr; // Owned by self.
Button::ButtonState last_sender_state_ = Button::STATE_NORMAL; TestMenuButton* button_ = nullptr; // Owned by |widget_|.
ui::EventType last_event_type_ = ui::ET_UNKNOWN; std::unique_ptr<ui::test::EventGenerator> generator_;
test::TestInkDrop* ink_drop_ = nullptr; // Owned by |button_|.
DISALLOW_COPY_AND_ASSIGN(TestButtonListener);
}; };
// A ButtonListener that will acquire a PressedLock in the // A Button that will acquire a PressedLock in the pressed callback and
// ButtonPressed() method and optionally release it as well. // optionally release it as well.
class PressStateButtonListener : public ButtonListener { class PressStateButton : public TestMenuButton {
public: public:
explicit PressStateButtonListener(bool release_lock) explicit PressStateButton(bool release_lock)
: menu_button_(nullptr), release_lock_(release_lock) {} : TestMenuButton(base::BindRepeating(&PressStateButton::ButtonPressed,
base::Unretained(this))),
~PressStateButtonListener() override = default; release_lock_(release_lock) {}
PressStateButton(const PressStateButton&) = delete;
void set_menu_button(MenuButton* menu_button) { menu_button_ = menu_button; } PressStateButton& operator=(const PressStateButton&) = delete;
~PressStateButton() override = default;
void ButtonPressed(Button* source, const ui::Event& event) override {
pressed_lock_ = menu_button_->button_controller()->TakeLock();
if (release_lock_)
pressed_lock_.reset();
}
void ReleasePressedLock() { pressed_lock_.reset(); } void ReleasePressedLock() { pressed_lock_.reset(); }
private: private:
MenuButton* menu_button_; void ButtonPressed() {
pressed_lock_ = button_controller()->TakeLock();
std::unique_ptr<MenuButtonController::PressedLock> pressed_lock_; if (release_lock_)
ReleasePressedLock();
}
// The |pressed_lock_| will be released when true.
bool release_lock_; bool release_lock_;
std::unique_ptr<MenuButtonController::PressedLock> pressed_lock_;
DISALLOW_COPY_AND_ASSIGN(PressStateButtonListener);
}; };
// Basic implementation of a DragController, to test input behaviour for // Basic implementation of a DragController, to test input behaviour for
...@@ -193,6 +158,8 @@ class PressStateButtonListener : public ButtonListener { ...@@ -193,6 +158,8 @@ class PressStateButtonListener : public ButtonListener {
class TestDragController : public DragController { class TestDragController : public DragController {
public: public:
TestDragController() = default; TestDragController() = default;
TestDragController(const TestDragController&) = delete;
TestDragController& operator=(const TestDragController&) = delete;
~TestDragController() override = default; ~TestDragController() override = default;
void WriteDragDataForView(View* sender, void WriteDragDataForView(View* sender,
...@@ -208,9 +175,6 @@ class TestDragController : public DragController { ...@@ -208,9 +175,6 @@ class TestDragController : public DragController {
const gfx::Point& p) override { const gfx::Point& p) override {
return true; return true;
} }
private:
DISALLOW_COPY_AND_ASSIGN(TestDragController);
}; };
#if defined(USE_AURA) #if defined(USE_AURA)
...@@ -221,6 +185,8 @@ class TestDragDropClient : public aura::client::DragDropClient, ...@@ -221,6 +185,8 @@ class TestDragDropClient : public aura::client::DragDropClient,
public ui::EventHandler { public ui::EventHandler {
public: public:
TestDragDropClient(); TestDragDropClient();
TestDragDropClient(const TestDragDropClient&) = delete;
TestDragDropClient& operator=(const TestDragDropClient&) = delete;
~TestDragDropClient() override; ~TestDragDropClient() override;
// aura::client::DragDropClient: // aura::client::DragDropClient:
...@@ -245,8 +211,6 @@ class TestDragDropClient : public aura::client::DragDropClient, ...@@ -245,8 +211,6 @@ class TestDragDropClient : public aura::client::DragDropClient,
// Target window where drag operations are occurring. // Target window where drag operations are occurring.
aura::Window* target_ = nullptr; aura::Window* target_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(TestDragDropClient);
}; };
TestDragDropClient::TestDragDropClient() = default; TestDragDropClient::TestDragDropClient() = default;
...@@ -292,77 +256,50 @@ void TestDragDropClient::OnMouseEvent(ui::MouseEvent* event) { ...@@ -292,77 +256,50 @@ void TestDragDropClient::OnMouseEvent(ui::MouseEvent* event) {
} }
#endif // defined(USE_AURA) #endif // defined(USE_AURA)
class TestShowSiblingButtonListener : public ButtonListener { // Tests if the callback is called correctly when a mouse click happens on a
public: // MenuButton.
TestShowSiblingButtonListener() = default;
~TestShowSiblingButtonListener() override = default;
void ButtonPressed(Button* source, const ui::Event& event) override {
// The MenuButton itself doesn't set the PRESSED state during Activate() or
// ButtonPressed(). That should be handled by the MenuController or,
// if no menu is shown, the listener.
EXPECT_EQ(Button::STATE_HOVERED, source->GetState());
}
private:
DISALLOW_COPY_AND_ASSIGN(TestShowSiblingButtonListener);
};
// Tests if the listener is notified correctly when a mouse click happens on a
// MenuButton that has a ButtonListener.
TEST_F(MenuButtonTest, ActivateDropDownOnMouseClick) { TEST_F(MenuButtonTest, ActivateDropDownOnMouseClick) {
TestButtonListener button_listener; ConfigureMenuButton(std::make_unique<TestMenuButton>());
CreateMenuButtonWithButtonListener(&button_listener);
generator()->ClickLeftButton(); generator()->ClickLeftButton();
// Check that MenuButton has notified the listener, while it was in pressed EXPECT_TRUE(button()->clicked());
// state. EXPECT_EQ(Button::STATE_HOVERED, button()->last_state());
EXPECT_EQ(button(), button_listener.last_sender());
EXPECT_EQ(Button::STATE_HOVERED, button_listener.last_sender_GetState());
} }
TEST_F(MenuButtonTest, ActivateOnKeyPress) { TEST_F(MenuButtonTest, ActivateOnKeyPress) {
TestButtonListener button_listener; ConfigureMenuButton(std::make_unique<TestMenuButton>());
CreateMenuButtonWithButtonListener(&button_listener);
EXPECT_EQ(nullptr, button_listener.last_sender()); EXPECT_FALSE(button()->clicked());
button()->OnKeyPressed(ui::KeyEvent( button()->OnKeyPressed(ui::KeyEvent(
ui::ET_KEY_PRESSED, ui::KeyboardCode::VKEY_SPACE, ui::DomCode::SPACE, 0)); ui::ET_KEY_PRESSED, ui::KeyboardCode::VKEY_SPACE, ui::DomCode::SPACE, 0));
EXPECT_EQ(button(), button_listener.last_sender()); EXPECT_TRUE(button()->clicked());
button_listener.Reset(); button()->Reset();
EXPECT_EQ(nullptr, button_listener.last_sender()); EXPECT_FALSE(button()->clicked());
button()->OnKeyPressed(ui::KeyEvent(ui::ET_KEY_PRESSED, button()->OnKeyPressed(ui::KeyEvent(ui::ET_KEY_PRESSED,
ui::KeyboardCode::VKEY_RETURN, ui::KeyboardCode::VKEY_RETURN,
ui::DomCode::ENTER, 0)); ui::DomCode::ENTER, 0));
if (PlatformStyle::kReturnClicksFocusedControl) { EXPECT_EQ(PlatformStyle::kReturnClicksFocusedControl, button()->clicked());
EXPECT_EQ(button(), button_listener.last_sender());
} else {
EXPECT_EQ(nullptr, button_listener.last_sender());
}
} }
// Tests that the ink drop center point is set from the mouse click point. // Tests that the ink drop center point is set from the mouse click point.
TEST_F(MenuButtonTest, InkDropCenterSetFromClick) { TEST_F(MenuButtonTest, InkDropCenterSetFromClick) {
TestButtonListener button_listener; ConfigureMenuButton(std::make_unique<TestMenuButton>());
CreateMenuButtonWithButtonListener(&button_listener);
gfx::Point click_point(6, 8); gfx::Point click_point(6, 8);
generator()->MoveMouseTo(click_point); generator()->MoveMouseTo(click_point);
generator()->ClickLeftButton(); generator()->ClickLeftButton();
EXPECT_EQ(button(), button_listener.last_sender()); EXPECT_TRUE(button()->clicked());
EXPECT_EQ( EXPECT_EQ(click_point, test::InkDropHostViewTestApi(button())
click_point, .GetInkDropCenterBasedOnLastEvent());
InkDropHostViewTestApi(button()).GetInkDropCenterBasedOnLastEvent());
} }
// Tests that the ink drop center point is set from the PressedLock constructor. // Tests that the ink drop center point is set from the PressedLock constructor.
TEST_F(MenuButtonTest, InkDropCenterSetFromClickWithPressedLock) { TEST_F(MenuButtonTest, InkDropCenterSetFromClickWithPressedLock) {
TestButtonListener button_listener; ConfigureMenuButton(std::make_unique<TestMenuButton>());
CreateMenuButtonWithButtonListener(&button_listener);
gfx::Point click_point(11, 7); gfx::Point click_point(11, 7);
ui::MouseEvent click_event(ui::EventType::ET_MOUSE_PRESSED, click_point, ui::MouseEvent click_event(ui::EventType::ET_MOUSE_PRESSED, click_point,
...@@ -371,22 +308,21 @@ TEST_F(MenuButtonTest, InkDropCenterSetFromClickWithPressedLock) { ...@@ -371,22 +308,21 @@ TEST_F(MenuButtonTest, InkDropCenterSetFromClickWithPressedLock) {
false, &click_event); false, &click_event);
EXPECT_EQ(Button::STATE_PRESSED, button()->GetState()); EXPECT_EQ(Button::STATE_PRESSED, button()->GetState());
EXPECT_EQ( EXPECT_EQ(click_point, test::InkDropHostViewTestApi(button())
click_point, .GetInkDropCenterBasedOnLastEvent());
InkDropHostViewTestApi(button()).GetInkDropCenterBasedOnLastEvent());
} }
// Test that the MenuButton stays pressed while there are any PressedLocks. // Test that the MenuButton stays pressed while there are any PressedLocks.
TEST_F(MenuButtonTest, ButtonStateForMenuButtonsWithPressedLocks) { TEST_F(MenuButtonTest, ButtonStateForMenuButtonsWithPressedLocks) {
CreateMenuButtonWithNoListener(); ConfigureMenuButton(std::make_unique<TestMenuButton>());
// Move the mouse over the button; the button should be in a hovered state. // Move the mouse over the button; the button should be in a hovered state.
generator()->MoveMouseTo(gfx::Point(10, 10)); generator()->MoveMouseTo(gfx::Point(10, 10));
EXPECT_EQ(Button::STATE_HOVERED, button()->GetState()); EXPECT_EQ(Button::STATE_HOVERED, button()->GetState());
// Introduce a PressedLock, which should make the button pressed. // Introduce a PressedLock, which should make the button pressed.
std::unique_ptr<MenuButtonController::PressedLock> pressed_lock1( auto pressed_lock1 = std::make_unique<MenuButtonController::PressedLock>(
new MenuButtonController::PressedLock(button()->button_controller())); button()->button_controller());
EXPECT_EQ(Button::STATE_PRESSED, button()->GetState()); EXPECT_EQ(Button::STATE_PRESSED, button()->GetState());
// Even if we move the mouse outside of the button, it should remain pressed. // Even if we move the mouse outside of the button, it should remain pressed.
...@@ -394,8 +330,8 @@ TEST_F(MenuButtonTest, ButtonStateForMenuButtonsWithPressedLocks) { ...@@ -394,8 +330,8 @@ TEST_F(MenuButtonTest, ButtonStateForMenuButtonsWithPressedLocks) {
EXPECT_EQ(Button::STATE_PRESSED, button()->GetState()); EXPECT_EQ(Button::STATE_PRESSED, button()->GetState());
// Creating a new lock should obviously keep the button pressed. // Creating a new lock should obviously keep the button pressed.
std::unique_ptr<MenuButtonController::PressedLock> pressed_lock2( auto pressed_lock2 = std::make_unique<MenuButtonController::PressedLock>(
new MenuButtonController::PressedLock(button()->button_controller())); button()->button_controller());
EXPECT_EQ(Button::STATE_PRESSED, button()->GetState()); EXPECT_EQ(Button::STATE_PRESSED, button()->GetState());
// The button should remain pressed while any locks are active. // The button should remain pressed while any locks are active.
...@@ -436,37 +372,24 @@ TEST_F(MenuButtonTest, ButtonStateForMenuButtonsWithPressedLocks) { ...@@ -436,37 +372,24 @@ TEST_F(MenuButtonTest, ButtonStateForMenuButtonsWithPressedLocks) {
EXPECT_EQ(Button::STATE_NORMAL, button()->GetState()); EXPECT_EQ(Button::STATE_NORMAL, button()->GetState());
} }
// Test that if a sibling menu is shown, the original menu button releases its
// PressedLock.
TEST_F(MenuButtonTest, PressedStateWithSiblingMenu) {
TestShowSiblingButtonListener listener;
CreateMenuButtonWithButtonListener(&listener);
// Move the mouse over the button; the button should be in a hovered state.
generator()->MoveMouseTo(gfx::Point(10, 10));
EXPECT_EQ(Button::STATE_HOVERED, button()->GetState());
generator()->ClickLeftButton();
// Test is continued in TestShowSiblingButtonListener::ButtonPressed().
}
// Test that the MenuButton does not become pressed if it can be dragged, until // Test that the MenuButton does not become pressed if it can be dragged, until
// a release occurs. // a release occurs.
TEST_F(MenuButtonTest, DraggableMenuButtonActivatesOnRelease) { TEST_F(MenuButtonTest, DraggableMenuButtonActivatesOnRelease) {
TestButtonListener button_listener; ConfigureMenuButton(std::make_unique<TestMenuButton>());
CreateMenuButtonWithButtonListener(&button_listener);
TestDragController drag_controller; TestDragController drag_controller;
button()->set_drag_controller(&drag_controller); button()->set_drag_controller(&drag_controller);
generator()->PressLeftButton(); generator()->PressLeftButton();
EXPECT_EQ(nullptr, button_listener.last_sender()); EXPECT_FALSE(button()->clicked());
generator()->ReleaseLeftButton(); generator()->ReleaseLeftButton();
EXPECT_EQ(button(), button_listener.last_sender()); EXPECT_TRUE(button()->clicked());
EXPECT_EQ(Button::STATE_HOVERED, button_listener.last_sender_GetState()); EXPECT_EQ(Button::STATE_HOVERED, button()->last_state());
} }
TEST_F(MenuButtonTest, InkDropStateForMenuButtonActivationsWithoutListener) { TEST_F(MenuButtonTest, InkDropStateForMenuButtonActivationsWithoutCallback) {
CreateMenuButtonWithNoListener(); ConfigureMenuButton(
std::make_unique<TestMenuButton>(Button::PressedCallback()));
ink_drop()->AnimateToState(InkDropState::ACTION_PENDING); ink_drop()->AnimateToState(InkDropState::ACTION_PENDING);
button()->Activate(nullptr); button()->Activate(nullptr);
...@@ -474,9 +397,8 @@ TEST_F(MenuButtonTest, InkDropStateForMenuButtonActivationsWithoutListener) { ...@@ -474,9 +397,8 @@ TEST_F(MenuButtonTest, InkDropStateForMenuButtonActivationsWithoutListener) {
} }
TEST_F(MenuButtonTest, TEST_F(MenuButtonTest,
InkDropStateForMenuButtonActivationsWithListenerThatDoesntAcquireALock) { InkDropStateForMenuButtonActivationsWithCallbackThatDoesntAcquireALock) {
TestButtonListener button_listener; ConfigureMenuButton(std::make_unique<TestMenuButton>());
CreateMenuButtonWithButtonListener(&button_listener);
button()->Activate(nullptr); button()->Activate(nullptr);
EXPECT_EQ(InkDropState::ACTION_TRIGGERED, EXPECT_EQ(InkDropState::ACTION_TRIGGERED,
...@@ -485,35 +407,31 @@ TEST_F(MenuButtonTest, ...@@ -485,35 +407,31 @@ TEST_F(MenuButtonTest,
TEST_F( TEST_F(
MenuButtonTest, MenuButtonTest,
InkDropStateForMenuButtonActivationsWithListenerThatDontReleaseAllLocks) { InkDropStateForMenuButtonActivationsWithCallbackThatDoesntReleaseAllLocks) {
PressStateButtonListener button_listener(false); ConfigureMenuButton(std::make_unique<PressStateButton>(false));
CreateMenuButtonWithButtonListener(&button_listener);
button_listener.set_menu_button(button());
button()->Activate(nullptr); button()->Activate(nullptr);
EXPECT_EQ(InkDropState::ACTIVATED, ink_drop()->GetTargetInkDropState()); EXPECT_EQ(InkDropState::ACTIVATED, ink_drop()->GetTargetInkDropState());
} }
TEST_F(MenuButtonTest, TEST_F(MenuButtonTest,
InkDropStateForMenuButtonActivationsWithListenerThatReleaseAllLocks) { InkDropStateForMenuButtonActivationsWithCallbackThatReleasesAllLocks) {
PressStateButtonListener button_listener(true); ConfigureMenuButton(std::make_unique<PressStateButton>(true));
CreateMenuButtonWithButtonListener(&button_listener);
button_listener.set_menu_button(button());
button()->Activate(nullptr); button()->Activate(nullptr);
EXPECT_EQ(InkDropState::DEACTIVATED, ink_drop()->GetTargetInkDropState()); EXPECT_EQ(InkDropState::DEACTIVATED, ink_drop()->GetTargetInkDropState());
} }
TEST_F(MenuButtonTest, InkDropStateForMenuButtonsWithPressedLocks) { TEST_F(MenuButtonTest, InkDropStateForMenuButtonsWithPressedLocks) {
CreateMenuButtonWithNoListener(); ConfigureMenuButton(std::make_unique<TestMenuButton>());
std::unique_ptr<MenuButtonController::PressedLock> pressed_lock1( auto pressed_lock1 = std::make_unique<MenuButtonController::PressedLock>(
new MenuButtonController::PressedLock(button()->button_controller())); button()->button_controller());
EXPECT_EQ(InkDropState::ACTIVATED, ink_drop()->GetTargetInkDropState()); EXPECT_EQ(InkDropState::ACTIVATED, ink_drop()->GetTargetInkDropState());
std::unique_ptr<MenuButtonController::PressedLock> pressed_lock2( auto pressed_lock2 = std::make_unique<MenuButtonController::PressedLock>(
new MenuButtonController::PressedLock(button()->button_controller())); button()->button_controller());
EXPECT_EQ(InkDropState::ACTIVATED, ink_drop()->GetTargetInkDropState()); EXPECT_EQ(InkDropState::ACTIVATED, ink_drop()->GetTargetInkDropState());
...@@ -527,16 +445,16 @@ TEST_F(MenuButtonTest, InkDropStateForMenuButtonsWithPressedLocks) { ...@@ -527,16 +445,16 @@ TEST_F(MenuButtonTest, InkDropStateForMenuButtonsWithPressedLocks) {
// Verifies only one ink drop animation is triggered when multiple PressedLocks // Verifies only one ink drop animation is triggered when multiple PressedLocks
// are attached to a MenuButton. // are attached to a MenuButton.
TEST_F(MenuButtonTest, OneInkDropAnimationForReentrantPressedLocks) { TEST_F(MenuButtonTest, OneInkDropAnimationForReentrantPressedLocks) {
CreateMenuButtonWithNoListener(); ConfigureMenuButton(std::make_unique<TestMenuButton>());
std::unique_ptr<MenuButtonController::PressedLock> pressed_lock1( auto pressed_lock1 = std::make_unique<MenuButtonController::PressedLock>(
new MenuButtonController::PressedLock(button()->button_controller())); button()->button_controller());
EXPECT_EQ(InkDropState::ACTIVATED, ink_drop()->GetTargetInkDropState()); EXPECT_EQ(InkDropState::ACTIVATED, ink_drop()->GetTargetInkDropState());
ink_drop()->AnimateToState(InkDropState::ACTION_PENDING); ink_drop()->AnimateToState(InkDropState::ACTION_PENDING);
std::unique_ptr<MenuButtonController::PressedLock> pressed_lock2( auto pressed_lock2 = std::make_unique<MenuButtonController::PressedLock>(
new MenuButtonController::PressedLock(button()->button_controller())); button()->button_controller());
EXPECT_EQ(InkDropState::ACTION_PENDING, ink_drop()->GetTargetInkDropState()); EXPECT_EQ(InkDropState::ACTION_PENDING, ink_drop()->GetTargetInkDropState());
} }
...@@ -545,8 +463,7 @@ TEST_F(MenuButtonTest, OneInkDropAnimationForReentrantPressedLocks) { ...@@ -545,8 +463,7 @@ TEST_F(MenuButtonTest, OneInkDropAnimationForReentrantPressedLocks) {
// before another Activation occurs. // before another Activation occurs.
TEST_F(MenuButtonTest, TEST_F(MenuButtonTest,
InkDropStateForMenuButtonWithPressedLockBeforeActivation) { InkDropStateForMenuButtonWithPressedLockBeforeActivation) {
TestButtonListener button_listener; ConfigureMenuButton(std::make_unique<TestMenuButton>());
CreateMenuButtonWithButtonListener(&button_listener);
MenuButtonController::PressedLock lock(button()->button_controller()); MenuButtonController::PressedLock lock(button()->button_controller());
button()->Activate(nullptr); button()->Activate(nullptr);
...@@ -559,8 +476,7 @@ TEST_F(MenuButtonTest, ...@@ -559,8 +476,7 @@ TEST_F(MenuButtonTest,
// Tests that the MenuButton does not become pressed if it can be dragged, and a // Tests that the MenuButton does not become pressed if it can be dragged, and a
// DragDropClient is processing the events. // DragDropClient is processing the events.
TEST_F(MenuButtonTest, DraggableMenuButtonDoesNotActivateOnDrag) { TEST_F(MenuButtonTest, DraggableMenuButtonDoesNotActivateOnDrag) {
TestButtonListener button_listener; ConfigureMenuButton(std::make_unique<TestMenuButton>());
CreateMenuButtonWithButtonListener(&button_listener);
TestDragController drag_controller; TestDragController drag_controller;
button()->set_drag_controller(&drag_controller); button()->set_drag_controller(&drag_controller);
...@@ -570,8 +486,8 @@ TEST_F(MenuButtonTest, DraggableMenuButtonDoesNotActivateOnDrag) { ...@@ -570,8 +486,8 @@ TEST_F(MenuButtonTest, DraggableMenuButtonDoesNotActivateOnDrag) {
ui::EventTarget::Priority::kSystem); ui::EventTarget::Priority::kSystem);
generator()->DragMouseBy(10, 0); generator()->DragMouseBy(10, 0);
EXPECT_EQ(nullptr, button_listener.last_sender()); EXPECT_FALSE(button()->clicked());
EXPECT_EQ(Button::STATE_NORMAL, button_listener.last_sender_GetState()); EXPECT_EQ(Button::STATE_NORMAL, button()->last_state());
button()->RemovePreTargetHandler(&drag_client); button()->RemovePreTargetHandler(&drag_client);
} }
...@@ -583,8 +499,7 @@ TEST_F(MenuButtonTest, DraggableMenuButtonDoesNotActivateOnDrag) { ...@@ -583,8 +499,7 @@ TEST_F(MenuButtonTest, DraggableMenuButtonDoesNotActivateOnDrag) {
// Tests if the listener is notified correctly when a gesture tap happens on a // Tests if the listener is notified correctly when a gesture tap happens on a
// MenuButton that has a ButtonListener. // MenuButton that has a ButtonListener.
TEST_F(MenuButtonTest, ActivateDropDownOnGestureTap) { TEST_F(MenuButtonTest, ActivateDropDownOnGestureTap) {
TestButtonListener button_listener; ConfigureMenuButton(std::make_unique<TestMenuButton>());
CreateMenuButtonWithButtonListener(&button_listener);
// Move the mouse outside the menu button so that it doesn't impact the // Move the mouse outside the menu button so that it doesn't impact the
// button state. // button state.
...@@ -595,45 +510,41 @@ TEST_F(MenuButtonTest, ActivateDropDownOnGestureTap) { ...@@ -595,45 +510,41 @@ TEST_F(MenuButtonTest, ActivateDropDownOnGestureTap) {
// Check that MenuButton has notified the listener, while it was in pressed // Check that MenuButton has notified the listener, while it was in pressed
// state. // state.
EXPECT_EQ(button(), button_listener.last_sender()); EXPECT_TRUE(button()->clicked());
EXPECT_EQ(Button::STATE_HOVERED, button_listener.last_sender_GetState()); EXPECT_EQ(Button::STATE_HOVERED, button()->last_state());
// The button should go back to it's normal state since the gesture ended. // The button should go back to its normal state since the gesture ended.
EXPECT_EQ(Button::STATE_NORMAL, button()->GetState()); EXPECT_EQ(Button::STATE_NORMAL, button()->GetState());
} }
// Tests that the button enters a hovered state upon a tap down, before becoming // Tests that the button enters a hovered state upon a tap down, before becoming
// pressed at activation. // pressed at activation.
TEST_F(MenuButtonTest, TouchFeedbackDuringTap) { TEST_F(MenuButtonTest, TouchFeedbackDuringTap) {
TestButtonListener button_listener; ConfigureMenuButton(std::make_unique<TestMenuButton>());
CreateMenuButtonWithButtonListener(&button_listener);
generator()->PressTouch(); generator()->PressTouch();
EXPECT_EQ(Button::STATE_HOVERED, button()->GetState()); EXPECT_EQ(Button::STATE_HOVERED, button()->GetState());
generator()->ReleaseTouch(); generator()->ReleaseTouch();
EXPECT_EQ(Button::STATE_HOVERED, button_listener.last_sender_GetState()); EXPECT_EQ(Button::STATE_HOVERED, button()->last_state());
} }
// Tests that a move event that exits the button returns it to the normal state, // Tests that a move event that exits the button returns it to the normal state,
// and that the button did not activate the listener. // and that the button did not activate the listener.
TEST_F(MenuButtonTest, TouchFeedbackDuringTapCancel) { TEST_F(MenuButtonTest, TouchFeedbackDuringTapCancel) {
TestButtonListener button_listener; ConfigureMenuButton(std::make_unique<TestMenuButton>());
CreateMenuButtonWithButtonListener(&button_listener);
generator()->PressTouch(); generator()->PressTouch();
EXPECT_EQ(Button::STATE_HOVERED, button()->GetState()); EXPECT_EQ(Button::STATE_HOVERED, button()->GetState());
generator()->MoveTouch(gfx::Point(10, 30)); generator()->MoveTouch(gfx::Point(10, 30));
generator()->ReleaseTouch(); generator()->ReleaseTouch();
EXPECT_EQ(Button::STATE_NORMAL, button()->GetState()); EXPECT_EQ(Button::STATE_NORMAL, button()->GetState());
EXPECT_EQ(nullptr, button_listener.last_sender()); EXPECT_FALSE(button()->clicked());
} }
#endif // !defined(OS_APPLE) || defined(USE_AURA) #endif // !defined(OS_APPLE) || defined(USE_AURA)
TEST_F(MenuButtonTest, InkDropHoverWhenShowingMenu) { TEST_F(MenuButtonTest, InkDropHoverWhenShowingMenu) {
PressStateButtonListener button_listener(false); ConfigureMenuButton(std::make_unique<PressStateButton>(false));
CreateMenuButtonWithButtonListener(&button_listener);
button_listener.set_menu_button(button());
generator()->MoveMouseTo(GetOutOfButtonLocation()); generator()->MoveMouseTo(GetOutOfButtonLocation());
EXPECT_FALSE(ink_drop()->is_hovered()); EXPECT_FALSE(ink_drop()->is_hovered());
...@@ -646,62 +557,44 @@ TEST_F(MenuButtonTest, InkDropHoverWhenShowingMenu) { ...@@ -646,62 +557,44 @@ TEST_F(MenuButtonTest, InkDropHoverWhenShowingMenu) {
} }
TEST_F(MenuButtonTest, InkDropIsHoveredAfterDismissingMenuWhenMouseOverButton) { TEST_F(MenuButtonTest, InkDropIsHoveredAfterDismissingMenuWhenMouseOverButton) {
PressStateButtonListener button_listener(false); auto press_state_button = std::make_unique<PressStateButton>(false);
CreateMenuButtonWithButtonListener(&button_listener); auto* test_button = press_state_button.get();
button_listener.set_menu_button(button()); ConfigureMenuButton(std::move(press_state_button));
generator()->MoveMouseTo(button()->bounds().CenterPoint()); generator()->MoveMouseTo(button()->bounds().CenterPoint());
generator()->PressLeftButton(); generator()->PressLeftButton();
EXPECT_FALSE(ink_drop()->is_hovered()); EXPECT_FALSE(ink_drop()->is_hovered());
button_listener.ReleasePressedLock(); test_button->ReleasePressedLock();
EXPECT_TRUE(ink_drop()->is_hovered()); EXPECT_TRUE(ink_drop()->is_hovered());
} }
TEST_F(MenuButtonTest, TEST_F(MenuButtonTest,
InkDropIsntHoveredAfterDismissingMenuWhenMouseOutsideButton) { InkDropIsntHoveredAfterDismissingMenuWhenMouseOutsideButton) {
PressStateButtonListener button_listener(false); auto press_state_button = std::make_unique<PressStateButton>(false);
CreateMenuButtonWithButtonListener(&button_listener); auto* test_button = press_state_button.get();
button_listener.set_menu_button(button()); ConfigureMenuButton(std::move(press_state_button));
generator()->MoveMouseTo(button()->bounds().CenterPoint()); generator()->MoveMouseTo(button()->bounds().CenterPoint());
generator()->PressLeftButton(); generator()->PressLeftButton();
generator()->MoveMouseTo(GetOutOfButtonLocation()); generator()->MoveMouseTo(GetOutOfButtonLocation());
button_listener.ReleasePressedLock(); test_button->ReleasePressedLock();
EXPECT_FALSE(ink_drop()->is_hovered()); EXPECT_FALSE(ink_drop()->is_hovered());
} }
class DestroyButtonInGestureListener : public ButtonListener { // This test ensures there isn't a UAF in MenuButton::OnGestureEvent() if the
public: // button callback deletes the MenuButton.
DestroyButtonInGestureListener() {
menu_button_ = std::make_unique<MenuButton>();
}
~DestroyButtonInGestureListener() override = default;
MenuButton* menu_button() { return menu_button_.get(); }
private:
// ButtonListener:
void ButtonPressed(Button* source, const ui::Event& event) override {
menu_button_.reset();
}
std::unique_ptr<MenuButton> menu_button_;
DISALLOW_COPY_AND_ASSIGN(DestroyButtonInGestureListener);
};
// This test ensures there isn't a UAF in MenuButton::OnGestureEvent() if
// the ButtonListener::ButtonPressed() deletes the MenuButton.
TEST_F(MenuButtonTest, DestroyButtonInGesture) { TEST_F(MenuButtonTest, DestroyButtonInGesture) {
DestroyButtonInGestureListener listener; std::unique_ptr<TestMenuButton> test_menu_button =
std::make_unique<TestMenuButton>(base::BindRepeating(
[](std::unique_ptr<TestMenuButton>* button) { button->reset(); },
&test_menu_button));
ConfigureMenuButton(std::move(test_menu_button));
ui::GestureEvent gesture_event(0, 0, 0, base::TimeTicks::Now(), ui::GestureEvent gesture_event(0, 0, 0, base::TimeTicks::Now(),
ui::GestureEventDetails(ui::ET_GESTURE_TAP)); ui::GestureEventDetails(ui::ET_GESTURE_TAP));
CreateWidget(); button()->OnGestureEvent(&gesture_event);
widget_->SetContentsView(listener.menu_button());
listener.menu_button()->OnGestureEvent(&gesture_event);
} }
} // namespace views } // namespace views
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