Commit 4a0c0947 authored by sahel's avatar sahel Committed by Commit bot

Tap suppression controller forwards the next TapCancel when the stashed TapDown is forwarded.

When the controller forwards the stashed TapDown event after
tapDownTimer expiration, it should forward the next TapCancel event as
well to maintain a valid input stream. The rest of the tap ending events
should get suppressed till the next TapDown event.

BUG=674602
TEST=TapSuppressionControllerTest.GFCAckBeforeTapSufficientlyLateTapCancel

Review-Url: https://codereview.chromium.org/2613533003
Cr-Commit-Position: refs/heads/master@{#441396}
parent 05683872
...@@ -71,8 +71,10 @@ class MockTapSuppressionController : public TapSuppressionController, ...@@ -71,8 +71,10 @@ class MockTapSuppressionController : public TapSuppressionController,
} }
void SendTapCancel() { void SendTapCancel() {
bool stashed_tap_down_forwarded =
last_actions_ & STASHED_TAP_DOWN_FORWARDED;
last_actions_ = NONE; last_actions_ = NONE;
if (ShouldSuppressTapEnd()) if (!stashed_tap_down_forwarded && ShouldSuppressTapEnd())
last_actions_ |= TAP_CANCEL_SUPPRESSED; last_actions_ |= TAP_CANCEL_SUPPRESSED;
else else
last_actions_ |= TAP_CANCEL_FORWARDED; last_actions_ |= TAP_CANCEL_FORWARDED;
...@@ -245,7 +247,7 @@ TEST_F(TapSuppressionControllerTest, GFCAckBeforeTapSufficientlyLateTapUp) { ...@@ -245,7 +247,7 @@ TEST_F(TapSuppressionControllerTest, GFCAckBeforeTapSufficientlyLateTapUp) {
EXPECT_EQ(MockTapSuppressionController::LAST_CANCEL_STOPPED_FLING, EXPECT_EQ(MockTapSuppressionController::LAST_CANCEL_STOPPED_FLING,
tap_suppression_controller_->state()); tap_suppression_controller_->state());
// Send MouseDown. This MouseDown should be suppressed, for now. // Send TapDown. This TapDown should be suppressed, for now.
tap_suppression_controller_->SendTapDown(); tap_suppression_controller_->SendTapDown();
EXPECT_EQ(MockTapSuppressionController::TAP_DOWN_DEFERRED, EXPECT_EQ(MockTapSuppressionController::TAP_DOWN_DEFERRED,
tap_suppression_controller_->last_actions()); tap_suppression_controller_->last_actions());
...@@ -270,6 +272,49 @@ TEST_F(TapSuppressionControllerTest, GFCAckBeforeTapSufficientlyLateTapUp) { ...@@ -270,6 +272,49 @@ TEST_F(TapSuppressionControllerTest, GFCAckBeforeTapSufficientlyLateTapUp) {
tap_suppression_controller_->state()); tap_suppression_controller_->state());
} }
// Test TapSuppressionController for when stashed TapDown gets forwarded.
// The next TapCancel should be forwarded as well to maintain a valid input
// stream.
TEST_F(TapSuppressionControllerTest, GFCAckBeforeTapSufficientlyLateTapCancel) {
// Send GestureFlingCancel.
tap_suppression_controller_->SendGestureFlingCancel();
EXPECT_EQ(MockTapSuppressionController::NONE,
tap_suppression_controller_->last_actions());
EXPECT_EQ(MockTapSuppressionController::GFC_IN_PROGRESS,
tap_suppression_controller_->state());
// Send processed GestureFlingCancel Ack.
tap_suppression_controller_->SendGestureFlingCancelAck(true);
EXPECT_EQ(MockTapSuppressionController::NONE,
tap_suppression_controller_->last_actions());
EXPECT_EQ(MockTapSuppressionController::LAST_CANCEL_STOPPED_FLING,
tap_suppression_controller_->state());
// Send TapDown. This TapDown should be suppressed, for now.
tap_suppression_controller_->SendTapDown();
EXPECT_EQ(MockTapSuppressionController::TAP_DOWN_DEFERRED,
tap_suppression_controller_->last_actions());
EXPECT_EQ(MockTapSuppressionController::TAP_DOWN_STASHED,
tap_suppression_controller_->state());
// Wait more than the delay for TapDown timer. This should release the
// previously stashed TapDown.
tap_suppression_controller_->AdvanceTime(TimeDelta::FromMilliseconds(13));
EXPECT_EQ(MockTapSuppressionController::STASHED_TAP_DOWN_FORWARDED,
tap_suppression_controller_->last_actions());
EXPECT_EQ(MockTapSuppressionController::SUPPRESSING_TAPS,
tap_suppression_controller_->state());
// Send TapCancel. This TapCancel should be forwarded.
// When a TapDown is forwarded because of the timer expiration, the next
// TapCancel should get forwarded as well to maintain a valid input stream.
tap_suppression_controller_->SendTapCancel();
EXPECT_EQ(MockTapSuppressionController::TAP_CANCEL_FORWARDED,
tap_suppression_controller_->last_actions());
EXPECT_EQ(MockTapSuppressionController::SUPPRESSING_TAPS,
tap_suppression_controller_->state());
}
// Test TapSuppressionController for when GestureFlingCancel Ack comes before // Test TapSuppressionController for when GestureFlingCancel Ack comes before
// TapDown, but there is a small delay between the Ack and TapDown. // TapDown, but there is a small delay between the Ack and TapDown.
TEST_F(TapSuppressionControllerTest, GFCAckBeforeTapInsufficientlyLateTapDown) { TEST_F(TapSuppressionControllerTest, GFCAckBeforeTapInsufficientlyLateTapDown) {
......
...@@ -33,6 +33,7 @@ bool TouchscreenTapSuppressionController::FilterTapEvent( ...@@ -33,6 +33,7 @@ bool TouchscreenTapSuppressionController::FilterTapEvent(
const GestureEventWithLatencyInfo& event) { const GestureEventWithLatencyInfo& event) {
switch (event.event.type) { switch (event.event.type) {
case WebInputEvent::GestureTapDown: case WebInputEvent::GestureTapDown:
forward_next_tap_cancel_ = false;
if (!controller_.ShouldDeferTapDown()) if (!controller_.ShouldDeferTapDown())
return false; return false;
stashed_tap_down_.reset(new GestureEventWithLatencyInfo(event)); stashed_tap_down_.reset(new GestureEventWithLatencyInfo(event));
...@@ -58,6 +59,8 @@ bool TouchscreenTapSuppressionController::FilterTapEvent( ...@@ -58,6 +59,8 @@ bool TouchscreenTapSuppressionController::FilterTapEvent(
return !!stashed_tap_down_; return !!stashed_tap_down_;
case WebInputEvent::GestureTapCancel: case WebInputEvent::GestureTapCancel:
return !forward_next_tap_cancel_ && controller_.ShouldSuppressTapEnd();
case WebInputEvent::GestureTap: case WebInputEvent::GestureTap:
case WebInputEvent::GestureDoubleTap: case WebInputEvent::GestureDoubleTap:
case WebInputEvent::GestureLongTap: case WebInputEvent::GestureLongTap:
...@@ -94,6 +97,7 @@ void TouchscreenTapSuppressionController::ForwardStashedTapDown() { ...@@ -94,6 +97,7 @@ void TouchscreenTapSuppressionController::ForwardStashedTapDown() {
gesture_event_queue_->ForwardGestureEvent(*tap_down); gesture_event_queue_->ForwardGestureEvent(*tap_down);
stashed_show_press_.reset(); stashed_show_press_.reset();
stashed_long_press_.reset(); stashed_long_press_.reset();
forward_next_tap_cancel_ = true;
} }
} // namespace content } // namespace content
...@@ -50,6 +50,11 @@ class TouchscreenTapSuppressionController ...@@ -50,6 +50,11 @@ class TouchscreenTapSuppressionController
ScopedGestureEvent stashed_show_press_; ScopedGestureEvent stashed_show_press_;
ScopedGestureEvent stashed_long_press_; ScopedGestureEvent stashed_long_press_;
// This is true when the stashed GestureTapDown event gets forwarded. The
// controller should forward the next GestureTapCancel as well to maintain a
// valid input stream.
bool forward_next_tap_cancel_;
// The core controller of tap suppression. // The core controller of tap suppression.
TapSuppressionController controller_; TapSuppressionController controller_;
......
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