summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorbokan@chromium.org <bokan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-10 22:44:05 +0000
committerbokan@chromium.org <bokan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-10 22:44:05 +0000
commitd5d60089a9dd4d5220fe547866dd547d376ed251 (patch)
tree39668fc9846fa827e86caafb44bb065d81ec259e /content
parenta86a61db8cdf05123dd10569c40f90d9bb5fc514 (diff)
downloadchromium_src-d5d60089a9dd4d5220fe547866dd547d376ed251.zip
chromium_src-d5d60089a9dd4d5220fe547866dd547d376ed251.tar.gz
chromium_src-d5d60089a9dd4d5220fe547866dd547d376ed251.tar.bz2
Fix for often broken fling scrolls on Aura
Because the Animate() method was recently changed to pass the current frame's tick time in r259735, getting the diff between it and the fling's start time would often result in a negative time delta. This caused the fling to report no scrolling and the scroll would stop. We still want to start flinging immediately where possible so instead of letting Animate() always set the startTime and losing a frame, we do it only for a non-positive time delta. This does not affect Android since its gesture fling ignores the passed delta and uses gfx::FrameTime::Now(). BUG=360633 Review URL: https://codereview.chromium.org/232683003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@263104 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/renderer/input/input_handler_proxy.cc3
-rw-r--r--content/renderer/input/input_handler_proxy_unittest.cc68
2 files changed, 70 insertions, 1 deletions
diff --git a/content/renderer/input/input_handler_proxy.cc b/content/renderer/input/input_handler_proxy.cc
index 6172e60..cecd0f54 100644
--- a/content/renderer/input/input_handler_proxy.cc
+++ b/content/renderer/input/input_handler_proxy.cc
@@ -352,7 +352,8 @@ void InputHandlerProxy::Animate(base::TimeTicks time) {
return;
double monotonic_time_sec = InSecondsF(time);
- if (!fling_parameters_.startTime) {
+ if (!fling_parameters_.startTime ||
+ monotonic_time_sec <= fling_parameters_.startTime) {
fling_parameters_.startTime = monotonic_time_sec;
input_handler_->ScheduleAnimation();
return;
diff --git a/content/renderer/input/input_handler_proxy_unittest.cc b/content/renderer/input/input_handler_proxy_unittest.cc
index 2f0be4a..4f80340 100644
--- a/content/renderer/input/input_handler_proxy_unittest.cc
+++ b/content/renderer/input/input_handler_proxy_unittest.cc
@@ -1310,5 +1310,73 @@ TEST_F(InputHandlerProxyTest, GestureFlingCancelledByKeyboardEvent) {
EXPECT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
}
+TEST_F(InputHandlerProxyTest, GestureFlingWithNegativeTimeDelta) {
+ // We shouldn't send any events to the widget for this gesture.
+ expected_disposition_ = InputHandlerProxy::DID_HANDLE;
+ VERIFY_AND_RESET_MOCKS();
+
+ EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
+ .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
+
+ gesture_.type = WebInputEvent::GestureScrollBegin;
+ gesture_.sourceDevice = WebGestureEvent::Touchscreen;
+ EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
+
+ VERIFY_AND_RESET_MOCKS();
+
+ // On the fling start, we should schedule an animation but not actually start
+ // scrolling.
+ base::TimeDelta startTimeOffset = base::TimeDelta::FromMilliseconds(10);
+ gesture_.type = WebInputEvent::GestureFlingStart;
+ WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
+ WebPoint fling_point = WebPoint(7, 13);
+ WebPoint fling_global_point = WebPoint(17, 23);
+ int modifiers = WebInputEvent::ControlKey;
+ gesture_.timeStampSeconds = startTimeOffset.InSecondsF();
+ gesture_.data.flingStart.velocityX = fling_delta.x;
+ gesture_.data.flingStart.velocityY = fling_delta.y;
+ gesture_.sourceDevice = WebGestureEvent::Touchscreen;
+ gesture_.x = fling_point.x;
+ gesture_.y = fling_point.y;
+ gesture_.globalX = fling_global_point.x;
+ gesture_.globalY = fling_global_point.y;
+ gesture_.modifiers = modifiers;
+ EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
+ .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
+ EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
+
+ testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
+
+ // If we get a negative time delta, that is, the Animation tick time happens
+ // before the fling's start time then we should *not* try scrolling and
+ // instead reset the fling start time.
+ EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_,
+ ScrollBy(testing::_,
+ testing::_)).Times(0);
+ base::TimeTicks time =
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(8);
+ input_handler_->Animate(time);
+
+ testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
+
+ // The first call should have reset the start time so subsequent calls should
+ // generate scroll events.
+ EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_,
+ ScrollBy(testing::_,
+ testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
+ .WillOnce(testing::Return(true));
+
+ input_handler_->Animate(time + base::TimeDelta::FromMilliseconds(1));
+
+ testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
+
+ EXPECT_CALL(mock_input_handler_, ScrollEnd());
+ gesture_.type = WebInputEvent::GestureFlingCancel;
+ EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
+}
+
} // namespace
} // namespace content