Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / input / touch_event_queue_unittest.cc
index 1b887ec..7d2c086 100644 (file)
@@ -28,14 +28,20 @@ class TouchEventQueueTest : public testing::Test,
   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 {
@@ -48,7 +54,7 @@ class TouchEventQueueTest : public testing::Test,
     ++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(
@@ -77,6 +83,11 @@ class TouchEventQueueTest : public testing::Test,
     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()));
   }
@@ -88,10 +99,18 @@ class TouchEventQueueTest : public testing::Test,
         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));
   }
@@ -180,6 +199,12 @@ class TouchEventQueueTest : public testing::Test,
     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_;
@@ -190,6 +215,8 @@ class TouchEventQueueTest : public testing::Test,
   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_;
 };
 
@@ -206,14 +233,14 @@ TEST_F(TouchEventQueueTest, Basic) {
   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());
@@ -244,7 +271,7 @@ TEST_F(TouchEventQueueTest, QueueFlushedWhenHandlersRemoved) {
 
   // 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());
@@ -305,7 +332,7 @@ TEST_F(TouchEventQueueTest, ActiveSequenceDroppedWhenHandlersRemoved) {
   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());
 
@@ -347,7 +374,7 @@ TEST_F(TouchEventQueueTest, Coalesce) {
   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());
@@ -355,14 +382,14 @@ TEST_F(TouchEventQueueTest, Coalesce) {
   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());
@@ -384,7 +411,7 @@ TEST_F(TouchEventQueueTest, SentTouchEventDoesNotCoalesce) {
   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());
 
@@ -446,7 +473,7 @@ TEST_F(TouchEventQueueTest, AckAfterQueueFlushed) {
 
   // 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());
 
@@ -455,7 +482,7 @@ TEST_F(TouchEventQueueTest, AckAfterQueueFlushed) {
   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());
 }
@@ -477,7 +504,7 @@ TEST_F(TouchEventQueueTest, NoConsumer) {
 
   // 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());
@@ -506,14 +533,14 @@ TEST_F(TouchEventQueueTest, NoConsumer) {
   // 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());
@@ -553,12 +580,12 @@ TEST_F(TouchEventQueueTest, ConsumerIgnoreMultiFinger) {
 
   // 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());
 
@@ -566,12 +593,12 @@ TEST_F(TouchEventQueueTest, ConsumerIgnoreMultiFinger) {
   // 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());
 
@@ -592,11 +619,11 @@ TEST_F(TouchEventQueueTest, ConsumerIgnoreMultiFinger) {
   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());
 
@@ -618,14 +645,14 @@ TEST_F(TouchEventQueueTest, ConsumerIgnoreMultiFinger) {
   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);
@@ -655,7 +682,7 @@ TEST_F(TouchEventQueueTest, AckWithFollowupEvents) {
 
   // 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());
@@ -668,7 +695,7 @@ TEST_F(TouchEventQueueTest, AckWithFollowupEvents) {
 
   // 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());
@@ -699,7 +726,7 @@ TEST_F(TouchEventQueueTest, SynchronousAcks) {
 
   // 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());
@@ -762,17 +789,17 @@ TEST_F(TouchEventQueueTest, NoTouchBasic) {
 
   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());
 }
 
@@ -781,7 +808,7 @@ TEST_F(TouchEventQueueTest, NoTouchOnScroll) {
   // 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);
@@ -798,7 +825,7 @@ TEST_F(TouchEventQueueTest, NoTouchOnScroll) {
   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());
@@ -806,7 +833,7 @@ TEST_F(TouchEventQueueTest, NoTouchOnScroll) {
   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());
@@ -835,17 +862,17 @@ TEST_F(TouchEventQueueTest, NoTouchOnScroll) {
   // 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());
 }
 
@@ -855,7 +882,7 @@ TEST_F(TouchEventQueueTest, NoTouchCancelOnScrollIfNoConsumer) {
   // 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);
 
@@ -889,7 +916,7 @@ TEST_F(TouchEventQueueTest, NoTouchCancelOnScrollIfNoConsumer) {
   // 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());
 }
 
@@ -909,7 +936,7 @@ TEST_F(TouchEventQueueTest, PendingStart) {
   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());
 
@@ -919,7 +946,7 @@ TEST_F(TouchEventQueueTest, PendingStart) {
   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());
 
@@ -929,12 +956,12 @@ TEST_F(TouchEventQueueTest, PendingStart) {
   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());
 }
@@ -946,28 +973,28 @@ TEST_F(TouchEventQueueTest, TouchTimeoutTypes) {
   // 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());
 }
 
@@ -1000,7 +1027,7 @@ TEST_F(TouchEventQueueTest, TouchTimeoutBasic) {
   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());
@@ -1016,7 +1043,7 @@ TEST_F(TouchEventQueueTest, TouchTimeoutBasic) {
 
   // 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());
 
@@ -1037,23 +1064,23 @@ TEST_F(TouchEventQueueTest, NoTouchTimeoutIfRendererIsConsumingGesture) {
 
   // 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);
@@ -1113,14 +1140,14 @@ TEST_F(TouchEventQueueTest, TouchTimeoutWithFollowupGesture) {
   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());
@@ -1189,12 +1216,12 @@ TEST_F(TouchEventQueueTest, TouchTimeoutWithFollowupGestureAndDelayedAck) {
   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());
 
@@ -1235,7 +1262,7 @@ TEST_F(TouchEventQueueTest, NoCancelOnTouchTimeoutWithoutConsumer) {
 
   // 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());
@@ -1245,4 +1272,242 @@ TEST_F(TouchEventQueueTest, NoCancelOnTouchTimeoutWithoutConsumer) {
   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