Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(195)

Unified Diff: ui/events/gesture_detection/gesture_provider_unittest.cc

Issue 243403002: Add multi-finger swipe detection to GestureDetector (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix M_PI Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/events/gesture_detection/gesture_provider.cc ('k') | ui/events/gesture_detection/mock_motion_event.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/events/gesture_detection/gesture_provider_unittest.cc
diff --git a/ui/events/gesture_detection/gesture_provider_unittest.cc b/ui/events/gesture_detection/gesture_provider_unittest.cc
index 9720a20153b49cf63ebaa9b909f03a9cc3228ef4..e91d8d9baaca648466cbc0d8c5ef1343080d00fc 100644
--- a/ui/events/gesture_detection/gesture_provider_unittest.cc
+++ b/ui/events/gesture_detection/gesture_provider_unittest.cc
@@ -73,16 +73,43 @@ class GestureProviderTest : public testing::Test, public GestureProviderClient {
return MockMotionEvent(action, event_time, x0, y0, x1, y1);
}
+ static MockMotionEvent ObtainMotionEvent(
+ base::TimeTicks event_time,
+ MotionEvent::Action action,
+ const std::vector<gfx::PointF>& positions) {
+ switch (positions.size()) {
+ case 1:
+ return MockMotionEvent(
+ action, event_time, positions[0].x(), positions[0].y());
+ case 2:
+ return MockMotionEvent(action,
+ event_time,
+ positions[0].x(),
+ positions[0].y(),
+ positions[1].x(),
+ positions[1].y());
+ case 3:
+ return MockMotionEvent(action,
+ event_time,
+ positions[0].x(),
+ positions[0].y(),
+ positions[1].x(),
+ positions[1].y(),
+ positions[2].x(),
+ positions[2].y());
+ default:
+ CHECK(false) << "MockMotionEvent only supports 1-3 pointers";
+ return MockMotionEvent();
+ }
+ }
+
static MockMotionEvent ObtainMotionEvent(base::TimeTicks event_time,
MotionEvent::Action action) {
return ObtainMotionEvent(event_time, action, kFakeCoordX, kFakeCoordY);
}
// Test
- virtual void SetUp() OVERRIDE {
- gesture_provider_.reset(new GestureProvider(GetDefaultConfig(), this));
- gesture_provider_->SetMultiTouchZoomSupportEnabled(false);
- }
+ virtual void SetUp() OVERRIDE { SetUpWithConfig(GetDefaultConfig()); }
virtual void TearDown() OVERRIDE {
gestures_.clear();
@@ -96,6 +123,15 @@ class GestureProviderTest : public testing::Test, public GestureProviderClient {
gestures_.push_back(gesture);
}
+ void SetUpWithConfig(const GestureProvider::Config& config) {
+ gesture_provider_.reset(new GestureProvider(config, this));
+ gesture_provider_->SetMultiTouchZoomSupportEnabled(false);
+ }
+
+ void ResetGestureDetection() {
+ CancelActiveTouchSequence();
+ gestures_.clear();
+ }
bool CancelActiveTouchSequence() {
if (!gesture_provider_->current_down_event())
return false;
@@ -141,6 +177,10 @@ class GestureProviderTest : public testing::Test, public GestureProviderClient {
return GetDefaultConfig().gesture_detector_config.touch_slop;
}
+ float GetMinSwipeVelocity() const {
+ return GetDefaultConfig().gesture_detector_config.minimum_swipe_velocity;
+ }
+
base::TimeDelta GetLongPressTimeout() const {
return GetDefaultConfig().gesture_detector_config.longpress_timeout;
}
@@ -149,11 +189,16 @@ class GestureProviderTest : public testing::Test, public GestureProviderClient {
return GetDefaultConfig().gesture_detector_config.showpress_timeout;
}
- void SetBeginEndTypesEnabled(bool enabled) {
+ void EnableBeginEndTypes() {
GestureProvider::Config config = GetDefaultConfig();
config.gesture_begin_end_types_enabled = true;
- gesture_provider_.reset(new GestureProvider(config, this));
- gesture_provider_->SetMultiTouchZoomSupportEnabled(false);
+ SetUpWithConfig(config);
+ }
+
+ void EnableMultiFingerSwipe() {
+ GestureProvider::Config config = GetDefaultConfig();
+ config.gesture_detector_config.swipe_enabled = true;
+ SetUpWithConfig(config);
}
bool HasDownEvent() const { return gesture_provider_->current_down_event(); }
@@ -208,6 +253,72 @@ class GestureProviderTest : public testing::Test, public GestureProviderClient {
GetMostRecentGestureEvent().details.bounding_box());
}
+ void TwoFingerSwipe(float vx0, float vy0, float vx1, float vy1) {
+ std::vector<gfx::Vector2dF> velocities;
+ velocities.push_back(gfx::Vector2dF(vx0, vy0));
+ velocities.push_back(gfx::Vector2dF(vx1, vy1));
+ MultiFingerSwipe(velocities);
+ }
+
+ void ThreeFingerSwipe(float vx0,
+ float vy0,
+ float vx1,
+ float vy1,
+ float vx2,
+ float vy2) {
+ std::vector<gfx::Vector2dF> velocities;
+ velocities.push_back(gfx::Vector2dF(vx0, vy0));
+ velocities.push_back(gfx::Vector2dF(vx1, vy1));
+ velocities.push_back(gfx::Vector2dF(vx2, vy2));
+ MultiFingerSwipe(velocities);
+ }
+
+ void MultiFingerSwipe(std::vector<gfx::Vector2dF> velocities) {
+ ASSERT_GT(velocities.size(), 0U);
+
+ base::TimeTicks event_time = base::TimeTicks::Now();
+
+ std::vector<gfx::PointF> positions(velocities.size());
+ for (size_t i = 0; i < positions.size(); ++i)
+ positions[i] = gfx::PointF(kFakeCoordX * (i + 1), kFakeCoordY * (i + 1));
+
+ float dt = kDeltaTimeForFlingSequences.InSecondsF();
+
+ // Each pointer down should be a separate event.
+ for (size_t i = 0; i < positions.size(); ++i) {
+ const size_t pointer_count = i + 1;
+ std::vector<gfx::PointF> event_positions(pointer_count);
+ event_positions.assign(positions.begin(),
+ positions.begin() + pointer_count);
+ MockMotionEvent event =
+ ObtainMotionEvent(event_time,
+ pointer_count > 1 ? MotionEvent::ACTION_POINTER_DOWN
+ : MotionEvent::ACTION_DOWN,
+ event_positions);
+ EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
+ }
+
+ for (size_t i = 0; i < positions.size(); ++i)
+ positions[i] += gfx::ScaleVector2d(velocities[i], dt);
+ MockMotionEvent event =
+ ObtainMotionEvent(event_time + kDeltaTimeForFlingSequences,
+ MotionEvent::ACTION_MOVE,
+ positions);
+ EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
+
+ for (size_t i = 0; i < positions.size(); ++i)
+ positions[i] += gfx::ScaleVector2d(velocities[i], dt);
+ event = ObtainMotionEvent(event_time + 2 * kDeltaTimeForFlingSequences,
+ MotionEvent::ACTION_MOVE,
+ positions);
+ EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
+
+ event = ObtainMotionEvent(event_time + 2 * kDeltaTimeForFlingSequences,
+ MotionEvent::ACTION_POINTER_UP,
+ positions);
+ EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
+ }
+
static void RunTasksAndWait(base::TimeDelta delay) {
base::MessageLoop::current()->PostDelayedTask(
FROM_HERE, base::MessageLoop::QuitClosure(), delay);
@@ -1317,6 +1428,105 @@ TEST_F(GestureProviderTest, PinchZoom) {
GetMostRecentGestureEvent().details.bounding_box());
}
+// Verify that multi-finger swipe sends the proper event sequence.
+TEST_F(GestureProviderTest, MultiFingerSwipe) {
+ EnableMultiFingerSwipe();
+ gesture_provider_->SetMultiTouchZoomSupportEnabled(false);
+ const float min_swipe_velocity = GetMinSwipeVelocity();
+
+ // Swipe right.
+ TwoFingerSwipe(min_swipe_velocity * 2, 0, min_swipe_velocity * 2, 0);
+ EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_MULTIFINGER_SWIPE));
+ EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_right());
+ EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
+ ResetGestureDetection();
+
+ // Swipe left.
+ TwoFingerSwipe(-min_swipe_velocity * 2, 0, -min_swipe_velocity * 2, 0);
+ EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_MULTIFINGER_SWIPE));
+ EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_left());
+ EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
+ ResetGestureDetection();
+
+ // No swipe with different touch directions.
+ TwoFingerSwipe(min_swipe_velocity * 2, 0, -min_swipe_velocity * 2, 0);
+ EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_MULTIFINGER_SWIPE));
+ ResetGestureDetection();
+
+ // No swipe without a dominant direction.
+ TwoFingerSwipe(min_swipe_velocity * 2,
+ min_swipe_velocity * 2,
+ min_swipe_velocity * 2,
+ min_swipe_velocity * 2);
+ EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_MULTIFINGER_SWIPE));
+ ResetGestureDetection();
+
+ // Swipe up with non-zero velocities on both axes and dominant direction.
+ TwoFingerSwipe(-min_swipe_velocity,
+ min_swipe_velocity * 4,
+ -min_swipe_velocity,
+ min_swipe_velocity * 4);
+ EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_MULTIFINGER_SWIPE));
+ EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_down());
+ EXPECT_FALSE(GetMostRecentGestureEvent().details.swipe_left());
+ EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
+ ResetGestureDetection();
+
+ // Swipe down with non-zero velocities on both axes.
+ TwoFingerSwipe(min_swipe_velocity,
+ -min_swipe_velocity * 4,
+ min_swipe_velocity,
+ -min_swipe_velocity * 4);
+ EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_MULTIFINGER_SWIPE));
+ EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_up());
+ EXPECT_FALSE(GetMostRecentGestureEvent().details.swipe_right());
+ EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
+ ResetGestureDetection();
+
+ // No swipe without sufficient velocity.
+ TwoFingerSwipe(min_swipe_velocity / 2, 0, 0, 0);
+ EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_MULTIFINGER_SWIPE));
+ ResetGestureDetection();
+
+ // Swipe up with one small and one medium velocity in slightly different but
+ // not opposing directions.
+ TwoFingerSwipe(min_swipe_velocity / 2,
+ min_swipe_velocity / 2,
+ 0,
+ min_swipe_velocity * 2);
+ EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_MULTIFINGER_SWIPE));
+ EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_down());
+ EXPECT_FALSE(GetMostRecentGestureEvent().details.swipe_right());
+ EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
+ ResetGestureDetection();
+
+ // No swipe in orthogonal directions.
+ TwoFingerSwipe(min_swipe_velocity * 2, 0, 0, min_swipe_velocity * 7);
+ EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_MULTIFINGER_SWIPE));
+ ResetGestureDetection();
+
+ // Three finger swipe in same directions.
+ ThreeFingerSwipe(min_swipe_velocity * 2,
+ 0,
+ min_swipe_velocity * 3,
+ 0,
+ min_swipe_velocity * 4,
+ 0);
+ EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_MULTIFINGER_SWIPE));
+ EXPECT_TRUE(GetMostRecentGestureEvent().details.swipe_right());
+ EXPECT_EQ(3, GetMostRecentGestureEvent().details.touch_points());
+ ResetGestureDetection();
+
+ // No three finger swipe in different directions.
+ ThreeFingerSwipe(min_swipe_velocity * 2,
+ 0,
+ 0,
+ min_swipe_velocity * 3,
+ min_swipe_velocity * 4,
+ 0);
+ EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_MULTIFINGER_SWIPE));
+}
+
// Verify that the timer of LONG_PRESS will be cancelled when scrolling begins
// so LONG_PRESS and LONG_TAP won't be triggered.
TEST_F(GestureProviderTest, GesturesCancelledAfterLongPressCausesLostFocus) {
@@ -1439,7 +1649,7 @@ TEST_F(GestureProviderTest, DoubleTapDragZoomCancelledOnSecondaryPointerDown) {
// Verify that gesture begin and gesture end events are dispatched correctly.
TEST_F(GestureProviderTest, GestureBeginAndEnd) {
- SetBeginEndTypesEnabled(true);
+ EnableBeginEndTypes();
base::TimeTicks event_time = base::TimeTicks::Now();
EXPECT_EQ(0U, GetReceivedGestureCount());
« no previous file with comments | « ui/events/gesture_detection/gesture_provider.cc ('k') | ui/events/gesture_detection/mock_motion_event.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698