Commit 1b241325 authored by jdduke's avatar jdduke Committed by Commit bot

Prevent orthogonal fling accumulation

Tighten the directional comparison for fling accumulation, preventing
perfectly orthogonal flings from accumulating. Also adjust Android's
ContentViewScrollingTest#testFling integration test to scale the
fling by the device scale factor, ensuring consistent results all
all displays.

BUG=406848

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

Cr-Commit-Position: refs/heads/master@{#296507}
parent 572a998c
......@@ -19,7 +19,7 @@ import org.chromium.content.browser.test.util.Criteria;
import org.chromium.content.browser.test.util.CriteriaHelper;
import org.chromium.content_shell_apk.ContentShellTestBase;
/*
/**
* Tests that we can scroll and fling a ContentView running inside ContentShell.
*/
public class ContentViewScrollingTest extends ContentShellTestBase {
......@@ -152,24 +152,30 @@ public class ContentViewScrollingTest extends ContentShellTestBase {
@SmallTest
@Feature({"Main"})
public void testFling() throws Throwable {
// Scaling the initial velocity by the device scale factor ensures that
// it's of sufficient magnitude for all displays densities.
float deviceScaleFactor =
getInstrumentation().getTargetContext().getResources().getDisplayMetrics().density;
int velocity = (int) (1000 * deviceScaleFactor);
// Vertical fling to lower-left.
fling(0, -1000);
fling(0, -velocity);
assertWaitForScroll(true, false);
// Horizontal fling to lower-right.
fling(-1000, 0);
fling(-velocity, 0);
assertWaitForScroll(false, false);
// Vertical fling to upper-right.
fling(0, 1000);
fling(0, velocity);
assertWaitForScroll(false, true);
// Horizontal fling to top-left.
fling(1000, 0);
fling(velocity, 0);
assertWaitForScroll(true, true);
// Diagonal fling to bottom-right.
fling(-1000, -1000);
fling(-velocity, -velocity);
assertWaitForScroll(false, false);
}
......
......@@ -70,7 +70,7 @@ bool ShouldSuppressScrollForFlingBoosting(
gfx::Vector2dF dx(scroll_update_event.data.scrollUpdate.deltaX,
scroll_update_event.data.scrollUpdate.deltaY);
if (gfx::DotProduct(current_fling_velocity, dx) < 0)
if (gfx::DotProduct(current_fling_velocity, dx) <= 0)
return false;
if (time_since_last_boost_event < 0.001)
......@@ -94,7 +94,7 @@ bool ShouldBoostFling(const gfx::Vector2dF& current_fling_velocity,
fling_start_event.data.flingStart.velocityX,
fling_start_event.data.flingStart.velocityY);
if (gfx::DotProduct(current_fling_velocity, new_fling_velocity) < 0)
if (gfx::DotProduct(current_fling_velocity, new_fling_velocity) <= 0)
return false;
if (current_fling_velocity.LengthSquared() < kMinBoostFlingSpeedSquare)
......@@ -550,6 +550,8 @@ bool InputHandlerProxy::FilterInputEventForFlingBoosting(
WebFloatPoint velocity(current_fling_velocity_.x(),
current_fling_velocity_.y());
deferred_fling_cancel_time_seconds_ = 0;
disallow_horizontal_fling_scroll_ = !velocity.x;
disallow_vertical_fling_scroll_ = !velocity.y;
last_fling_boost_event_ = WebGestureEvent();
fling_curve_.reset(client_->CreateFlingAnimationCurve(
gesture_event.sourceDevice,
......
......@@ -1793,6 +1793,48 @@ TEST_F(InputHandlerProxyTest, NoFlingBoostIfScrollDelayed) {
VERIFY_AND_RESET_MOCKS();
}
TEST_F(InputHandlerProxyTest, NoFlingBoostIfFlingInDifferentDirection) {
base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
base::TimeTicks time = base::TimeTicks() + dt;
WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
WebPoint fling_point = WebPoint(7, 13);
StartFling(
time, blink::WebGestureDeviceTouchscreen, fling_delta, fling_point);
// Cancel the fling. The fling cancellation should be deferred to allow
// fling boosting events to arrive.
time += dt;
CancelFling(time);
// If the new fling is orthogonal to the existing fling, no boosting should
// take place, with the new fling replacing the old.
WebFloatPoint orthogonal_fling_delta =
WebFloatPoint(fling_delta.y, -fling_delta.x);
gesture_ = CreateFling(time,
blink::WebGestureDeviceTouchscreen,
orthogonal_fling_delta,
fling_point,
fling_point,
0);
EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
VERIFY_AND_RESET_MOCKS();
// Note that the new fling delta uses the orthogonal, unboosted fling
// velocity.
time += dt;
float expected_delta = dt.InSecondsF() * -orthogonal_fling_delta.y;
EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_,
ScrollBy(testing::_,
testing::Property(&gfx::Vector2dF::y,
testing::Eq(expected_delta))))
.WillOnce(testing::Return(true));
input_handler_->Animate(time);
VERIFY_AND_RESET_MOCKS();
}
TEST_F(InputHandlerProxyTest, NoFlingBoostIfScrollInDifferentDirection) {
base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
base::TimeTicks time = base::TimeTicks() + dt;
......
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