TouchEventQueueTest()
: sent_event_count_(0),
acked_event_count_(0),
- last_acked_event_state_(INPUT_EVENT_ACK_STATE_UNKNOWN) {}
+ last_acked_event_state_(INPUT_EVENT_ACK_STATE_UNKNOWN),
+ slop_length_dips_(0),
+ touch_scrolling_mode_(TouchEventQueue::TOUCH_SCROLLING_MODE_DEFAULT) {}
virtual ~TouchEventQueueTest() {}
// testing::Test
virtual void SetUp() OVERRIDE {
- queue_.reset(new TouchEventQueue(this));
- queue_->OnHasTouchEventHandlers(true);
+ ResetQueueWithParameters(touch_scrolling_mode_, slop_length_dips_);
+ }
+
+ virtual void SetTouchScrollingMode(TouchEventQueue::TouchScrollingMode mode) {
+ touch_scrolling_mode_ = mode;
+ ResetQueueWithParameters(touch_scrolling_mode_, slop_length_dips_);
}
virtual void TearDown() OVERRIDE {
++sent_event_count_;
last_sent_event_ = event.event;
if (sync_ack_result_)
- SendTouchEventACK(*sync_ack_result_.Pass());
+ SendTouchEventAck(*sync_ack_result_.Pass());
}
virtual void OnTouchEventAck(
queue_->SetAckTimeoutEnabled(true, timeout_delay_ms);
}
+ void SetUpForTouchMoveSlopTesting(double slop_length_dips) {
+ slop_length_dips_ = slop_length_dips;
+ ResetQueueWithParameters(touch_scrolling_mode_, slop_length_dips_);
+ }
+
void SendTouchEvent(const WebTouchEvent& event) {
queue_->QueueEvent(TouchEventWithLatencyInfo(event, ui::LatencyInfo()));
}
GestureEventWithLatencyInfo(event, ui::LatencyInfo()));
}
- void SendTouchEventACK(InputEventAckState ack_result) {
+ void SendTouchEventAck(InputEventAckState ack_result) {
queue_->ProcessTouchAck(ack_result, ui::LatencyInfo());
}
+ void SendGestureEventAck(WebInputEvent::Type type,
+ InputEventAckState ack_result) {
+ blink::WebGestureEvent gesture_event;
+ gesture_event.type = type;
+ GestureEventWithLatencyInfo event(gesture_event, ui::LatencyInfo());
+ queue_->OnGestureEventAck(event, ack_result);
+ }
+
void SetFollowupEvent(const WebTouchEvent& event) {
followup_touch_event_.reset(new WebTouchEvent(event));
}
touch_event_.ResetPoints();
}
+ void ResetQueueWithParameters(TouchEventQueue::TouchScrollingMode mode,
+ double slop_length_dips) {
+ queue_.reset(new TouchEventQueue(this, mode, slop_length_dips));
+ queue_->OnHasTouchEventHandlers(true);
+ }
+
scoped_ptr<TouchEventQueue> queue_;
size_t sent_event_count_;
size_t acked_event_count_;
scoped_ptr<WebTouchEvent> followup_touch_event_;
scoped_ptr<WebGestureEvent> followup_gesture_event_;
scoped_ptr<InputEventAckState> sync_ack_result_;
+ double slop_length_dips_;
+ TouchEventQueue::TouchScrollingMode touch_scrolling_mode_;
base::MessageLoopForUI message_loop_;
};
EXPECT_EQ(0U, GetAndResetSentEventCount());
// Receive an ACK for the first touch-event.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, queued_event_count());
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
EXPECT_EQ(WebInputEvent::TouchStart, acked_event().type);
// Receive an ACK for the second touch-event.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(0U, queued_event_count());
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
// Receive an ACK for the first touch-event. One of the queued touch-event
// should be forwarded.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(31U, queued_event_count());
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
EXPECT_EQ(0U, queued_event_count());
// The ack should be ignored as the touch queue is now empty.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
EXPECT_EQ(0U, GetAndResetAckedEventCount());
EXPECT_EQ(0U, queued_event_count());
EXPECT_EQ(3U, queued_event_count());
// ACK the press. Coalesced touch-move events should be sent.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(2U, queued_event_count());
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, acked_event_state());
// ACK the moves.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, queued_event_count());
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(10U, GetAndResetAckedEventCount());
EXPECT_EQ(WebInputEvent::TouchMove, acked_event().type);
// ACK the release.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(0U, queued_event_count());
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(2U, queued_event_count());
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(1U, queued_event_count());
// Receive an ACK for the press. This should cause the queued touch-move to
// be sent to the renderer.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(1U, queued_event_count());
EXPECT_EQ(0U, queued_event_count());
// Now receive an ACK for the move.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(0U, queued_event_count());
}
// Receive an ACK for the first touch-event. This should release the queued
// touch-event, but it should not be sent to the renderer.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
EXPECT_EQ(0U, queued_event_count());
EXPECT_EQ(WebInputEvent::TouchMove, acked_event().type);
EXPECT_EQ(2U, GetAndResetAckedEventCount());
// touch-move event, the touch-end event and the second touch-press event.
EXPECT_EQ(4U, queued_event_count());
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(WebInputEvent::TouchEnd, acked_event().type);
EXPECT_EQ(4U, GetAndResetAckedEventCount());
EXPECT_EQ(1U, queued_event_count());
// ACK the second press event as NO_CONSUMER too.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(WebInputEvent::TouchStart, acked_event().type);
EXPECT_EQ(1U, GetAndResetAckedEventCount());
// ACK the first press as CONSUMED. This should cause the first touch-move of
// the first touch-point to be dispatched.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(3U, queued_event_count());
// ACK the first move as CONSUMED.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(2U, queued_event_count());
// touch-move event (which contains both touch points). Although the second
// touch-point does not need to be sent to the renderer, the first touch-point
// did move, and so the coalesced touch-event will be sent to the renderer.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(1U, queued_event_count());
// ACK the coalesced move as NOT_CONSUMED.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(0U, queued_event_count());
MoveTouchPoints(0, 15, 15, 1, 25, 25);
EXPECT_EQ(0U, GetAndResetSentEventCount());
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(1U, queued_event_count());
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(0U, queued_event_count());
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(4U, queued_event_count());
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(2U, queued_event_count());
EXPECT_EQ(WebInputEvent::TouchMove, acked_event().type);
// ACK the press with NO_CONSUMED_EXISTS. This should release the queued
// touch-move events to the view.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(0U, queued_event_count());
EXPECT_EQ(WebInputEvent::TouchMove, acked_event().type);
// Receive an ACK for the press. This should cause the followup touch-move to
// be sent to the renderer.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, queued_event_count());
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
// Receive an ACK for the touch-move followup event. This should cause the
// subsequent touch move event be sent to the renderer.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, queued_event_count());
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
// TouchCancel (first inserting a TouchStart so the TouchCancel will be sent)
PressTouchPoint(1, 1);
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(0U, queued_event_count());
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
PressTouchPoint(80, 10);
EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, GetAndResetAckedEventCount());
MoveTouchPoint(0, 80, 20);
EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, GetAndResetAckedEventCount());
ReleaseTouchPoint(0);
EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, GetAndResetAckedEventCount());
}
// Queue a TouchStart.
PressTouchPoint(0, 1);
EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, GetAndResetAckedEventCount());
MoveTouchPoint(0, 20, 5);
WebGestureEvent followup_scroll;
followup_scroll.type = WebInputEvent::GestureScrollBegin;
SetFollowupEvent(followup_scroll);
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
EXPECT_EQ(2U, queued_event_count());
EXPECT_EQ(WebInputEvent::TouchStart, latest_event().type);
// Acking the TouchCancel will result in dispatch of the next TouchStart.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
// The synthetic TouchCancel should not reach client, only the TouchStart.
EXPECT_EQ(1U, GetAndResetAckedEventCount());
EXPECT_EQ(0U, GetAndResetSentEventCount());
// Touch events from a new gesture sequence should be forwarded normally.
PressTouchPoint(80, 10);
EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, GetAndResetAckedEventCount());
MoveTouchPoint(0, 80, 20);
EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, GetAndResetAckedEventCount());
ReleaseTouchPoint(0);
EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, GetAndResetAckedEventCount());
}
// Queue a TouchStart.
PressTouchPoint(0, 1);
EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
EXPECT_EQ(1U, GetAndResetAckedEventCount());
EXPECT_EQ(WebInputEvent::TouchStart, sent_event().type);
// Touch events from a new gesture sequence should be forwarded normally.
PressTouchPoint(80, 10);
EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, GetAndResetAckedEventCount());
}
EXPECT_TRUE(IsPendingAckTouchStart());
// Ack the touchstart (#1).
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, queued_event_count());
EXPECT_FALSE(IsPendingAckTouchStart());
EXPECT_FALSE(IsPendingAckTouchStart());
// Ack the touchmove (#2).
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, queued_event_count());
EXPECT_TRUE(IsPendingAckTouchStart());
EXPECT_TRUE(IsPendingAckTouchStart());
// Ack the touchstart for the second point (#3).
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, queued_event_count());
EXPECT_TRUE(IsPendingAckTouchStart());
// Ack the touchstart for the third point (#4).
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(0U, queued_event_count());
EXPECT_FALSE(IsPendingAckTouchStart());
}
// Sending a TouchStart will start the timeout.
PressTouchPoint(0, 1);
EXPECT_TRUE(IsTimeoutRunning());
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_FALSE(IsTimeoutRunning());
// A TouchMove should start the timeout.
MoveTouchPoint(0, 5, 5);
EXPECT_TRUE(IsTimeoutRunning());
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_FALSE(IsTimeoutRunning());
// A TouchEnd should not start the timeout.
ReleaseTouchPoint(0);
EXPECT_FALSE(IsTimeoutRunning());
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_FALSE(IsTimeoutRunning());
// A TouchCancel should not start the timeout.
PressTouchPoint(0, 1);
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
ASSERT_FALSE(IsTimeoutRunning());
CancelTouchPoint(0);
EXPECT_FALSE(IsTimeoutRunning());
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_FALSE(IsTimeoutRunning());
}
EXPECT_EQ(1U, GetAndResetAckedEventCount());
// Ack'ing the original event should trigger a cancel event.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_FALSE(IsTimeoutRunning());
EXPECT_EQ(0U, GetAndResetAckedEventCount());
EXPECT_EQ(1U, GetAndResetSentEventCount());
// The synthetic TouchCancel ack should not reach the client, but should
// resume touch forwarding.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(0U, GetAndResetAckedEventCount());
// Mark the event as consumed. This should prevent the timeout from
// being activated on subsequent TouchEvents in this gesture.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_FALSE(IsTimeoutRunning());
// A TouchMove should not start the timeout.
MoveTouchPoint(0, 5, 5);
EXPECT_FALSE(IsTimeoutRunning());
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
// A secondary TouchStart should not start the timeout.
PressTouchPoint(1, 0);
EXPECT_FALSE(IsTimeoutRunning());
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
// A TouchEnd should not start the timeout.
ReleaseTouchPoint(1);
EXPECT_FALSE(IsTimeoutRunning());
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
// A TouchCancel should not start the timeout.
CancelTouchPoint(0);
EXPECT_EQ(1U, GetAndResetAckedEventCount());
// Ack the original event, triggering a TouchCancel.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_FALSE(IsTimeoutRunning());
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(0U, GetAndResetAckedEventCount());
// Ack the cancel event. Normally, this would resume touch forwarding,
// but we're still within a scroll gesture so it remains disabled.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_FALSE(IsTimeoutRunning());
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(0U, GetAndResetAckedEventCount());
EXPECT_EQ(2U, GetAndResetAckedEventCount());
// Ack the original event, triggering a cancel.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(0U, GetAndResetAckedEventCount());
// Ack the cancel event, resuming touch forwarding.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(0U, GetAndResetAckedEventCount());
// Ack'ing the original event should not trigger a cancel event, as the
// TouchStart had no consumer. However, it should re-enable touch forwarding.
- SendTouchEventACK(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
EXPECT_FALSE(IsTimeoutRunning());
EXPECT_EQ(0U, GetAndResetAckedEventCount());
EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(0U, GetAndResetAckedEventCount());
}
+
+// Tests that TouchMove's are dropped if within the slop suppression region
+// for an unconsumed TouchStart
+TEST_F(TouchEventQueueTest, TouchMoveSuppressionWithinSlopRegion) {
+ const double kSlopLengthDips = 10.;
+ const double kHalfSlopLengthDips = kSlopLengthDips / 2;
+ SetUpForTouchMoveSlopTesting(kSlopLengthDips);
+
+ // Queue a TouchStart.
+ PressTouchPoint(0, 0);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ ASSERT_EQ(1U, GetAndResetSentEventCount());
+ ASSERT_EQ(1U, GetAndResetAckedEventCount());
+
+ // TouchMove's within the region should be suppressed.
+ MoveTouchPoint(0, 0, kHalfSlopLengthDips);
+ EXPECT_EQ(0U, queued_event_count());
+ EXPECT_EQ(0U, GetAndResetSentEventCount());
+ EXPECT_EQ(1U, GetAndResetAckedEventCount());
+ EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, acked_event_state());
+
+ MoveTouchPoint(0, kHalfSlopLengthDips, 0);
+ EXPECT_EQ(0U, queued_event_count());
+ EXPECT_EQ(0U, GetAndResetSentEventCount());
+ EXPECT_EQ(1U, GetAndResetAckedEventCount());
+ EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, acked_event_state());
+
+ MoveTouchPoint(0, -kHalfSlopLengthDips, 0);
+ EXPECT_EQ(0U, queued_event_count());
+ EXPECT_EQ(0U, GetAndResetSentEventCount());
+ EXPECT_EQ(1U, GetAndResetAckedEventCount());
+ EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, acked_event_state());
+
+ // As soon as a TouchMove exceeds the (Euclidean) distance, no more
+ // TouchMove's should be suppressed.
+ // TODO(jdduke): Remove ceil with adoption of floating point touch coords,
+ // crbug/336807.
+ const double kFortyFiveDegreeSlopLengthXY =
+ std::ceil(kSlopLengthDips * std::sqrt(2.) / 2.);
+ MoveTouchPoint(0, kFortyFiveDegreeSlopLengthXY + .1,
+ kFortyFiveDegreeSlopLengthXY + .1);
+ EXPECT_EQ(1U, queued_event_count());
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
+ EXPECT_EQ(0U, GetAndResetAckedEventCount());
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(1U, GetAndResetAckedEventCount());
+
+ // Even TouchMove's within the original slop region should now be forwarded.
+ MoveTouchPoint(0, 0, 0);
+ EXPECT_EQ(1U, queued_event_count());
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
+ EXPECT_EQ(0U, GetAndResetAckedEventCount());
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(1U, GetAndResetAckedEventCount());
+
+ // A new touch sequence should reset suppression.
+ ReleaseTouchPoint(0);
+ PressTouchPoint(0, 0);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ ASSERT_EQ(2U, GetAndResetSentEventCount());
+ ASSERT_EQ(2U, GetAndResetAckedEventCount());
+ ASSERT_EQ(0U, queued_event_count());
+
+ // The slop region is boundary-exclusive.
+ // TODO(jdduke): Change to inclusive upon resolving crbug.com/336807.
+ MoveTouchPoint(0, kSlopLengthDips - 1., 0);
+ EXPECT_EQ(0U, queued_event_count());
+ EXPECT_EQ(0U, GetAndResetSentEventCount());
+ EXPECT_EQ(1U, GetAndResetAckedEventCount());
+
+ MoveTouchPoint(0, kSlopLengthDips, 0);
+ EXPECT_EQ(1U, queued_event_count());
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
+ EXPECT_EQ(0U, GetAndResetAckedEventCount());
+}
+
+// Tests that TouchMove's are not dropped within the slop suppression region if
+// the touchstart was consumed.
+TEST_F(TouchEventQueueTest, NoTouchMoveSuppressionAfterTouchConsumed) {
+ const double kSlopLengthDips = 10.;
+ const double kHalfSlopLengthDips = kSlopLengthDips / 2;
+ SetUpForTouchMoveSlopTesting(kSlopLengthDips);
+
+ // Queue a TouchStart.
+ PressTouchPoint(0, 0);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
+ ASSERT_EQ(1U, GetAndResetSentEventCount());
+ ASSERT_EQ(1U, GetAndResetAckedEventCount());
+
+ // TouchMove's within the region should not be suppressed, as a touch was
+ // consumed.
+ MoveTouchPoint(0, 0, kHalfSlopLengthDips);
+ EXPECT_EQ(1U, queued_event_count());
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
+ EXPECT_EQ(0U, GetAndResetAckedEventCount());
+}
+
+// Tests that TouchMove's are not dropped due to integral truncation of
+// WebTouchPoint coordinates after DPI scaling.
+TEST_F(TouchEventQueueTest, TouchMoveSuppressionWithDIPScaling) {
+ const float kSlopLengthPixels = 7.f;
+ const float kDPIScale = 3.f;
+ SetUpForTouchMoveSlopTesting(kSlopLengthPixels / kDPIScale);
+
+ // Queue a TouchStart.
+ PressTouchPoint(0, 0);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ ASSERT_EQ(1U, GetAndResetSentEventCount());
+ ASSERT_EQ(1U, GetAndResetAckedEventCount());
+
+ // TouchMove's along the slop boundary should not be suppresed.
+ // TODO(jdduke): These should be suppressed, crbug.com/336807.
+ MoveTouchPoint(0, 0, kSlopLengthPixels / kDPIScale);
+ EXPECT_EQ(1U, queued_event_count());
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
+ EXPECT_EQ(0U, GetAndResetAckedEventCount());
+
+ // Reset the touch sequence.
+ ReleaseTouchPoint(0);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ GetAndResetSentEventCount();
+ GetAndResetAckedEventCount();
+
+ // Queue a TouchStart.
+ PressTouchPoint(0, 0);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ ASSERT_EQ(1U, GetAndResetSentEventCount());
+ ASSERT_EQ(1U, GetAndResetAckedEventCount());
+
+ // TouchMove's outside the region should not be suppressed.
+ const float kPixelCoordOutsideSlopRegion = kSlopLengthPixels + 1.f;
+ MoveTouchPoint(0, 0, kPixelCoordOutsideSlopRegion / kDPIScale);
+ EXPECT_EQ(1U, queued_event_count());
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
+ EXPECT_EQ(0U, GetAndResetAckedEventCount());
+}
+
+
+// Tests that TouchMove's are not dropped if a secondary pointer is present
+// during any movement.
+TEST_F(TouchEventQueueTest, NoTouchMoveSuppressionAfterMultiTouch) {
+ const double kSlopLengthDips = 10.;
+ const double kHalfSlopLengthDips = kSlopLengthDips / 2;
+ const double kDoubleSlopLengthDips = 10.;
+ SetUpForTouchMoveSlopTesting(kSlopLengthDips);
+
+ // Queue a TouchStart.
+ PressTouchPoint(0, 0);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ ASSERT_EQ(1U, GetAndResetSentEventCount());
+ ASSERT_EQ(1U, GetAndResetAckedEventCount());
+
+ // TouchMove's within the region should be suppressed.
+ MoveTouchPoint(0, 0, kHalfSlopLengthDips);
+ EXPECT_EQ(0U, queued_event_count());
+ EXPECT_EQ(0U, GetAndResetSentEventCount());
+ EXPECT_EQ(1U, GetAndResetAckedEventCount());
+
+ // Simulate a secondary pointer press.
+ PressTouchPoint(kDoubleSlopLengthDips, 0);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
+ EXPECT_EQ(1U, GetAndResetAckedEventCount());
+
+ // TouchMove with a secondary pointer should not be suppressed.
+ MoveTouchPoint(1, kDoubleSlopLengthDips, 0);
+ EXPECT_EQ(1U, queued_event_count());
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(1U, GetAndResetAckedEventCount());
+
+ // Release the secondary pointer.
+ ReleaseTouchPoint(0);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
+ EXPECT_EQ(1U, GetAndResetAckedEventCount());
+
+ // TouchMove's should not should be suppressed, even with the original
+ // unmoved pointer.
+ MoveTouchPoint(0, 0, 0);
+ EXPECT_EQ(1U, queued_event_count());
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
+ EXPECT_EQ(0U, GetAndResetAckedEventCount());
+}
+
+TEST_F(TouchEventQueueTest, SyncTouchMoveDoesntCancelTouchOnScroll) {
+ SetTouchScrollingMode(TouchEventQueue::TOUCH_SCROLLING_MODE_SYNC_TOUCHMOVE);
+ // Queue a TouchStart.
+ PressTouchPoint(0, 1);
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(1U, GetAndResetAckedEventCount());
+
+ MoveTouchPoint(0, 20, 5);
+ EXPECT_EQ(1U, queued_event_count());
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
+
+ // GestureScrollBegin doesn't insert a synthetic TouchCancel.
+ WebGestureEvent followup_scroll;
+ followup_scroll.type = WebInputEvent::GestureScrollBegin;
+ SetFollowupEvent(followup_scroll);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(0U, GetAndResetSentEventCount());
+ EXPECT_EQ(1U, GetAndResetAckedEventCount());
+ EXPECT_EQ(0U, queued_event_count());
+}
+
+TEST_F(TouchEventQueueTest, TouchAbsorption) {
+ SetTouchScrollingMode(
+ TouchEventQueue::TOUCH_SCROLLING_MODE_ABSORB_TOUCHMOVE);
+ // Queue a TouchStart.
+ PressTouchPoint(0, 1);
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(1U, GetAndResetAckedEventCount());
+
+ for (int i = 0; i < 3; ++i) {
+ SendGestureEventAck(WebInputEvent::GestureScrollUpdate,
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+
+ MoveTouchPoint(0, 20, 5);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(0U, queued_event_count());
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
+
+ // Consuming a scroll event prevents the next touch moves from being
+ // dispatched.
+ SendGestureEventAck(WebInputEvent::GestureScrollUpdate,
+ INPUT_EVENT_ACK_STATE_CONSUMED);
+ MoveTouchPoint(0, 20, 5);
+ SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(0U, queued_event_count());
+ EXPECT_EQ(0U, GetAndResetSentEventCount());
+ }
+}
+
} // namespace content