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