#include "ui/touch_selection/longpress_drag_selector.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/test/motion_event_test_utils.h"
#include "arkweb/build/features/features.h"
using ui::test::MockMotionEvent;
namespace ui {
namespace {
const double kSlop = 10.;
class LongPressDragSelectorTest : public testing::Test,
public LongPressDragSelectorClient {
public:
LongPressDragSelectorTest()
: dragging_(false), active_state_changed_(false) {}
~LongPressDragSelectorTest() override {}
void SetSelection(const gfx::PointF& start, const gfx::PointF& end) {
selection_start_ = start;
selection_end_ = end;
}
bool GetAndResetActiveStateChanged() {
bool active_state_changed = active_state_changed_;
active_state_changed_ = false;
return active_state_changed;
}
bool IsDragging() const { return dragging_; }
const gfx::PointF& DragPosition() const { return drag_position_; }
void OnDragBegin(const TouchSelectionDraggable& handler,
const gfx::PointF& drag_position) override {
dragging_ = true;
drag_position_ = drag_position;
}
void UpdateSelectionChanged(
const TouchSelectionDraggable& draggable) override {
}
void OnDragUpdate(const TouchSelectionDraggable& handler,
const gfx::PointF& drag_position) override {
drag_position_ = drag_position;
}
void OnDragEnd(const TouchSelectionDraggable& handler) override {
dragging_ = false;
}
bool IsWithinTapSlop(const gfx::Vector2dF& delta) const override {
return delta.LengthSquared() < (kSlop * kSlop);
}
void OnLongPressDragActiveStateChanged() override {
active_state_changed_ = true;
}
gfx::PointF GetSelectionStart() const override { return selection_start_; }
gfx::PointF GetSelectionEnd() const override { return selection_end_; }
#if BUILDFLAG(ARKWEB_MENU)
gfx::PointF GetSelectionTop() const override { return selection_start_; }
#endif
private:
bool dragging_;
bool active_state_changed_;
gfx::PointF drag_position_;
gfx::PointF selection_start_;
gfx::PointF selection_end_;
};
TEST_F(LongPressDragSelectorTest, BasicDrag) {
LongPressDragSelector selector(this);
MockMotionEvent event;
EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
EXPECT_FALSE(GetAndResetActiveStateChanged());
gfx::PointF selection_start(0, 10);
gfx::PointF selection_end(10, 10);
selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF());
EXPECT_FALSE(GetAndResetActiveStateChanged());
EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
SetSelection(selection_start, selection_end);
selector.OnSelectionActivated();
EXPECT_TRUE(GetAndResetActiveStateChanged());
EXPECT_FALSE(IsDragging());
EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
EXPECT_FALSE(IsDragging());
EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
EXPECT_TRUE(IsDragging());
EXPECT_EQ(selection_end, DragPosition());
EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
EXPECT_TRUE(IsDragging());
EXPECT_EQ(selection_end + gfx::Vector2dF(0, kSlop), DragPosition());
EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 3)));
EXPECT_TRUE(IsDragging());
EXPECT_EQ(selection_end + gfx::Vector2dF(0, kSlop * 2), DragPosition());
EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint()));
EXPECT_FALSE(IsDragging());
EXPECT_TRUE(GetAndResetActiveStateChanged());
}
TEST_F(LongPressDragSelectorTest, DoublePressDrag) {
LongPressDragSelector selector(this);
MockMotionEvent event;
EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
EXPECT_FALSE(GetAndResetActiveStateChanged());
constexpr gfx::PointF selection_start(0, 10);
constexpr gfx::PointF selection_end(10, 10);
selector.OnDoublePressEvent(event.GetEventTime(), gfx::PointF());
EXPECT_FALSE(GetAndResetActiveStateChanged());
EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
SetSelection(selection_start, selection_end);
selector.OnSelectionActivated();
EXPECT_TRUE(GetAndResetActiveStateChanged());
EXPECT_FALSE(IsDragging());
EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
EXPECT_FALSE(IsDragging());
EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
EXPECT_TRUE(IsDragging());
EXPECT_EQ(selection_end, DragPosition());
EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
EXPECT_TRUE(IsDragging());
EXPECT_EQ(selection_end + gfx::Vector2dF(0, kSlop), DragPosition());
EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 3)));
EXPECT_TRUE(IsDragging());
EXPECT_EQ(selection_end + gfx::Vector2dF(0, kSlop * 2), DragPosition());
EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint()));
EXPECT_FALSE(IsDragging());
EXPECT_TRUE(GetAndResetActiveStateChanged());
}
TEST_F(LongPressDragSelectorTest, BasicReverseDrag) {
LongPressDragSelector selector(this);
MockMotionEvent event;
EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
EXPECT_FALSE(GetAndResetActiveStateChanged());
gfx::PointF selection_start(0, 10);
gfx::PointF selection_end(10, 10);
selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF());
EXPECT_FALSE(GetAndResetActiveStateChanged());
SetSelection(selection_start, selection_end);
selector.OnSelectionActivated();
EXPECT_TRUE(GetAndResetActiveStateChanged());
EXPECT_FALSE(IsDragging());
EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 5, 0)));
EXPECT_FALSE(IsDragging());
EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, -kSlop, 0)));
EXPECT_TRUE(IsDragging());
EXPECT_EQ(selection_start, DragPosition());
EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, -kSlop)));
EXPECT_TRUE(IsDragging());
EXPECT_EQ(selection_start + gfx::Vector2dF(kSlop, -kSlop), DragPosition());
EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint()));
EXPECT_FALSE(IsDragging());
EXPECT_TRUE(GetAndResetActiveStateChanged());
}
TEST_F(LongPressDragSelectorTest, NoActiveTouch) {
LongPressDragSelector selector(this);
MockMotionEvent event;
gfx::PointF selection_start(0, 10);
gfx::PointF selection_end(10, 10);
selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF());
SetSelection(selection_start, selection_end);
selector.OnSelectionActivated();
EXPECT_FALSE(GetAndResetActiveStateChanged());
EXPECT_FALSE(IsDragging());
EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
EXPECT_FALSE(IsDragging());
EXPECT_EQ(gfx::PointF(), DragPosition());
}
TEST_F(LongPressDragSelectorTest, NoLongPress) {
LongPressDragSelector selector(this);
MockMotionEvent event;
EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
EXPECT_FALSE(GetAndResetActiveStateChanged());
gfx::PointF selection_start(0, 10);
gfx::PointF selection_end(10, 10);
SetSelection(selection_start, selection_end);
selector.OnSelectionActivated();
EXPECT_FALSE(GetAndResetActiveStateChanged());
EXPECT_FALSE(IsDragging());
EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
EXPECT_FALSE(IsDragging());
EXPECT_EQ(gfx::PointF(), DragPosition());
}
TEST_F(LongPressDragSelectorTest, NoValidLongPress) {
LongPressDragSelector selector(this);
MockMotionEvent event;
EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
EXPECT_FALSE(GetAndResetActiveStateChanged());
gfx::PointF selection_start(0, 10);
gfx::PointF selection_end(10, 10);
SetSelection(selection_start, selection_end);
selector.OnLongPressEvent(event.GetEventTime() - base::Seconds(1),
gfx::PointF());
selector.OnSelectionActivated();
EXPECT_FALSE(GetAndResetActiveStateChanged());
EXPECT_FALSE(IsDragging());
selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF(kSlop, 0));
selector.OnSelectionActivated();
EXPECT_FALSE(GetAndResetActiveStateChanged());
EXPECT_FALSE(IsDragging());
EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
EXPECT_FALSE(IsDragging());
EXPECT_EQ(gfx::PointF(), DragPosition());
}
TEST_F(LongPressDragSelectorTest, NoSelection) {
LongPressDragSelector selector(this);
MockMotionEvent event;
EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
EXPECT_FALSE(GetAndResetActiveStateChanged());
selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF());
EXPECT_FALSE(GetAndResetActiveStateChanged());
EXPECT_FALSE(IsDragging());
EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
EXPECT_FALSE(IsDragging());
EXPECT_EQ(gfx::PointF(), DragPosition());
EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint()));
}
TEST_F(LongPressDragSelectorTest, NoDragMotion) {
LongPressDragSelector selector(this);
MockMotionEvent event;
EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
EXPECT_FALSE(GetAndResetActiveStateChanged());
selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF());
EXPECT_FALSE(GetAndResetActiveStateChanged());
gfx::PointF selection_start(0, 10);
gfx::PointF selection_end(10, 10);
SetSelection(selection_start, selection_end);
selector.OnSelectionActivated();
EXPECT_TRUE(GetAndResetActiveStateChanged());
EXPECT_FALSE(IsDragging());
EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop / 2)));
EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, -kSlop / 2)));
EXPECT_FALSE(IsDragging());
EXPECT_EQ(gfx::PointF(), DragPosition());
EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint()));
EXPECT_TRUE(GetAndResetActiveStateChanged());
}
TEST_F(LongPressDragSelectorTest, SelectionDeactivated) {
LongPressDragSelector selector(this);
MockMotionEvent event;
EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
EXPECT_FALSE(GetAndResetActiveStateChanged());
selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF());
EXPECT_FALSE(GetAndResetActiveStateChanged());
gfx::PointF selection_start(0, 10);
gfx::PointF selection_end(10, 10);
SetSelection(selection_start, selection_end);
selector.OnSelectionActivated();
EXPECT_TRUE(GetAndResetActiveStateChanged());
EXPECT_FALSE(IsDragging());
EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
EXPECT_TRUE(IsDragging());
selector.OnSelectionDeactivated();
EXPECT_TRUE(GetAndResetActiveStateChanged());
EXPECT_FALSE(IsDragging());
EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop)));
EXPECT_FALSE(selector.WillHandleTouchEvent(event.MovePoint(0, 0, kSlop * 2)));
EXPECT_FALSE(IsDragging());
EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint()));
}
TEST_F(LongPressDragSelectorTest, DragFast) {
LongPressDragSelector selector(this);
MockMotionEvent event;
EXPECT_FALSE(selector.WillHandleTouchEvent(event.PressPoint(0, 0)));
EXPECT_FALSE(GetAndResetActiveStateChanged());
gfx::PointF selection_start(0, 10);
gfx::PointF selection_end(10, 10);
selector.OnLongPressEvent(event.GetEventTime(), gfx::PointF());
EXPECT_FALSE(GetAndResetActiveStateChanged());
SetSelection(selection_start, selection_end);
selector.OnSelectionActivated();
EXPECT_TRUE(GetAndResetActiveStateChanged());
EXPECT_FALSE(IsDragging());
EXPECT_TRUE(selector.WillHandleTouchEvent(event.MovePoint(0, 15, 5)));
EXPECT_FALSE(IsDragging());
EXPECT_TRUE(selector.WillHandleTouchEvent(
event.MovePoint(0, 15.f + kSlop * 2.f, 5.f + kSlop)));
EXPECT_TRUE(IsDragging());
EXPECT_EQ(selection_end, DragPosition());
EXPECT_FALSE(selector.WillHandleTouchEvent(event.ReleasePoint()));
EXPECT_FALSE(IsDragging());
EXPECT_TRUE(GetAndResetActiveStateChanged());
}
TEST_F(LongPressDragSelectorTest, ScrollAfterLongPress) {
LongPressDragSelector selector(this);
MockMotionEvent event;
gfx::PointF touch_point(0, 0);
EXPECT_FALSE(selector.WillHandleTouchEvent(
event.PressPoint(touch_point.x(), touch_point.y())));
selector.OnLongPressEvent(event.GetEventTime(), touch_point);
touch_point.Offset(0, 2 * kSlop);
EXPECT_FALSE(selector.WillHandleTouchEvent(
event.MovePoint(0, touch_point.x(), touch_point.y())));
selector.OnScrollBeginEvent();
selector.OnSelectionActivated();
EXPECT_FALSE(GetAndResetActiveStateChanged());
selector.WillHandleTouchEvent(event.ReleasePoint());
}
}
}