Commit 5646751f authored by tdresser@chromium.org's avatar tdresser@chromium.org

[Aura] Reduce frequency of PinchUpdate events.

BUG=373318
TEST=GestureProviderTest.PinchZoomWithThreshold

Review URL: https://codereview.chromium.org/298823006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@272336 0039d316-1c4b-4281-b951-d872f2087c98
parent ced667b3
......@@ -52,6 +52,8 @@ ScaleGestureDetector::Config DefaultScaleGestureDetectorConfig() {
config.gesture_detector_config = DefaultGestureDetectorConfig();
config.min_scaling_touch_major = GestureConfiguration::default_radius() * 2;
config.min_scaling_span = GestureConfiguration::min_scaling_span_in_pixels();
config.min_pinch_update_span_delta =
GestureConfiguration::min_pinch_update_distance_in_pixels();
return config;
}
......
......@@ -130,7 +130,8 @@ class GestureProvider::ScaleGestureListenerImpl
: scale_gesture_detector_(config, this),
provider_(provider),
ignore_multitouch_events_(false),
pinch_event_sent_(false) {}
pinch_event_sent_(false),
min_pinch_update_span_delta_(config.min_pinch_update_span_delta) {}
bool OnTouchEvent(const MotionEvent& event) {
// TODO: Need to deal with multi-touch transition.
......@@ -182,6 +183,11 @@ class GestureProvider::ScaleGestureListenerImpl
GetBoundingBox(e)));
}
if (std::abs(detector.GetCurrentSpan() - detector.GetPreviousSpan()) <
min_pinch_update_span_delta_) {
return false;
}
float scale = detector.GetScaleFactor();
if (scale == 1)
return true;
......@@ -247,6 +253,10 @@ class GestureProvider::ScaleGestureListenerImpl
// Whether any pinch zoom event has been sent to native.
bool pinch_event_sent_;
// The minimum change in span required before this is considered a pinch. See
// crbug.com/373318.
float min_pinch_update_span_delta_;
DISALLOW_COPY_AND_ASSIGN(ScaleGestureListenerImpl);
};
......
......@@ -217,6 +217,13 @@ class GestureProviderTest : public testing::Test, public GestureProviderClient {
SetUpWithConfig(config);
}
void SetMinPinchUpdateSpanDelta(float min_pinch_update_span_delta) {
GestureProvider::Config config = GetDefaultConfig();
config.scale_gesture_detector_config.min_pinch_update_span_delta =
min_pinch_update_span_delta;
SetUpWithConfig(config);
}
bool HasDownEvent() const { return gesture_provider_->current_down_event(); }
protected:
......@@ -1910,4 +1917,85 @@ TEST_F(GestureProviderTest, TwoFingerTapCancelledByDistanceBetweenPointers) {
EXPECT_EQ(1U, GetReceivedGestureCount());
}
// Verify that pinch zoom only sends updates which exceed the
// min_pinch_update_span_delta.
TEST_F(GestureProviderTest, PinchZoomWithThreshold) {
const float kMinPinchUpdateDistance = 5;
base::TimeTicks event_time = base::TimeTicks::Now();
const float touch_slop = GetTouchSlop();
SetMinPinchUpdateSpanDelta(kMinPinchUpdateDistance);
gesture_provider_->SetDoubleTapSupportForPageEnabled(false);
gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
gesture_provider_->SetMultiTouchZoomSupportEnabled(true);
int secondary_coord_x = kFakeCoordX + 20 * touch_slop;
int secondary_coord_y = kFakeCoordY + 20 * touch_slop;
// First finger down.
MockMotionEvent event =
ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
// Second finger down.
event = ObtainMotionEvent(event_time,
MotionEvent::ACTION_POINTER_DOWN,
kFakeCoordX,
kFakeCoordY,
secondary_coord_x,
secondary_coord_y);
gesture_provider_->OnTouchEvent(event);
EXPECT_EQ(1U, GetReceivedGestureCount());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
// Move second finger.
secondary_coord_x += 5 * touch_slop;
secondary_coord_y += 5 * touch_slop;
event = ObtainMotionEvent(event_time,
MotionEvent::ACTION_MOVE,
kFakeCoordX,
kFakeCoordY,
secondary_coord_x,
secondary_coord_y);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE));
// Small move, shouldn't trigger pinch.
event = ObtainMotionEvent(event_time,
MotionEvent::ACTION_MOVE,
kFakeCoordX,
kFakeCoordY,
secondary_coord_x + kMinPinchUpdateDistance,
secondary_coord_y);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
// Small move, but combined with the previous move, should trigger pinch. We
// need to overshoot kMinPinchUpdateDistance by a fair bit, as the span
// calculation factors in touch radius.
const float kOvershootMinPinchUpdateDistance = 3;
event = ObtainMotionEvent(event_time,
MotionEvent::ACTION_MOVE,
kFakeCoordX,
kFakeCoordY,
secondary_coord_x + kMinPinchUpdateDistance +
kOvershootMinPinchUpdateDistance,
secondary_coord_y);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
}
} // namespace ui
......@@ -33,7 +33,9 @@ const float kScaleFactor = .5f;
ScaleGestureDetector::Config::Config()
: min_scaling_touch_major(48),
min_scaling_span(200),
quick_scale_enabled(true) {}
quick_scale_enabled(true),
min_pinch_update_span_delta(0) {
}
ScaleGestureDetector::Config::~Config() {}
......
......@@ -33,6 +33,10 @@ class ScaleGestureDetector : public GestureDetector::SimpleGestureListener {
// Whether double-tap drag scaling is enabled.
bool quick_scale_enabled;
// Minimum pinch span change before pinch occurs (in dips). See
// crbug.com/373318.
float min_pinch_update_span_delta;
};
class ScaleGestureListener {
......
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