Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / content / public / android / javatests / src / org / chromium / content / browser / ContentViewGestureHandlerTest.java
index e18171b..2c46573 100644 (file)
@@ -10,6 +10,7 @@ import android.os.SystemClock;
 import android.test.InstrumentationTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
+import android.view.InputDevice;
 import android.view.MotionEvent;
 import android.view.MotionEvent.PointerCoords;
 import android.view.MotionEvent.PointerProperties;
@@ -18,7 +19,6 @@ import android.view.ViewConfiguration;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.ScalableTimeout;
 import org.chromium.content.browser.ContentViewGestureHandler.MotionEventDelegate;
-import org.chromium.content.browser.third_party.GestureDetector;
 
 import java.util.ArrayList;
 import java.util.concurrent.CountDownLatch;
@@ -32,147 +32,82 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
     private static final int FAKE_COORD_Y = 24;
 
     private static final String TAG = "ContentViewGestureHandler";
-    private MockListener mMockListener;
     private MockMotionEventDelegate mMockMotionEventDelegate;
-    private MockGestureDetector mMockGestureDetector;
-    private MockZoomManager mMockZoomManager;
     private ContentViewGestureHandler mGestureHandler;
-    private LongPressDetector mLongPressDetector;
-
-    static class MockListener extends GestureDetector.SimpleOnGestureListener {
-        MotionEvent mLastLongPress;
-        MotionEvent mLastShowPress;
-        MotionEvent mLastSingleTap;
-        MotionEvent mLastFling1;
-        CountDownLatch mLongPressCalled;
-        CountDownLatch mShowPressCalled;
-
-        public MockListener() {
-            mLongPressCalled = new CountDownLatch(1);
-            mShowPressCalled = new CountDownLatch(1);
-        }
-
-        @Override
-        public void onLongPress(MotionEvent e) {
-            mLastLongPress = MotionEvent.obtain(e);
-            mLongPressCalled.countDown();
-        }
-
-        @Override
-        public void onShowPress(MotionEvent e) {
-            mLastShowPress = MotionEvent.obtain(e);
-            mShowPressCalled.countDown();
-            Log.e("Overscroll", "OnShowPress");
-        }
-
-        @Override
-        public boolean onSingleTapConfirmed(MotionEvent e) {
-            mLastSingleTap = e;
-            return true;
-        }
 
-        @Override
-        public boolean onSingleTapUp(MotionEvent e) {
-            mLastSingleTap = e;
-            return true;
-        }
-
-        @Override
-        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
-            return true;
-        }
-
-        @Override
-        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
-            mLastFling1 = e1;
-            return true;
-        }
-    }
+    static class MockMotionEventDelegate implements MotionEventDelegate {
+        static class GestureEvent {
+            public final int mType;
+            public final long mTimeMs;
+            public final int mX;
+            public final int mY;
+            public final Bundle mExtraParams;
 
-    static class MockGestureDetector extends GestureDetector {
-        MotionEvent mLastEvent;
-        public MockGestureDetector(Context context, OnGestureListener listener) {
-            super(context, listener);
-        }
+            public GestureEvent(int type, long timeMs, int x, int y, Bundle extraParams) {
+                mType = type;
+                mTimeMs = timeMs;
+                mX = x;
+                mY = y;
+                mExtraParams = extraParams;
+            }
 
-        @Override
-        public boolean onTouchEvent(MotionEvent ev) {
-            mLastEvent = MotionEvent.obtain(ev);
-            return super.onTouchEvent(ev);
-        }
-    }
+            public int getType() {
+                return mType;
+            }
 
-    static class MockMotionEventDelegate implements MotionEventDelegate {
-        private ContentViewGestureHandler mSynchronousConfirmTarget;
-        private int mSynchronousConfirmAckResult;
+            public long getTimeMs() {
+                return mTimeMs;
+            }
 
-        public int mLastTouchAction;
-        public int mLastGestureType;
-        public int mTotalSentGestureCount;
+            public int getX() {
+                return mX;
+            }
 
-        @Override
-        public boolean sendTouchEvent(long timeMs, int action, TouchPoint[] pts) {
-            mLastTouchAction = action;
-            if (mSynchronousConfirmTarget != null) {
-                mSynchronousConfirmTarget.confirmTouchEvent(mSynchronousConfirmAckResult);
+            public int getY() {
+                return mY;
             }
-            return true;
-        }
 
-        @Override
-        public boolean sendGesture(int type, long timeMs, int x, int y, Bundle extraParams) {
-            Log.i(TAG,"Gesture event received with type id " + type);
-            mLastGestureType = type;
-            mTotalSentGestureCount++;
-            return true;
+            public Bundle getExtraParams() {
+                return mExtraParams;
+            }
         }
+        GestureEvent mMostRecentGestureEvent;
+        GestureEvent mActiveScrollStartEvent;
+        int mMostRecentMotionEventAction = -1;
+        final ArrayList<Integer> mGestureTypeList = new ArrayList<Integer>();
+        final ArrayList<Long> mGestureTimeList = new ArrayList<Long>();
 
-        @Override
-        public void sendSingleTapUMA(int type) {
-            // Not implemented.
-        }
+        final CountDownLatch mLongPressCalled = new CountDownLatch(1);
+        final CountDownLatch mShowPressCalled = new CountDownLatch(1);
 
         @Override
-        public void sendActionAfterDoubleTapUMA(int type,
-                boolean clickDelayEnabled) {
-            // Not implemented.
+        public void onTouchEventHandlingBegin(MotionEvent event) {
+            mMostRecentMotionEventAction = event.getActionMasked();
         }
 
         @Override
-        public void invokeZoomPicker() {
-            // Not implemented.
-        }
-
-        public void enableSynchronousConfirmTouchEvent(
-                ContentViewGestureHandler handler, int ackResult) {
-            mSynchronousConfirmTarget = handler;
-            mSynchronousConfirmAckResult = ackResult;
-        }
-
-        public void disableSynchronousConfirmTouchEvent() {
-            mSynchronousConfirmTarget = null;
-        }
-    }
-
-    static class MockZoomManager extends ZoomManager {
-        private ContentViewGestureHandler mHandlerForMoveEvents;
-
-        MockZoomManager(Context context, ContentViewCore contentViewCore) {
-            super(context, contentViewCore);
-        }
-
-        public void pinchOnMoveEvents(ContentViewGestureHandler handler) {
-            mHandlerForMoveEvents = handler;
+        public void onTouchEventHandlingEnd() {
         }
 
         @Override
-        public boolean processTouchEvent(MotionEvent event) {
-            if (event.getActionMasked() == MotionEvent.ACTION_MOVE
-                    && mHandlerForMoveEvents != null) {
-                mHandlerForMoveEvents.pinchBy(event.getEventTime(), 1, 1, 1.1f);
-                return true;
+        public boolean onGestureEventCreated(
+                int type, long timeMs, int x, int y, Bundle extraParams) {
+            Log.i(TAG, "Gesture event received with type id " + type);
+            mMostRecentGestureEvent = new GestureEvent(type, timeMs, x, y, extraParams);
+            mGestureTypeList.add(mMostRecentGestureEvent.mType);
+            mGestureTimeList.add(timeMs);
+            if (type == GestureEventType.SCROLL_START) {
+                mActiveScrollStartEvent = mMostRecentGestureEvent;
+            } else if (type == GestureEventType.SCROLL_END
+                           || type == GestureEventType.FLING_CANCEL) {
+                mActiveScrollStartEvent = null;
+            } else if (type == GestureEventType.LONG_PRESS) {
+                mLongPressCalled.countDown();
+            } else if (type == GestureEventType.SHOW_PRESS) {
+                mShowPressCalled.countDown();
             }
-            return false;
+
+            return true;
         }
     }
 
@@ -182,19 +117,10 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
 
     @Override
     public void setUp() {
-        mMockListener = new MockListener();
-        mMockGestureDetector = new MockGestureDetector(
-                getInstrumentation().getTargetContext(), mMockListener);
         mMockMotionEventDelegate = new MockMotionEventDelegate();
-        mMockZoomManager = new MockZoomManager(getInstrumentation().getTargetContext(), null);
         mGestureHandler = new ContentViewGestureHandler(
-                getInstrumentation().getTargetContext(), mMockMotionEventDelegate,
-                mMockZoomManager);
-        mLongPressDetector = new LongPressDetector(
-                getInstrumentation().getTargetContext(), mGestureHandler);
-        mGestureHandler.setTestDependencies(
-                mLongPressDetector, mMockGestureDetector, mMockListener);
-        TouchPoint.initializeConstantsForTesting();
+                getInstrumentation().getTargetContext(), mMockMotionEventDelegate);
+        mGestureHandler.updateMultiTouchSupport(false);
     }
 
     /**
@@ -208,302 +134,17 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         final long downTime = SystemClock.uptimeMillis();
         final long eventTime = SystemClock.uptimeMillis();
 
-        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
-
-        assertFalse(mGestureHandler.onTouchEvent(event));
-        assertTrue("Should have a pending gesture", mMockGestureDetector.mLastEvent != null);
-        assertTrue("Should have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
-
-        event = motionEvent(MotionEvent.ACTION_UP, downTime, eventTime + 10);
-        mLongPressDetector.cancelLongPressIfNeeded(event);
-        assertTrue("Should not have a pending LONG_PRESS", !mLongPressDetector.hasPendingMessage());
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        // Synchronous, no need to wait.
-        assertTrue("Should have a single tap", mMockListener.mLastSingleTap != null);
-    }
-
-    /**
-     * Verify that when a touch event handler is registered the touch events are queued
-     * and sent in order.
-     * @throws Exception
-     */
-    @SmallTest
-    @Feature({"Gestures"})
-    public void testFlingOnTouchHandler() throws Exception {
-        final long downTime = SystemClock.uptimeMillis();
-        final long eventTime = SystemClock.uptimeMillis();
-
-        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
-
-        mGestureHandler.hasTouchEventHandlers(true);
-
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertTrue("Should not have a pending gesture", mMockGestureDetector.mLastEvent == null);
-        assertFalse("Should not have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 5, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X * 5, FAKE_COORD_Y * 5, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X * 10, FAKE_COORD_Y * 10, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals("We should have coalesced move events into one"
-                , 2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 15, MotionEvent.ACTION_UP,
-                FAKE_COORD_X * 10, FAKE_COORD_Y * 10, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(3, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-        assertEquals(2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertEquals(MotionEvent.ACTION_MOVE,
-                mGestureHandler.peekFirstInPendingMotionEventsForTesting().getActionMasked());
-        assertFalse("Pending LONG_PRESS should have been canceled",
-                mLongPressDetector.hasPendingMessage());
-
-        mGestureHandler.confirmTouchEvent(ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_CONSUMED);
-        assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertEquals(MotionEvent.ACTION_UP,
-                mGestureHandler.peekFirstInPendingMotionEventsForTesting().getActionMasked());
-
-        mGestureHandler.confirmTouchEvent(ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_CONSUMED);
-        assertEquals(0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        // Synchronous, no need to wait.
-        assertTrue("Should not have a fling", mMockListener.mLastFling1 == null);
-        assertTrue("Should not have a long press", mMockListener.mLastLongPress == null);
-    }
-
-    /**
-     * Verify that after a touch event handlers starts handling a gesture, even though some event
-     * in the middle of the gesture returns with NOT_CONSUMED, we don't send that to the gesture
-     * detector to avoid falling to a faulty state.
-     * @throws Exception
-     */
-    @SmallTest
-    @Feature({"Gestures"})
-    public void testFlingOnTouchHandlerWithOneEventNotConsumed() throws Exception {
-        final long downTime = SystemClock.uptimeMillis();
-        final long eventTime = SystemClock.uptimeMillis();
-
-        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
-
-        mGestureHandler.hasTouchEventHandlers(true);
-
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertTrue("Should not have a pending gesture", mMockGestureDetector.mLastEvent == null);
-        assertFalse("Should not have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 5, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X * 5, FAKE_COORD_Y * 5, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X * 10, FAKE_COORD_Y * 10, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals("We should have coalesced move events into one"
-                , 2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 15, MotionEvent.ACTION_UP,
-                FAKE_COORD_X * 10, FAKE_COORD_Y * 10, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(3, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_CONSUMED);
-        assertEquals(2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertEquals(MotionEvent.ACTION_MOVE,
-                mGestureHandler.peekFirstInPendingMotionEventsForTesting().getActionMasked());
-
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-        assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertEquals(MotionEvent.ACTION_UP,
-                mGestureHandler.peekFirstInPendingMotionEventsForTesting().getActionMasked());
-        assertTrue("Even though the last event was not consumed by JavaScript," +
-                "it shouldn't have been sent to the Gesture Detector",
-                        mMockGestureDetector.mLastEvent == null);
-
-        mGestureHandler.confirmTouchEvent(ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_CONSUMED);
-        assertEquals(0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        // Synchronous, no need to wait.
-        assertTrue("Should not have a fling", mMockListener.mLastFling1 == null);
-        assertTrue("Should not have a long press", mMockListener.mLastLongPress == null);
-    }
-
-    /**
-     * Verify that when a registered touch event handler return NO_CONSUMER_EXISTS for down event
-     * all queue is drained until next down.
-     * @throws Exception
-     */
-    @SmallTest
-    @Feature({"Gestures"})
-    public void testDrainWithFlingAndClickOutofTouchHandler() throws Exception {
-        final long downTime = SystemClock.uptimeMillis();
-        final long eventTime = SystemClock.uptimeMillis();
-
-        mGestureHandler = new ContentViewGestureHandler(
-                getInstrumentation().getTargetContext(), new MockMotionEventDelegate(),
-                mMockZoomManager);
-        mLongPressDetector = new LongPressDetector(
-                getInstrumentation().getTargetContext(), mGestureHandler);
-
-        mGestureHandler.hasTouchEventHandlers(true);
-
-        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertFalse("Should not have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 5, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X * 5, FAKE_COORD_Y * 5, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X * 10, FAKE_COORD_Y * 10, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 15, MotionEvent.ACTION_UP,
-                FAKE_COORD_X * 10, FAKE_COORD_Y * 10, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(3, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        event = motionEvent(MotionEvent.ACTION_DOWN, eventTime + 20, eventTime + 20);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(4, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 20, MotionEvent.ACTION_UP,
-                FAKE_COORD_X, FAKE_COORD_Y, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(5, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
-        assertEquals("The queue should have been drained until first down since no consumer exists",
-                2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertEquals(MotionEvent.ACTION_DOWN,
-                mGestureHandler.peekFirstInPendingMotionEventsForTesting().getActionMasked());
-
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
-        assertEquals("The queue should have been drained",
-                0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-    }
-
-    /**
-     * Verify that when a touch event handler is registered the touch events stop getting queued
-     * after we received INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS.
-     * @throws Exception
-     */
-    @SmallTest
-    @Feature({"Gestures"})
-    public void testFlingOutOfTouchHandler() throws Exception {
-        final long downTime = SystemClock.uptimeMillis();
-        final long eventTime = SystemClock.uptimeMillis();
-
-        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
-
-        mGestureHandler.hasTouchEventHandlers(true);
-
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertTrue("Should not have a pending gesture", mMockGestureDetector.mLastEvent == null);
-        assertFalse("Should not have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
-
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
-        assertEquals(0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertEquals("The down touch event should have been sent to the Gesture Detector",
-                event.getEventTime(), mMockGestureDetector.mLastEvent.getEventTime());
-        assertEquals("The down touch event should have been sent to the Gesture Detector",
-                MotionEvent.ACTION_DOWN, mMockGestureDetector.mLastEvent.getActionMasked());
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 5, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X * 5, FAKE_COORD_Y * 5, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertEquals("Motion events should be going to the Gesture Detector directly",
-                event.getEventTime(), mMockGestureDetector.mLastEvent.getEventTime());
-        assertEquals("Motion events should be going to the Gesture Detector directly",
-                MotionEvent.ACTION_MOVE, mMockGestureDetector.mLastEvent.getActionMasked());
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 10, MotionEvent.ACTION_UP,
-                FAKE_COORD_X * 5, FAKE_COORD_Y * 5, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertEquals("Motion events should be going to the Gesture Detector directly",
-                event.getEventTime(), mMockGestureDetector.mLastEvent.getEventTime());
-        assertEquals("Motion events should be going to the Gesture Detector directly",
-                MotionEvent.ACTION_UP, mMockGestureDetector.mLastEvent.getActionMasked());
-
-        // Synchronous, no need to wait.
-        assertTrue("Should have a fling", mMockListener.mLastFling1 != null);
-        assertTrue("Should not have a long press", mMockListener.mLastLongPress == null);
-    }
-
-    /**
-     * Verifies that a single tap doesn't cause a long press event to be sent.
-     * @throws Exception
-     */
-    @SmallTest
-    @Feature({"Gestures"})
-    public void testNoLongPressIsSentForSingleTapOutOfTouchHandler() throws Exception {
-        final long downTime = SystemClock.uptimeMillis();
-        final long eventTime = SystemClock.uptimeMillis();
+        mGestureHandler.updateDoubleTapSupport(false);
 
         MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
-
-        mGestureHandler.hasTouchEventHandlers(true);
-
         assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertTrue("Should not have a pending gesture", mMockGestureDetector.mLastEvent == null);
-        assertFalse("Should not have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
+        assertEquals(GestureEventType.TAP_DOWN,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
 
-        event = motionEvent(MotionEvent.ACTION_UP, downTime, eventTime + 5);
+        event = motionEvent(MotionEvent.ACTION_UP, downTime, eventTime + 10);
         assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-
-        assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertEquals("The down touch event should have been sent to the Gesture Detector",
-                event.getDownTime(), mMockGestureDetector.mLastEvent.getEventTime());
-        assertEquals("The next event should be ACTION_UP",
-                MotionEvent.ACTION_UP,
-                mGestureHandler.peekFirstInPendingMotionEventsForTesting().getActionMasked());
-
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-
-        assertEquals(0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertEquals("The up touch event should have been sent to the Gesture Detector",
-                event.getEventTime(), mMockGestureDetector.mLastEvent.getEventTime());
-
-        assertFalse("Should not have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
+        assertEquals(GestureEventType.SINGLE_TAP_CONFIRMED,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
     }
 
     /**
@@ -518,25 +159,23 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
 
         MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
 
-        assertFalse(mGestureHandler.onTouchEvent(event));
-        assertTrue("Should have a pending gesture", mMockGestureDetector.mLastEvent != null);
-        assertTrue("Should have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
+        assertTrue(mGestureHandler.onTouchEvent(event));
+        assertEquals(GestureEventType.TAP_DOWN,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
 
         event = MotionEvent.obtain(
                 downTime, eventTime + 5, MotionEvent.ACTION_MOVE,
                 FAKE_COORD_X * 10, FAKE_COORD_Y * 10, 0);
-        mLongPressDetector.cancelLongPressIfNeeded(event);
-        assertTrue("Should not have a pending LONG_PRESS", !mLongPressDetector.hasPendingMessage());
         assertTrue(mGestureHandler.onTouchEvent(event));
 
         event = MotionEvent.obtain(
                 downTime, eventTime + 10, MotionEvent.ACTION_UP,
                 FAKE_COORD_X * 10, FAKE_COORD_Y * 10, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
-
-        // Synchronous, no need to wait.
-        assertTrue("Should have a fling", mMockListener.mLastFling1 != null);
-        assertTrue("Should not have a long press", mMockListener.mLastLongPress == null);
+        assertEquals(GestureEventType.FLING_START,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
+        assertFalse(mMockMotionEventDelegate.mGestureTypeList.contains(
+                GestureEventType.LONG_PRESS));
     }
 
     /**
@@ -571,11 +210,6 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         final int scrollToX = FAKE_COORD_X + 100;
         final int scrollToY = FAKE_COORD_Y + 100;
 
-        GestureRecordingMotionEventDelegate mockDelegate =
-                new GestureRecordingMotionEventDelegate();
-        mGestureHandler = new ContentViewGestureHandler(
-                getInstrumentation().getTargetContext(), mockDelegate, mMockZoomManager);
-
         MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
 
         assertTrue(mGestureHandler.onTouchEvent(event));
@@ -585,31 +219,31 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertTrue(mGestureHandler.isNativeScrolling());
         assertTrue("A scrollStart event should have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_SCROLL_START));
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.SCROLL_START));
         assertEquals("We should have started scrolling",
-                ContentViewGestureHandler.GESTURE_SCROLL_BY,
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.SCROLL_BY,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertEquals("Only tapDown, tapCancel, scrollBegin and scrollBy should have been sent",
-                4, mockDelegate.mGestureTypeList.size());
+                4, mMockMotionEventDelegate.mGestureTypeList.size());
         assertEquals("scrollBegin should be sent before scrollBy",
-                ContentViewGestureHandler.GESTURE_SCROLL_START,
-                (int) mockDelegate.mGestureTypeList.get(2));
+                GestureEventType.SCROLL_START,
+                (int) mMockMotionEventDelegate.mGestureTypeList.get(2));
         assertEquals("scrollBegin should have the time of the ACTION_MOVE",
-                eventTime + 1000, (long) mockDelegate.mGestureTimeList.get(2));
+                eventTime + 1000, (long) mMockMotionEventDelegate.mGestureTimeList.get(2));
 
         event = MotionEvent.obtain(
                 downTime, eventTime + 1000, endActionType, scrollToX, scrollToY, 0);
         mGestureHandler.onTouchEvent(event);
         assertFalse(mGestureHandler.isNativeScrolling());
         assertTrue("A scrollEnd event should have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_SCROLL_END));
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.SCROLL_END));
         assertEquals("We should have stopped scrolling",
-                ContentViewGestureHandler.GESTURE_SCROLL_END,
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.SCROLL_END,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertEquals("Only tapDown, scrollBegin and scrollBy and scrollEnd should have been sent",
-                5, mockDelegate.mGestureTypeList.size());
+                5, mMockMotionEventDelegate.mGestureTypeList.size());
     }
 
     /**
@@ -625,11 +259,6 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         final long downTime = SystemClock.uptimeMillis();
         final long eventTime = SystemClock.uptimeMillis();
 
-        GestureRecordingMotionEventDelegate mockDelegate =
-                new GestureRecordingMotionEventDelegate();
-        mGestureHandler = new ContentViewGestureHandler(
-                getInstrumentation().getTargetContext(), mockDelegate, mMockZoomManager);
-
         MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
 
         assertTrue(mGestureHandler.onTouchEvent(event));
@@ -640,18 +269,18 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertTrue(mGestureHandler.isNativeScrolling());
         assertTrue("A scrollStart event should have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_SCROLL_START));
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.SCROLL_START));
         assertEquals("We should have started scrolling",
-                ContentViewGestureHandler.GESTURE_SCROLL_BY,
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.SCROLL_BY,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertEquals("Only tapDown, tapCancel, scrollBegin and scrollBy should have been sent",
-                4, mockDelegate.mGestureTypeList.size());
+                4, mMockMotionEventDelegate.mGestureTypeList.size());
         assertEquals("scrollBegin should be sent before scrollBy",
-                ContentViewGestureHandler.GESTURE_SCROLL_START,
-                (int) mockDelegate.mGestureTypeList.get(2));
-        GestureRecordingMotionEventDelegate.GestureEvent startEvent =
-                mockDelegate.getActiveScrollStartEvent();
+                GestureEventType.SCROLL_START,
+                (int) mMockMotionEventDelegate.mGestureTypeList.get(2));
+        MockMotionEventDelegate.GestureEvent startEvent =
+                mMockMotionEventDelegate.mActiveScrollStartEvent;
         assertNotNull(startEvent);
         assertEquals("scrollBegin should have the time of the ACTION_MOVE",
                 eventTime + 10, (long) startEvent.getTimeMs());
@@ -668,23 +297,15 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertFalse(mGestureHandler.isNativeScrolling());
         assertEquals("We should have started flinging",
-                ContentViewGestureHandler.GESTURE_FLING_START,
-                        mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.FLING_START,
+                        mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertTrue("A scroll end event should not have been sent",
-                !mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_SCROLL_END));
+                !mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.SCROLL_END));
         assertEquals("The last up should have caused flingStart to be sent",
-                5, mockDelegate.mGestureTypeList.size());
+                5, mMockMotionEventDelegate.mGestureTypeList.size());
         assertEquals("flingStart should have the time of the ACTION_UP",
-                eventTime + 15, (long) mockDelegate.mGestureTimeList.get(4));
-
-        event = motionEvent(MotionEvent.ACTION_DOWN, downTime + 50, downTime + 50);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertTrue("A flingCancel should have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_FLING_CANCEL));
-        assertEquals("Only tapDown and flingCancel should have been sent",
-                7, mockDelegate.mGestureTypeList.size());
+                eventTime + 15, (long) mMockMotionEventDelegate.mGestureTimeList.get(4));
     }
 
     /**
@@ -698,43 +319,35 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         final long downTime = SystemClock.uptimeMillis();
         final long eventTime = SystemClock.uptimeMillis();
 
-        GestureRecordingMotionEventDelegate mockDelegate =
-                new GestureRecordingMotionEventDelegate();
-        mGestureHandler = new ContentViewGestureHandler(
-                getInstrumentation().getTargetContext(), mockDelegate, mMockZoomManager);
+        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
+        assertTrue(mGestureHandler.onTouchEvent(event));
 
         mGestureHandler.fling(eventTime, 5, 5, 0, 0);
-        assertEquals("A zero-velocity fling should not be forwrded",
-                null, mockDelegate.mMostRecentGestureEvent);
+        assertEquals("A zero-velocity fling should not be forwarded",
+                GestureEventType.TAP_DOWN,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
 
         mGestureHandler.fling(eventTime, 5, 5, 5, 0);
         assertEquals("Subsequent flings should work properly",
-                ContentViewGestureHandler.GESTURE_FLING_START,
-                        mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.FLING_START,
+                        mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
 
-        mGestureHandler.fling(eventTime, 5, 5, 0, 0);
-        assertEquals("A zero-velocity fling should cancel any outstanding fling",
-                ContentViewGestureHandler.GESTURE_FLING_CANCEL,
-                        mockDelegate.mMostRecentGestureEvent.mType);
-
-        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
-        assertTrue(mGestureHandler.onTouchEvent(event));
         event = MotionEvent.obtain(
                 downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
                 FAKE_COORD_X * 5, FAKE_COORD_Y * 5, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertTrue(mGestureHandler.isNativeScrolling());
         assertTrue("A scrollStart event should have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_SCROLL_START));
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.SCROLL_START));
         assertEquals("We should have started scrolling",
-                ContentViewGestureHandler.GESTURE_SCROLL_BY,
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.SCROLL_BY,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
 
         mGestureHandler.fling(eventTime, 5, 5, 0, 0);
         assertEquals("A zero-velicty fling should end the current scroll sequence",
-                ContentViewGestureHandler.GESTURE_SCROLL_END,
-                        mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.SCROLL_END,
+                        mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
     }
 
     /**
@@ -746,41 +359,42 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
     @Feature({"Gestures"})
     public void testShowPressCancelOnWindowFocusLost() throws Exception {
         final long time = SystemClock.uptimeMillis();
-        GestureRecordingMotionEventDelegate mockDelegate =
-                new GestureRecordingMotionEventDelegate();
-        mGestureHandler = new ContentViewGestureHandler(
-                getInstrumentation().getTargetContext(), mockDelegate, mMockZoomManager);
-        mLongPressDetector = new LongPressDetector(
-                getInstrumentation().getTargetContext(), mGestureHandler);
-        mGestureHandler.setTestDependencies(mLongPressDetector, null, null);
 
-        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, time, time);
-        mGestureHandler.onTouchEvent(event);
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                setUp();
+                MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, time, time);
+                mGestureHandler.onTouchEvent(event);
+            }
+        });
 
-        mGestureHandler.sendShowPressedStateGestureForTesting();
-        assertEquals("A show pressed state event should have been sent",
-                ContentViewGestureHandler.GESTURE_SHOW_PRESSED_STATE,
-                        mockDelegate.mMostRecentGestureEvent.mType);
-        assertEquals("Only showPressedState and tapDown should have been sent",
-                2, mockDelegate.mGestureTypeList.size());
+        assertTrue(mMockMotionEventDelegate.mShowPressCalled.await(
+                ScalableTimeout.scaleTimeout(ViewConfiguration.getTapTimeout() + 10),
+                TimeUnit.MILLISECONDS));
 
-        mLongPressDetector.startLongPressTimerIfNeeded(event);
-        mLongPressDetector.sendLongPressGestureForTest();
+        assertTrue(mMockMotionEventDelegate.mLongPressCalled.await(
+                ScalableTimeout.scaleTimeout(ViewConfiguration.getLongPressTimeout()
+                        + ViewConfiguration.getTapTimeout() + 10),
+                TimeUnit.MILLISECONDS));
 
-        assertEquals("Only should have sent only LONG_PRESS event",
-                3, mockDelegate.mGestureTypeList.size());
-        assertEquals("Should have a long press event next",
-                ContentViewGestureHandler.GESTURE_LONG_PRESS,
-                mockDelegate.mGestureTypeList.get(2).intValue());
+        assertEquals("Should have sent SHOW_PRESS and LONG_PRESS events",
+                3, mMockMotionEventDelegate.mGestureTypeList.size());
+        assertEquals("Should have a show press event",
+                GestureEventType.SHOW_PRESS,
+                mMockMotionEventDelegate.mGestureTypeList.get(1).intValue());
+        assertEquals("Should have a long press event",
+                GestureEventType.LONG_PRESS,
+                mMockMotionEventDelegate.mGestureTypeList.get(2).intValue());
 
         // The long press triggers window focus loss by opening a context menu
         mGestureHandler.onWindowFocusLost();
 
         assertEquals("Only should have sent only GESTURE_TAP_CANCEL event",
-                4, mockDelegate.mGestureTypeList.size());
+                4, mMockMotionEventDelegate.mGestureTypeList.size());
         assertEquals("Should have a gesture show press cancel event next",
-                ContentViewGestureHandler.GESTURE_TAP_CANCEL,
-                mockDelegate.mGestureTypeList.get(3).intValue());
+                GestureEventType.TAP_CANCEL,
+                mMockMotionEventDelegate.mGestureTypeList.get(3).intValue());
     }
 
     /**
@@ -793,25 +407,17 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         final long downTime = SystemClock.uptimeMillis();
         final long eventTime = SystemClock.uptimeMillis();
 
-        GestureRecordingMotionEventDelegate mockDelegate =
-                new GestureRecordingMotionEventDelegate();
-        mGestureHandler = new ContentViewGestureHandler(
-                getInstrumentation().getTargetContext(), mockDelegate, mMockZoomManager);
-        mLongPressDetector = new LongPressDetector(
-                getInstrumentation().getTargetContext(), mGestureHandler);
-
         MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
 
         assertTrue(mGestureHandler.onTouchEvent(event));
-        assertFalse("Should not have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
 
         mGestureHandler.sendShowPressedStateGestureForTesting();
 
         assertEquals("A show pressed state event should have been sent",
-                ContentViewGestureHandler.GESTURE_SHOW_PRESSED_STATE,
-                        mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.SHOW_PRESS,
+                        mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertEquals("Only tapDown and showPressedState should have been sent",
-                2, mockDelegate.mGestureTypeList.size());
+                2, mMockMotionEventDelegate.mGestureTypeList.size());
 
         event = MotionEvent.obtain(
                 downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
@@ -819,27 +425,27 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         assertTrue(mGestureHandler.onTouchEvent(event));
 
         assertEquals("We should have started scrolling",
-                ContentViewGestureHandler.GESTURE_SCROLL_BY,
-                        mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.SCROLL_BY,
+                        mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertTrue("A show press cancel event should have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_TAP_CANCEL));
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.TAP_CANCEL));
         assertEquals("Only tapDown, showPressedState, showPressCancel, scrollBegin and scrollBy" +
                 " should have been sent",
-                5, mockDelegate.mGestureTypeList.size());
+                5, mMockMotionEventDelegate.mGestureTypeList.size());
 
         event = MotionEvent.obtain(
                 downTime, eventTime + 15, MotionEvent.ACTION_UP,
                 FAKE_COORD_X * 10, FAKE_COORD_Y * 10, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertEquals("We should have started flinging",
-                ContentViewGestureHandler.GESTURE_FLING_START,
-                        mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.FLING_START,
+                        mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertTrue("A scroll end event should not have been sent",
-                !mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_SCROLL_END));
+                !mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.SCROLL_END));
         assertEquals("The last up should have caused flingStart to be sent",
-                6, mockDelegate.mGestureTypeList.size());
+                6, mMockMotionEventDelegate.mGestureTypeList.size());
     }
 
     /**
@@ -853,49 +459,41 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         final long downTime = SystemClock.uptimeMillis();
         final long eventTime = SystemClock.uptimeMillis();
 
-        GestureRecordingMotionEventDelegate mockDelegate =
-                new GestureRecordingMotionEventDelegate();
-        mGestureHandler = new ContentViewGestureHandler(
-                getInstrumentation().getTargetContext(), mockDelegate, mMockZoomManager);
-        mLongPressDetector = new LongPressDetector(
-                getInstrumentation().getTargetContext(), mGestureHandler);
-
         MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
         assertTrue(mGestureHandler.onTouchEvent(event));
-        assertFalse("Should not have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
 
         mGestureHandler.sendShowPressedStateGestureForTesting();
-        assertEquals("GESTURE_SHOW_PRESSED_STATE should have been sent",
-                ContentViewGestureHandler.GESTURE_SHOW_PRESSED_STATE,
-                mockDelegate.mMostRecentGestureEvent.mType);
-        assertEquals("Only GESTURE_TAP_DOWN and GESTURE_SHOW_PRESSED_STATE should have been sent",
-                2, mockDelegate.mGestureTypeList.size());
+        assertEquals("GESTURE_SHOW_PRESS should have been sent",
+                GestureEventType.SHOW_PRESS,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
+        assertEquals("Only GESTURE_TAP_DOWN and GESTURE_SHOW_PRESS should have been sent",
+                2, mMockMotionEventDelegate.mGestureTypeList.size());
 
         event = MotionEvent.obtain(
                 downTime, eventTime + 5, MotionEvent.ACTION_UP,
                 FAKE_COORD_X, FAKE_COORD_Y, 0);
         mGestureHandler.onTouchEvent(event);
         assertEquals("A GESTURE_SINGLE_TAP_UNCONFIRMED event should have been sent",
-                ContentViewGestureHandler.GESTURE_SINGLE_TAP_UNCONFIRMED,
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.SINGLE_TAP_UNCONFIRMED,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertEquals("Only GESTURE_TAP_DOWN, " +
-                "GESTURE_SHOW_PRESSED_STATE and " +
+                "GESTURE_SHOW_PRESS and " +
                 "GESTURE_SINGLE_TAP_UNCONFIRMED should have been sent",
-                3, mockDelegate.mGestureTypeList.size());
+                3, mMockMotionEventDelegate.mGestureTypeList.size());
 
         event = MotionEvent.obtain(
                 eventTime + 10, eventTime + 10, MotionEvent.ACTION_DOWN,
                 FAKE_COORD_X, FAKE_COORD_Y, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertEquals("A GESTURE_TAP_DOWN event should have been sent ",
-                ContentViewGestureHandler.GESTURE_TAP_DOWN,
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.TAP_DOWN,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertEquals("Only GESTURE_TAP_DOWN, " +
-                "GESTURE_SHOW_PRESSED_STATE, " +
+                "GESTURE_SHOW_PRESS, " +
                 "GESTURE_SINGLE_TAP_UNCONFIRMED," +
                 "GESTURE_TAP_CANCEL and" +
                 "GESTURE_TAP_DOWN should have been sent",
-                5, mockDelegate.mGestureTypeList.size());
+                5, mMockMotionEventDelegate.mGestureTypeList.size());
 
         // Moving a very small amount of distance should not trigger the double tap drag zoom mode.
         event = MotionEvent.obtain(
@@ -903,26 +501,26 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
                 FAKE_COORD_X, FAKE_COORD_Y + 1, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertEquals("Only GESTURE_TAP_DOWN, " +
-                "GESTURE_SHOW_PRESSED_STATE, " +
+                "GESTURE_SHOW_PRESS, " +
                 "GESTURE_SINGLE_TAP_UNCONFIRMED and" +
-                "GESTURE_TAP_CANCEL and" +
+                "GESTURE_TAP_CANCEL and " +
                 "GESTURE_TAP_DOWN should have been sent",
-                5, mockDelegate.mGestureTypeList.size());
+                5, mMockMotionEventDelegate.mGestureTypeList.size());
 
         event = MotionEvent.obtain(
                 eventTime + 10, eventTime + 15, MotionEvent.ACTION_UP,
                 FAKE_COORD_X, FAKE_COORD_Y + 1, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertEquals("A double tap should have occurred",
-                ContentViewGestureHandler.GESTURE_DOUBLE_TAP,
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.DOUBLE_TAP,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertEquals("Only GESTURE_TAP_DOWN, " +
-                "GESTURE_SHOW_PRESSED_STATE, " +
+                "GESTURE_SHOW_PRESS, " +
                 "GESTURE_SINGLE_TAP_UNCONFIRMED, " +
                 "GESTURE_TAP_CANCEL, " +
                 "GESTURE_TAP_DOWN, " +
                 "GESTURE_DOUBLE_TAP should have been sent",
-                6, mockDelegate.mGestureTypeList.size());
+                6, mMockMotionEventDelegate.mGestureTypeList.size());
     }
 
     /**
@@ -935,23 +533,15 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         final long downTime1 = SystemClock.uptimeMillis();
         final long downTime2 = downTime1 + 100;
 
-        GestureRecordingMotionEventDelegate mockDelegate =
-                new GestureRecordingMotionEventDelegate();
-        mGestureHandler = new ContentViewGestureHandler(
-                getInstrumentation().getTargetContext(), mockDelegate, mMockZoomManager);
-        mLongPressDetector = new LongPressDetector(
-                getInstrumentation().getTargetContext(), mGestureHandler);
-
         MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime1, downTime1);
         assertTrue(mGestureHandler.onTouchEvent(event));
-        assertFalse("Should not have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
 
         mGestureHandler.sendShowPressedStateGestureForTesting();
-        assertEquals("GESTURE_SHOW_PRESSED_STATE should have been sent",
-                ContentViewGestureHandler.GESTURE_SHOW_PRESSED_STATE,
-                        mockDelegate.mMostRecentGestureEvent.mType);
-        assertEquals("Only GESTURE_TAP_DOWN and GESTURE_SHOW_PRESSED_STATE should have been sent",
-                2, mockDelegate.mGestureTypeList.size());
+        assertEquals("GESTURE_SHOW_PRESS should have been sent",
+                GestureEventType.SHOW_PRESS,
+                        mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
+        assertEquals("Only GESTURE_TAP_DOWN and GESTURE_SHOW_PRESS should have been sent",
+                2, mMockMotionEventDelegate.mGestureTypeList.size());
 
 
         event = MotionEvent.obtain(
@@ -959,37 +549,37 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
                 FAKE_COORD_X, FAKE_COORD_Y, 0);
         mGestureHandler.onTouchEvent(event);
         assertEquals("A GESTURE_SINGLE_TAP_UNCONFIRMED event should have been sent",
-                ContentViewGestureHandler.GESTURE_SINGLE_TAP_UNCONFIRMED,
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.SINGLE_TAP_UNCONFIRMED,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertEquals("Only GESTURE_TAP_DOWN, " +
-                "GESTURE_SHOW_PRESSED_STATE and " +
+                "GESTURE_SHOW_PRESS and " +
                 "GESTURE_TAP_UNCONFIRMED " +
                 "should have been sent",
-                3, mockDelegate.mGestureTypeList.size());
+                3, mMockMotionEventDelegate.mGestureTypeList.size());
 
         event = MotionEvent.obtain(
                 downTime2, downTime2, MotionEvent.ACTION_DOWN,
                 FAKE_COORD_X, FAKE_COORD_Y, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertEquals("GESTURE_TAP_DOWN should have been sent",
-                ContentViewGestureHandler.GESTURE_TAP_DOWN,
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.TAP_DOWN,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertEquals("Only GESTURE_TAP_DOWN, " +
-                "GESTURE_SHOW_PRESSED_STATE, " +
+                "GESTURE_SHOW_PRESS, " +
                 "GESTURE_TAP_UNCONFIRMED," +
                 "GESTURE_TAP_CANCEL and" +
                 "GESTURE_TAP_DOWN should have been sent",
-                5, mockDelegate.mGestureTypeList.size());
+                5, mMockMotionEventDelegate.mGestureTypeList.size());
 
         event = MotionEvent.obtain(
                 downTime2, downTime2 + 5, MotionEvent.ACTION_MOVE,
                 FAKE_COORD_X, FAKE_COORD_Y + 100, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertTrue("GESTURE_SCROLL_START should have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_SCROLL_START));
-        GestureRecordingMotionEventDelegate.GestureEvent startEvent =
-                mockDelegate.getActiveScrollStartEvent();
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.SCROLL_START));
+        MockMotionEventDelegate.GestureEvent startEvent =
+                mMockMotionEventDelegate.mActiveScrollStartEvent;
         assertEquals(FAKE_COORD_X, startEvent.getX());
         assertEquals(FAKE_COORD_Y + 100, startEvent.getY());
         Bundle extraParams = startEvent.getExtraParams();
@@ -1000,30 +590,30 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
                 100, extraParams.getInt(ContentViewGestureHandler.DELTA_HINT_Y));
 
         assertEquals("GESTURE_PINCH_BEGIN should have been sent",
-                ContentViewGestureHandler.GESTURE_PINCH_BEGIN,
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.PINCH_BEGIN,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertEquals("Only GESTURE_TAP_DOWN, " +
-                "GESTURE_SHOW_PRESSED_STATE, " +
+                "GESTURE_SHOW_PRESS, " +
                 "GESTURE_TAP_UNCONFIRMED," +
                 "GESTURE_TAP_CANCEL, " +
                 "GESTURE_TAP_DOWN, " +
                 "GESTURE_TAP_CANCEL, " +
                 "GESTURE_SCROLL_START, and " +
                 "GESTURE_PINCH_BEGIN should have been sent",
-                8, mockDelegate.mGestureTypeList.size());
+                8, mMockMotionEventDelegate.mGestureTypeList.size());
 
         event = MotionEvent.obtain(
                 downTime2, downTime2 + 10, MotionEvent.ACTION_MOVE,
                 FAKE_COORD_X, FAKE_COORD_Y + 200, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertTrue("GESTURE_SCROLL_BY should have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_SCROLL_BY));
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.SCROLL_BY));
         assertEquals("GESTURE_PINCH_BY should have been sent",
-                ContentViewGestureHandler.GESTURE_PINCH_BY,
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.PINCH_BY,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertEquals("Only GESTURE_TAP_DOWN, " +
-                "GESTURE_SHOW_PRESSED_STATE, " +
+                "GESTURE_SHOW_PRESS, " +
                 "GESTURE_TAP_UNCONFIRMED," +
                 "GESTURE_TAP_CANCEL, " +
                 "GESTURE_TAP_DOWN, " +
@@ -1032,20 +622,20 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
                 "GESTURE_PINCH_BEGIN, " +
                 "GESTURE_SCROLL_BY, and " +
                 "GESTURE_PINCH_BY should have been sent",
-                10, mockDelegate.mGestureTypeList.size());
+                10, mMockMotionEventDelegate.mGestureTypeList.size());
 
         event = MotionEvent.obtain(
                 downTime2, downTime2 + 15, MotionEvent.ACTION_UP,
                 FAKE_COORD_X, FAKE_COORD_Y + 200, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertTrue("GESTURE_PINCH_END should have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_PINCH_END));
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.PINCH_END));
         assertEquals("GESTURE_SCROLL_END should have been sent",
-                ContentViewGestureHandler.GESTURE_SCROLL_END,
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.SCROLL_END,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertEquals("Only GESTURE_TAP_DOWN, " +
-                "GESTURE_SHOW_PRESSED_STATE, " +
+                "GESTURE_SHOW_PRESS, " +
                 "GESTURE_TAP_UNCONFIRMED," +
                 "GESTURE_TAP_CANCEL, " +
                 "GESTURE_TAP_DOWN, " +
@@ -1056,7 +646,7 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
                 "GESTURE_PINCH_BY, " +
                 "GESTURE_PINCH_END, and " +
                 "GESTURE_SCROLL_END should have been sent",
-                12, mockDelegate.mGestureTypeList.size());
+                12, mMockMotionEventDelegate.mGestureTypeList.size());
     }
 
 
@@ -1071,83 +661,103 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         final long downTime1 = SystemClock.uptimeMillis();
         final long downTime2 = downTime1 + 100;
 
-        GestureRecordingMotionEventDelegate mockDelegate =
-                new GestureRecordingMotionEventDelegate();
-        mGestureHandler = new ContentViewGestureHandler(
-                getInstrumentation().getTargetContext(), mockDelegate, mMockZoomManager);
-        mLongPressDetector = new LongPressDetector(
-                getInstrumentation().getTargetContext(), mGestureHandler);
+        PointerProperties pp0 = new PointerProperties();
+        pp0.id = 0;
+        pp0.toolType = MotionEvent.TOOL_TYPE_FINGER;
+        PointerProperties pp1 = new PointerProperties();
+        pp1.id = 1;
+        pp1.toolType = MotionEvent.TOOL_TYPE_FINGER;
+
+        PointerCoords pc0 = new PointerCoords();
+        pc0.x = FAKE_COORD_X;
+        pc0.y = FAKE_COORD_Y;
+        pc0.pressure = 1;
+        pc0.size = 1;
+        PointerCoords pc1 = new PointerCoords();
+        pc1.x = FAKE_COORD_X + 50;
+        pc1.y = FAKE_COORD_Y + 50;
+        pc1.pressure = 1;
+        pc1.size = 1;
 
-        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime1, downTime1);
+        MotionEvent event = MotionEvent.obtain(
+                downTime1, downTime1, MotionEvent.ACTION_DOWN,
+                1, new PointerProperties[] { pp0 }, new PointerCoords[] { pc0 },
+                0, 0, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_CLASS_POINTER, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
 
         mGestureHandler.sendShowPressedStateGestureForTesting();
-        assertEquals("GESTURE_SHOW_PRESSED_STATE should have been sent",
-                ContentViewGestureHandler.GESTURE_SHOW_PRESSED_STATE,
-                        mockDelegate.mMostRecentGestureEvent.mType);
-        assertEquals("Only GESTURE_TAP_DOWN and GESTURE_SHOW_PRESSED_STATE should have been sent",
-                2, mockDelegate.mGestureTypeList.size());
+        assertEquals("GESTURE_SHOW_PRESS should have been sent",
+                GestureEventType.SHOW_PRESS,
+                        mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
+        assertEquals("Only GESTURE_TAP_DOWN and GESTURE_SHOW_PRESS should have been sent",
+                2, mMockMotionEventDelegate.mGestureTypeList.size());
 
         event = MotionEvent.obtain(
                 downTime1, downTime1 + 5, MotionEvent.ACTION_UP,
-                FAKE_COORD_X, FAKE_COORD_Y, 0);
+                1, new PointerProperties[] { pp0 }, new PointerCoords[] { pc0 },
+                0, 0, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_CLASS_POINTER, 0);
         mGestureHandler.onTouchEvent(event);
         assertEquals("A GESTURE_SINGLE_TAP_UNCONFIRMED event should have been sent",
-                ContentViewGestureHandler.GESTURE_SINGLE_TAP_UNCONFIRMED,
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.SINGLE_TAP_UNCONFIRMED,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertEquals("Only GESTURE_TAP_DOWN, " +
-                "GESTURE_SHOW_PRESSED_STATE and " +
+                "GESTURE_SHOW_PRESS and " +
                 "GESTURE_TAP_UNCONFIRMED " +
                 "should have been sent",
-                3, mockDelegate.mGestureTypeList.size());
+                3, mMockMotionEventDelegate.mGestureTypeList.size());
 
         event = MotionEvent.obtain(
                 downTime2, downTime2, MotionEvent.ACTION_DOWN,
-                FAKE_COORD_X, FAKE_COORD_Y, 0);
+                1, new PointerProperties[] { pp0 }, new PointerCoords[] { pc0 },
+                0, 0, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_CLASS_POINTER, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertEquals("GESTURE_TAP_DOWN should have been sent",
-                ContentViewGestureHandler.GESTURE_TAP_DOWN,
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.TAP_DOWN,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertEquals("Only GESTURE_TAP_DOWN, " +
-                "GESTURE_SHOW_PRESSED_STATE, " +
+                "GESTURE_SHOW_PRESS, " +
                 "GESTURE_TAP_UNCONFIRMED," +
                 "GESTURE_TAP_CANCEL and" +
                 "GESTURE_TAP_DOWN should have been sent",
-                5, mockDelegate.mGestureTypeList.size());
+                5, mMockMotionEventDelegate.mGestureTypeList.size());
+
+        pc0.y = pc0.y - 30;
 
         event = MotionEvent.obtain(
-                downTime2, downTime2 + 5, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X, FAKE_COORD_Y + 100, 0);
+                downTime2, downTime2 + 50, MotionEvent.ACTION_MOVE,
+                1, new PointerProperties[] { pp0 }, new PointerCoords[] { pc0 },
+                0, 0, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_CLASS_POINTER, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertTrue("GESTURE_SCROLL_START should have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_SCROLL_START));
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.SCROLL_START));
 
         assertEquals("GESTURE_PINCH_BEGIN should have been sent",
-                ContentViewGestureHandler.GESTURE_PINCH_BEGIN,
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.PINCH_BEGIN,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertEquals("Only GESTURE_TAP_DOWN, " +
-                "GESTURE_SHOW_PRESSED_STATE, " +
+                "GESTURE_SHOW_PRESS, " +
                 "GESTURE_TAP_UNCONFIRMED," +
                 "GESTURE_TAP_CANCEL, " +
                 "GESTURE_TAP_DOWN, " +
                 "GESTURE_TAP_CANCEL, " +
                 "GESTURE_SCROLL_START, and " +
                 "GESTURE_PINCH_BEGIN should have been sent",
-                8, mockDelegate.mGestureTypeList.size());
+                8, mMockMotionEventDelegate.mGestureTypeList.size());
 
         event = MotionEvent.obtain(
-                downTime2, downTime2 + 10, MotionEvent.ACTION_POINTER_DOWN,
-                FAKE_COORD_X, FAKE_COORD_Y + 200, 0);
+                downTime2, downTime2 + 100, MotionEvent.ACTION_POINTER_DOWN,
+                2, new PointerProperties[] { pp1, pp0 }, new PointerCoords[] { pc1, pc0 },
+                0, 0, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_CLASS_POINTER, 0);
         mGestureHandler.onTouchEvent(event);
         assertTrue("GESTURE_PINCH_END should have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_PINCH_END));
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.PINCH_END));
         assertEquals("GESTURE_SCROLL_END should have been sent",
-                ContentViewGestureHandler.GESTURE_SCROLL_END,
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.SCROLL_END,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertEquals("Only GESTURE_TAP_DOWN, " +
-                "GESTURE_SHOW_PRESSED_STATE, " +
+                "GESTURE_SHOW_PRESS, " +
                 "GESTURE_TAP_UNCONFIRMED," +
                 "GESTURE_TAP_CANCEL, " +
                 "GESTURE_TAP_DOWN, " +
@@ -1156,21 +766,15 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
                 "GESTURE_PINCH_BEGIN, " +
                 "GESTURE_PINCH_END, and " +
                 "GESTURE_SCROLL_END should have been sent",
-                10, mockDelegate.mGestureTypeList.size());
-
-        event = MotionEvent.obtain(
-                downTime2, downTime2 + 15, MotionEvent.ACTION_POINTER_UP,
-                FAKE_COORD_X, FAKE_COORD_Y + 200, 0);
-        mGestureHandler.onTouchEvent(event);
-        assertEquals("No new gestures should have been sent",
-                10, mockDelegate.mGestureTypeList.size());
+                10, mMockMotionEventDelegate.mGestureTypeList.size());
 
         event = MotionEvent.obtain(
-                downTime2, downTime2 + 20, MotionEvent.ACTION_UP,
-                FAKE_COORD_X, FAKE_COORD_Y + 200, 0);
+                downTime2, downTime2 + 150, MotionEvent.ACTION_POINTER_UP,
+                2, new PointerProperties[] { pp1, pp0 }, new PointerCoords[] { pc1, pc0 },
+                0, 0, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_CLASS_POINTER, 0);
         mGestureHandler.onTouchEvent(event);
         assertEquals("No new gestures should have been sent",
-                10, mockDelegate.mGestureTypeList.size());
+                10, mMockMotionEventDelegate.mGestureTypeList.size());
     }
 
     /**
@@ -1184,10 +788,6 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         final long downTime1 = SystemClock.uptimeMillis();
         final long downTime2 = downTime1 + 100;
 
-        GestureRecordingMotionEventDelegate mockDelegate =
-                new GestureRecordingMotionEventDelegate();
-        mGestureHandler = new ContentViewGestureHandler(
-                getInstrumentation().getTargetContext(), mockDelegate, mMockZoomManager);
         mGestureHandler.updateDoubleTapSupport(false);
 
         MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime1, downTime1);
@@ -1211,122 +811,33 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         // disabled.
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertTrue("GESTURE_SCROLL_START should have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_SCROLL_START));
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.SCROLL_START));
         assertFalse("No GESTURE_PINCH_BEGIN should have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_PINCH_BEGIN));
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.PINCH_BEGIN));
 
         event = MotionEvent.obtain(
                 downTime2, downTime2 + 10, MotionEvent.ACTION_MOVE,
                 FAKE_COORD_X, FAKE_COORD_Y + 200, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertEquals("GESTURE_SCROLL_BY should have been sent",
-                ContentViewGestureHandler.GESTURE_SCROLL_BY,
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.SCROLL_BY,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertEquals("GESTURE_SCROLL_BY should have been sent",
                 event.getEventTime(),
-                mockDelegate.mMostRecentGestureEvent.getTimeMs());
+                mMockMotionEventDelegate.mMostRecentGestureEvent.getTimeMs());
         assertTrue("No GESTURE_PINCH_BY should have been sent",
-                ContentViewGestureHandler.GESTURE_PINCH_BY !=
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.PINCH_BY !=
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
 
         event = MotionEvent.obtain(
                 downTime2, downTime2 + 15, MotionEvent.ACTION_UP,
                 FAKE_COORD_X, FAKE_COORD_Y + 200, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertFalse("No GESTURE_PINCH_END should have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_PINCH_END));
-    }
-
-    /**
-     * Mock MotionEventDelegate that remembers the most recent gesture event and any
-     * currently active scroll start event.
-     */
-    static class GestureRecordingMotionEventDelegate implements MotionEventDelegate {
-        static class GestureEvent {
-            private final int mType;
-            private final long mTimeMs;
-            private final int mX;
-            private final int mY;
-            private final Bundle mExtraParams;
-
-            public GestureEvent(int type, long timeMs, int x, int y, Bundle extraParams) {
-                mType = type;
-                mTimeMs = timeMs;
-                mX = x;
-                mY = y;
-                mExtraParams = extraParams;
-            }
-
-            public int getType() {
-                return mType;
-            }
-
-            public long getTimeMs() {
-                return mTimeMs;
-            }
-
-            public int getX() {
-                return mX;
-            }
-
-            public int getY() {
-                return mY;
-            }
-
-            public Bundle getExtraParams() {
-                return mExtraParams;
-            }
-        }
-        private GestureEvent mMostRecentGestureEvent;
-        private GestureEvent mActiveScrollStartEvent;
-        private final ArrayList<Integer> mGestureTypeList = new ArrayList<Integer>();
-        private final ArrayList<Long> mGestureTimeList = new ArrayList<Long>();
-
-        @Override
-        public boolean sendTouchEvent(long timeMs, int action, TouchPoint[] pts) {
-            return true;
-        }
-
-        @Override
-        public boolean sendGesture(int type, long timeMs, int x, int y, Bundle extraParams) {
-            Log.i(TAG, "Gesture event received with type id " + type);
-            mMostRecentGestureEvent = new GestureEvent(type, timeMs, x, y, extraParams);
-            mGestureTypeList.add(mMostRecentGestureEvent.mType);
-            mGestureTimeList.add(timeMs);
-            if (type == ContentViewGestureHandler.GESTURE_SCROLL_START)
-                mActiveScrollStartEvent = mMostRecentGestureEvent;
-            else if (type == ContentViewGestureHandler.GESTURE_SCROLL_END ||
-                         type == ContentViewGestureHandler.GESTURE_FLING_CANCEL)
-                mActiveScrollStartEvent = null;
-            return true;
-        }
-
-        @Override
-        public void sendSingleTapUMA(int type) {
-            // Not implemented.
-        }
-
-        @Override
-        public void sendActionAfterDoubleTapUMA(int type,
-                boolean clickDelayEnabled) {
-            // Not implemented.
-        }
-
-        @Override
-        public void invokeZoomPicker() {
-            // Not implemented.
-        }
-
-        public GestureEvent getMostRecentGestureEvent() {
-            return mMostRecentGestureEvent;
-        }
-
-        public GestureEvent getActiveScrollStartEvent() {
-            return mActiveScrollStartEvent;
-        }
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.PINCH_END));
     }
 
     /**
@@ -1340,29 +851,26 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         final int deltaY = 84;
         final long downTime = SystemClock.uptimeMillis();
 
-        GestureRecordingMotionEventDelegate delegate = new GestureRecordingMotionEventDelegate();
-        ContentViewGestureHandler gestureHandler = new ContentViewGestureHandler(
-                getInstrumentation().getTargetContext(), delegate, mMockZoomManager);
         MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
-        assertTrue(gestureHandler.onTouchEvent(event));
+        assertTrue(mGestureHandler.onTouchEvent(event));
 
         // Move twice so that we get two GESTURE_SCROLL_BY events and can compare
         // the relative and absolute coordinates.
         event = MotionEvent.obtain(
                 downTime, downTime + 5, MotionEvent.ACTION_MOVE,
                 FAKE_COORD_X - deltaX / 2, FAKE_COORD_Y - deltaY / 2, 0);
-        assertTrue(gestureHandler.onTouchEvent(event));
+        assertTrue(mGestureHandler.onTouchEvent(event));
 
         event = MotionEvent.obtain(
                 downTime, downTime + 10, MotionEvent.ACTION_MOVE,
                 FAKE_COORD_X - deltaX, FAKE_COORD_Y - deltaY, 0);
-        assertTrue(gestureHandler.onTouchEvent(event));
+        assertTrue(mGestureHandler.onTouchEvent(event));
 
         // Make sure the reported gesture event has all the expected data.
-        GestureRecordingMotionEventDelegate.GestureEvent gestureEvent =
-                delegate.getMostRecentGestureEvent();
+        MockMotionEventDelegate.GestureEvent gestureEvent =
+                mMockMotionEventDelegate.mMostRecentGestureEvent;
         assertNotNull(gestureEvent);
-        assertEquals(ContentViewGestureHandler.GESTURE_SCROLL_BY, gestureEvent.getType());
+        assertEquals(GestureEventType.SCROLL_BY, gestureEvent.getType());
         assertEquals(downTime + 10, gestureEvent.getTimeMs());
         assertEquals(FAKE_COORD_X - deltaX, gestureEvent.getX());
         assertEquals(FAKE_COORD_Y - deltaY, gestureEvent.getY());
@@ -1385,30 +893,27 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         final int deltaY = 89;
         final long downTime = SystemClock.uptimeMillis();
 
-        GestureRecordingMotionEventDelegate delegate = new GestureRecordingMotionEventDelegate();
-        ContentViewGestureHandler gestureHandler = new ContentViewGestureHandler(
-                getInstrumentation().getTargetContext(), delegate, mMockZoomManager);
         MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
-        assertTrue(gestureHandler.onTouchEvent(event));
+        assertTrue(mGestureHandler.onTouchEvent(event));
 
         // Move twice such that the first event isn't sufficient to start
         // scrolling on it's own.
         event = MotionEvent.obtain(
                 downTime, downTime + 5, MotionEvent.ACTION_MOVE,
                 FAKE_COORD_X + 2, FAKE_COORD_Y + 1, 0);
-        assertFalse(gestureHandler.onTouchEvent(event));
+        assertTrue(mGestureHandler.onTouchEvent(event));
         assertNull("Expect scrolling hasn't yet started",
-                delegate.getActiveScrollStartEvent());
+                mMockMotionEventDelegate.mActiveScrollStartEvent);
 
         event = MotionEvent.obtain(
                 downTime, downTime + 10, MotionEvent.ACTION_MOVE,
                 FAKE_COORD_X + deltaX, FAKE_COORD_Y + deltaY, 0);
-        assertTrue(gestureHandler.onTouchEvent(event));
+        assertTrue(mGestureHandler.onTouchEvent(event));
 
-        GestureRecordingMotionEventDelegate.GestureEvent startEvent =
-                delegate.getActiveScrollStartEvent();
+        MockMotionEventDelegate.GestureEvent startEvent =
+                mMockMotionEventDelegate.mActiveScrollStartEvent;
         assertNotNull(startEvent);
-        assertEquals(ContentViewGestureHandler.GESTURE_SCROLL_START, startEvent.getType());
+        assertEquals(GestureEventType.SCROLL_START, startEvent.getType());
         assertEquals(downTime + 10, startEvent.getTimeMs());
         assertEquals(FAKE_COORD_X, startEvent.getX());
         assertEquals(FAKE_COORD_Y, startEvent.getY());
@@ -1431,74 +936,36 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         final long downTime = SystemClock.uptimeMillis();
         final long eventTime = SystemClock.uptimeMillis();
 
-        GestureRecordingMotionEventDelegate mockDelegate =
-                new GestureRecordingMotionEventDelegate();
-        mGestureHandler = new ContentViewGestureHandler(
-                getInstrumentation().getTargetContext(), mockDelegate, mMockZoomManager);
-        mLongPressDetector = mGestureHandler.getLongPressDetector();
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                setUp();
 
-        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertTrue("Should have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
-        event = MotionEvent.obtain(
-                downTime, eventTime + 5, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X * 5, FAKE_COORD_Y * 5, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        event = MotionEvent.obtain(
-                downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X * 10, FAKE_COORD_Y * 10, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertTrue("Should not have a pending LONG_PRESS", !mLongPressDetector.hasPendingMessage());
+                MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
+                assertTrue(mGestureHandler.onTouchEvent(event));
+                event = MotionEvent.obtain(
+                        downTime, eventTime + 5, MotionEvent.ACTION_MOVE,
+                        FAKE_COORD_X * 5, FAKE_COORD_Y * 5, 0);
+                assertTrue(mGestureHandler.onTouchEvent(event));
+                event = MotionEvent.obtain(
+                        downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
+                        FAKE_COORD_X * 10, FAKE_COORD_Y * 10, 0);
+                assertTrue(mGestureHandler.onTouchEvent(event));
+            }
+        });
+
+        assertFalse(mMockMotionEventDelegate.mLongPressCalled.await(
+                ScalableTimeout.scaleTimeout(ViewConfiguration.getLongPressTimeout()
+                        + ViewConfiguration.getTapTimeout() + 10),
+                TimeUnit.MILLISECONDS));
 
         // No LONG_TAP because LONG_PRESS timer is cancelled.
         assertFalse("No LONG_PRESS should be sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_LONG_PRESS));
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.LONG_PRESS));
         assertFalse("No LONG_TAP should be sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_LONG_TAP));
-    }
-
-    /**
-     * Verifies that when hasTouchEventHandlers changes while in a gesture, that the pending
-     * queue does not grow continually.
-     */
-    @SmallTest
-    @Feature({"Gestures"})
-    public void testHasTouchEventHandlersChangesInGesture() {
-        final long downTime = SystemClock.uptimeMillis();
-        final long eventTime = SystemClock.uptimeMillis();
-
-        mGestureHandler = new ContentViewGestureHandler(
-                getInstrumentation().getTargetContext(), new MockMotionEventDelegate(),
-                mMockZoomManager);
-        mLongPressDetector = new LongPressDetector(
-                getInstrumentation().getTargetContext(), mGestureHandler);
-
-        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertFalse("Should not have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 5, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X * 5, FAKE_COORD_Y * 5, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        mGestureHandler.hasTouchEventHandlers(true);
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X * 10, FAKE_COORD_Y * 10, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 15, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X * 15, FAKE_COORD_Y * 15, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.LONG_TAP));
     }
 
     /**
@@ -1512,255 +979,186 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         final long downTime = SystemClock.uptimeMillis();
         final long eventTime = SystemClock.uptimeMillis();
 
-        GestureRecordingMotionEventDelegate mockDelegate =
-                new GestureRecordingMotionEventDelegate();
-        mGestureHandler = new ContentViewGestureHandler(
-                getInstrumentation().getTargetContext(), mockDelegate, mMockZoomManager);
-        mLongPressDetector = mGestureHandler.getLongPressDetector();
-
-        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertTrue("Should have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                setUp();
+                mGestureHandler = new ContentViewGestureHandler(
+                        getInstrumentation().getTargetContext(), mMockMotionEventDelegate);
+                MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
+                assertTrue(mGestureHandler.onTouchEvent(event));
+            }
+        });
 
-        mLongPressDetector.sendLongPressGestureForTest();
+        assertTrue(mMockMotionEventDelegate.mLongPressCalled.await(
+                ScalableTimeout.scaleTimeout(ViewConfiguration.getLongPressTimeout()
+                        + ViewConfiguration.getTapTimeout() + 10),
+                TimeUnit.MILLISECONDS));
 
         assertEquals("A LONG_PRESS gesture should have been sent",
-                ContentViewGestureHandler.GESTURE_LONG_PRESS,
-                        mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.LONG_PRESS,
+                        mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
 
-        event = motionEvent(MotionEvent.ACTION_UP, downTime, eventTime + 1000);
-        assertTrue(mGestureHandler.onTouchEvent(event));
+        MotionEvent event = motionEvent(MotionEvent.ACTION_UP, downTime, eventTime + 1000);
+        mGestureHandler.onTouchEvent(event);
         assertEquals("A LONG_TAP gesture should have been sent",
-                ContentViewGestureHandler.GESTURE_LONG_TAP,
-                        mockDelegate.mMostRecentGestureEvent.mType);
-    }
-
-    /**
-     * Verify that the touch slop region is removed from the first scroll delta to avoid a jump when
-     * starting to scroll.
-     * @throws Exception
-     */
-    @SmallTest
-    @Feature({"Gestures"})
-    public void testTouchSlopRemovedFromScroll() throws Exception {
-        Context context = getInstrumentation().getTargetContext();
-        final long downTime = SystemClock.uptimeMillis();
-        final long eventTime = SystemClock.uptimeMillis();
-        final int scaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
-        final int scrollDelta = 5;
-
-        GestureRecordingMotionEventDelegate mockDelegate =
-                new GestureRecordingMotionEventDelegate();
-        mGestureHandler = new ContentViewGestureHandler(
-                context, mockDelegate, mMockZoomManager);
-
-        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X, FAKE_COORD_Y + scaledTouchSlop + scrollDelta, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-
-        assertEquals("We should have started scrolling",
-                ContentViewGestureHandler.GESTURE_SCROLL_BY,
-                mockDelegate.mMostRecentGestureEvent.mType);
-
-        GestureRecordingMotionEventDelegate.GestureEvent gestureEvent =
-                mockDelegate.getMostRecentGestureEvent();
-        assertNotNull(gestureEvent);
-        Bundle extraParams = gestureEvent.getExtraParams();
-        assertEquals(0, extraParams.getInt(ContentViewGestureHandler.DISTANCE_X));
-        assertEquals(-scrollDelta, extraParams.getInt(ContentViewGestureHandler.DISTANCE_Y));
+                GestureEventType.LONG_TAP,
+                        mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
     }
 
     /**
-     * Verify that touch moves are deferred if they are within the touch slop region
-     * and the touch sequence is not being consumed.
+     * Verify that a LONG_PRESS gesture does not prevent further scrolling.
+     *
      * @throws Exception
      */
     @SmallTest
     @Feature({"Gestures"})
-    public void testTouchMoveWithinTouchSlopDeferred() throws Exception {
-        Context context = getInstrumentation().getTargetContext();
+    public void testGestureLongPressDoesNotPreventScrolling() throws Exception {
         final long downTime = SystemClock.uptimeMillis();
         final long eventTime = SystemClock.uptimeMillis();
-        final int scaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
-        final int lessThanSlopScrollDelta = scaledTouchSlop / 2;
-        final int greaterThanSlopScrollDelta = scaledTouchSlop * 2;
 
-        mGestureHandler.hasTouchEventHandlers(true);
-
-        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals("The touch down should have been forwarded",
-                TouchPoint.TOUCH_EVENT_TYPE_START, mMockMotionEventDelegate.mLastTouchAction);
-        assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X, FAKE_COORD_Y + lessThanSlopScrollDelta, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-        assertEquals("The less-than-slop touch move should not have been forwarded",
-                TouchPoint.TOUCH_EVENT_TYPE_START, mMockMotionEventDelegate.mLastTouchAction);
-        assertEquals(0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X, FAKE_COORD_Y + greaterThanSlopScrollDelta, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals("The touch move should have been forwarded",
-                TouchPoint.TOUCH_EVENT_TYPE_MOVE, mMockMotionEventDelegate.mLastTouchAction);
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-        assertEquals(0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-    }
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                setUp();
+                mGestureHandler = new ContentViewGestureHandler(
+                        getInstrumentation().getTargetContext(), mMockMotionEventDelegate);
+                MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
+                assertTrue(mGestureHandler.onTouchEvent(event));
+            }
+        });
 
-    /**
-     * Verify that touch moves are not deferred even if they are within the touch slop region
-     * when the touch sequence is being consumed.
-     * @throws Exception
-     */
-    @SmallTest
-    @Feature({"Gestures"})
-    public void testTouchMoveWithinTouchSlopNotDeferredIfJavascriptConsumingGesture()
-            throws Exception {
-        Context context = getInstrumentation().getTargetContext();
-        final long downTime = SystemClock.uptimeMillis();
-        final long eventTime = SystemClock.uptimeMillis();
-        final int scaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
-        final int lessThanSlopScrollDelta = scaledTouchSlop / 2;
+        final long longPressTimeoutMs = ViewConfiguration.getLongPressTimeout()
+                + ViewConfiguration.getTapTimeout() + 10;
+        assertTrue(mMockMotionEventDelegate.mLongPressCalled.await(
+                ScalableTimeout.scaleTimeout(longPressTimeoutMs), TimeUnit.MILLISECONDS));
 
-        mGestureHandler.hasTouchEventHandlers(true);
+        assertEquals("A LONG_PRESS gesture should have been sent",
+                GestureEventType.LONG_PRESS,
+                        mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
 
-        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals("The touch down should have been forwarded",
-                TouchPoint.TOUCH_EVENT_TYPE_START, mMockMotionEventDelegate.mLastTouchAction);
-        assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
+        MotionEvent event = MotionEvent.obtain(
+                downTime, eventTime + longPressTimeoutMs, MotionEvent.ACTION_MOVE,
+                FAKE_COORD_X + 100, FAKE_COORD_Y + 100, 0);
+        mGestureHandler.onTouchEvent(event);
 
-        event = MotionEvent.obtain(
-                downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X, FAKE_COORD_Y + lessThanSlopScrollDelta, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
+        assertEquals("Scrolling should have started",
+                GestureEventType.SCROLL_BY,
+                        mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
+        assertTrue(mMockMotionEventDelegate.mGestureTypeList.contains(
+                GestureEventType.SCROLL_START));
+        assertTrue(mMockMotionEventDelegate.mGestureTypeList.contains(
+                GestureEventType.TAP_CANCEL));
 
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_CONSUMED);
-        assertEquals("The less-than-slop touch move should have been forwarded",
-                TouchPoint.TOUCH_EVENT_TYPE_MOVE, mMockMotionEventDelegate.mLastTouchAction);
+        event = motionEvent(MotionEvent.ACTION_UP, downTime, eventTime + longPressTimeoutMs);
+        mGestureHandler.onTouchEvent(event);
+        assertFalse("Scrolling should have prevented the LONG_TAP",
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.LONG_TAP));
     }
 
-
     /**
-     * Verify that touch moves are not deferred when the MotionEvent has multiple active pointers.
+     * Verify that LONG_PRESS is not fired during a double-tap sequence.
+     *
      * @throws Exception
      */
     @SmallTest
     @Feature({"Gestures"})
-    public void testTouchMoveNotDeferredWithMultiplePointers()
-            throws Exception {
-        Context context = getInstrumentation().getTargetContext();
+    public void testNoGestureLongPressDuringDoubleTap() throws Exception {
         final long downTime = SystemClock.uptimeMillis();
         final long eventTime = SystemClock.uptimeMillis();
-        final int scaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
-        final int lessThanSlopScrollDelta = scaledTouchSlop / 2;
-
-        mGestureHandler.hasTouchEventHandlers(true);
-
-        final int secondaryCoordX = FAKE_COORD_X + 10 * scaledTouchSlop;
-        final int secondaryCoordY = FAKE_COORD_Y + 10 * scaledTouchSlop;
-
-        PointerProperties pp0 = new PointerProperties();
-        pp0.id = 0;
-        pp0.toolType = MotionEvent.TOOL_TYPE_FINGER;
-        PointerProperties pp1 = new PointerProperties();
-        pp1.id = 1;
-        pp1.toolType = MotionEvent.TOOL_TYPE_FINGER;
 
-        PointerCoords pc0 = new PointerCoords();
-        pc0.x = FAKE_COORD_X;
-        pc0.y = FAKE_COORD_Y;
-        pc0.pressure = 1;
-        pc0.size = 1;
-        PointerCoords pc1 = new PointerCoords();
-        pc1.x = secondaryCoordX;
-        pc1.y = secondaryCoordY;
-        pc1.pressure = 1;
-        pc1.size = 1;
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                setUp();
+                mGestureHandler.updateDoubleTapSupport(true);
 
-        MotionEvent event = MotionEvent.obtain(
-                eventTime, eventTime, MotionEvent.ACTION_DOWN,
-                1, new PointerProperties[] { pp0 }, new PointerCoords[] { pc0 },
-                0, 0, 1.0f, 1.0f, 0, 0, 0, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertEquals("The touch down should have been forwarded",
-                TouchPoint.TOUCH_EVENT_TYPE_START, mMockMotionEventDelegate.mLastTouchAction);
+                MotionEvent event = MotionEvent.obtain(
+                        downTime, eventTime, MotionEvent.ACTION_DOWN,
+                        FAKE_COORD_X, FAKE_COORD_Y, 0);
+                assertTrue(mGestureHandler.onTouchEvent(event));
 
-        event = MotionEvent.obtain(
-                eventTime, eventTime, MotionEvent.ACTION_POINTER_DOWN,
-                2, new PointerProperties[] { pp0, pp1 }, new PointerCoords[] { pc0, pc1 },
-                0, 0, 1.0f, 1.0f, 0, 0, 0, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
+                event = MotionEvent.obtain(
+                        downTime, eventTime + 1, MotionEvent.ACTION_UP,
+                        FAKE_COORD_X, FAKE_COORD_Y, 0);
+                mGestureHandler.onTouchEvent(event);
+                assertEquals("A GESTURE_SINGLE_TAP_UNCONFIRMED event should have been sent",
+                        GestureEventType.SINGLE_TAP_UNCONFIRMED,
+                        mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
 
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-        assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertEquals("The secondary touch down should have been forwarded",
-                TouchPoint.TOUCH_EVENT_TYPE_START, mMockMotionEventDelegate.mLastTouchAction);
+                event = MotionEvent.obtain(
+                        downTime + 2, eventTime + 2, MotionEvent.ACTION_DOWN,
+                        FAKE_COORD_X, FAKE_COORD_Y, 0);
+                assertTrue(mGestureHandler.onTouchEvent(event));
+                assertEquals("A GESTURE_TAP_DOWN event should have been sent ",
+                        GestureEventType.TAP_DOWN,
+                        mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
+                assertTrue(mGestureHandler.isDoubleTapActive());
+            }
+        });
 
-        pc1.x = secondaryCoordX + lessThanSlopScrollDelta;
-        pc1.y = secondaryCoordY + lessThanSlopScrollDelta;
+        final int longPressTimeoutMs = ViewConfiguration.getLongPressTimeout()
+                + ViewConfiguration.getTapTimeout() + 10;
 
-        event = MotionEvent.obtain(
-                eventTime, eventTime, MotionEvent.ACTION_MOVE,
-                2, new PointerProperties[] { pp0, pp1 }, new PointerCoords[] { pc0, pc1 },
-                0, 0, 1.0f, 1.0f, 0, 0, 0, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
+        assertFalse(mMockMotionEventDelegate.mLongPressCalled.await(
+                longPressTimeoutMs, TimeUnit.MILLISECONDS));
 
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-        assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertEquals("The secondary touch move should have been forwarded",
-                TouchPoint.TOUCH_EVENT_TYPE_MOVE, mMockMotionEventDelegate.mLastTouchAction);
-    }
+        assertFalse("A LONG_PRESS gesture should not have been sent",
+                GestureEventType.LONG_PRESS
+                        == mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
+
+        MotionEvent event = MotionEvent.obtain(
+                downTime + 2, eventTime + longPressTimeoutMs, MotionEvent.ACTION_MOVE,
+                FAKE_COORD_X + 20, FAKE_COORD_Y + 20, 0);
+        assertTrue(mGestureHandler.onTouchEvent(event));
+        assertEquals("A double tap drag should have started",
+                GestureEventType.PINCH_BEGIN,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
+        assertTrue(mGestureHandler.isDoubleTapActive());
 
-    private static void sendLastScrollByEvent(ContentViewGestureHandler handler) {
-        final long downTime = SystemClock.uptimeMillis();
-        final long eventTime = SystemClock.uptimeMillis();
-        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
-        assertTrue(handler.onTouchEvent(event));
         event = MotionEvent.obtain(
-                downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X, FAKE_COORD_Y + 30, 0);
-        assertTrue(handler.onTouchEvent(event));
+                downTime + 2, eventTime + longPressTimeoutMs, MotionEvent.ACTION_UP,
+                FAKE_COORD_X, FAKE_COORD_Y + 1, 0);
+        assertTrue(mGestureHandler.onTouchEvent(event));
+        assertEquals("A double tap drag should have ended",
+                GestureEventType.SCROLL_END,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
+        assertFalse(mGestureHandler.isDoubleTapActive());
     }
 
-    private static void sendLastZoomEvent(
-            ContentViewGestureHandler handler, MockZoomManager zoomManager) {
-        zoomManager.pinchOnMoveEvents(handler);
+    /**
+     * Verify that the touch slop region is removed from the first scroll delta to avoid a jump when
+     * starting to scroll.
+     * @throws Exception
+     */
+    @SmallTest
+    @Feature({"Gestures"})
+    public void testTouchSlopRemovedFromScroll() throws Exception {
+        Context context = getInstrumentation().getTargetContext();
         final long downTime = SystemClock.uptimeMillis();
         final long eventTime = SystemClock.uptimeMillis();
+        final int scaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+        final int scrollDelta = 5;
+
         MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
-        assertTrue(handler.onTouchEvent(event));
+        assertTrue(mGestureHandler.onTouchEvent(event));
+
         event = MotionEvent.obtain(
                 downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X, FAKE_COORD_Y + 30, 0);
-        assertTrue(handler.onTouchEvent(event));
-    }
+                FAKE_COORD_X, FAKE_COORD_Y + scaledTouchSlop + scrollDelta, 0);
+        assertTrue(mGestureHandler.onTouchEvent(event));
 
-    private static void sendLastPinchEvent(ContentViewGestureHandler handler) {
-        final long downTime = SystemClock.uptimeMillis();
-        final long eventTime = SystemClock.uptimeMillis();
-        handler.pinchBegin(downTime, FAKE_COORD_X, FAKE_COORD_Y);
-        handler.pinchBy(eventTime + 10, FAKE_COORD_X, FAKE_COORD_Y, 2);
+        assertEquals("We should have started scrolling",
+                GestureEventType.SCROLL_BY,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
+
+        MockMotionEventDelegate.GestureEvent gestureEvent =
+                mMockMotionEventDelegate.mMostRecentGestureEvent;
+        assertNotNull(gestureEvent);
+        Bundle extraParams = gestureEvent.getExtraParams();
+        assertEquals(0, extraParams.getInt(ContentViewGestureHandler.DISTANCE_X));
+        assertEquals(-scrollDelta, extraParams.getInt(ContentViewGestureHandler.DISTANCE_Y));
     }
 
     /**
@@ -1775,25 +1173,19 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         final long downTime = SystemClock.uptimeMillis();
         final long eventTime = SystemClock.uptimeMillis();
 
-        GestureRecordingMotionEventDelegate mockDelegate =
-                new GestureRecordingMotionEventDelegate();
-        mGestureHandler = new ContentViewGestureHandler(
-                getInstrumentation().getTargetContext(), mockDelegate, mMockZoomManager);
-
         MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertEquals("A TAP_DOWN gesture should have been sent",
-                ContentViewGestureHandler.GESTURE_TAP_DOWN,
-                        mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.TAP_DOWN,
+                        mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
 
         event = motionEvent(MotionEvent.ACTION_UP, downTime, eventTime + 10);
         assertFalse(mGestureHandler.onTouchEvent(event));
         assertEquals("A GESTURE_SINGLE_TAP_UNCONFIRMED gesture should have been sent",
-                ContentViewGestureHandler.GESTURE_SINGLE_TAP_UNCONFIRMED,
-                        mockDelegate.mMostRecentGestureEvent.mType);
-
-        assertTrue("Should not have confirmed a single tap yet",
-                mMockListener.mLastSingleTap == null);
+                GestureEventType.SINGLE_TAP_UNCONFIRMED,
+                        mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
+        assertFalse(mMockMotionEventDelegate.mGestureTypeList.contains(
+                GestureEventType.SINGLE_TAP_CONFIRMED));
     }
 
     /**
@@ -1807,27 +1199,22 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         long downTime = SystemClock.uptimeMillis();
         long eventTime = SystemClock.uptimeMillis();
 
-        GestureRecordingMotionEventDelegate mockDelegate =
-                new GestureRecordingMotionEventDelegate();
-        mGestureHandler = new ContentViewGestureHandler(
-                getInstrumentation().getTargetContext(), mockDelegate, mMockZoomManager);
-
         MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
         assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(ContentViewGestureHandler.GESTURE_TAP_DOWN,
-                mockDelegate.mMostRecentGestureEvent.mType);
+        assertEquals(GestureEventType.TAP_DOWN,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertTrue(mGestureHandler.needsTapEndingEventForTesting());
         event = motionEvent(MotionEvent.ACTION_UP, downTime, eventTime + 5);
-        assertFalse(mGestureHandler.onTouchEvent(event));
-        assertEquals(ContentViewGestureHandler.GESTURE_SINGLE_TAP_UNCONFIRMED,
-                mockDelegate.mMostRecentGestureEvent.mType);
+        mGestureHandler.onTouchEvent(event);
+        assertEquals(GestureEventType.SINGLE_TAP_UNCONFIRMED,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertTrue("An unconfirmed tap does not terminate the tap down.",
                 mGestureHandler.needsTapEndingEventForTesting());
 
         // A confirmed tap is a tap-ending event.
         downTime += 20;
         eventTime += 20;
-        mockDelegate.mGestureTypeList.clear();
+        mMockMotionEventDelegate.mGestureTypeList.clear();
         mGestureHandler.updateShouldDisableDoubleTap(true);
         event = MotionEvent.obtain(
                 downTime, downTime, MotionEvent.ACTION_DOWN,
@@ -1838,15 +1225,15 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
                 downTime, eventTime + 5, MotionEvent.ACTION_UP,
                 FAKE_COORD_X, FAKE_COORD_Y, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(ContentViewGestureHandler.GESTURE_SINGLE_TAP_CONFIRMED,
-                mockDelegate.mMostRecentGestureEvent.mType);
+        assertEquals(GestureEventType.SINGLE_TAP_CONFIRMED,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertFalse("A confirmed single tap should terminate the tap down.",
                 mGestureHandler.needsTapEndingEventForTesting());
 
         // A double tap gesture is a tap-ending event.
         downTime += 20;
         eventTime += 20;
-        mockDelegate.mGestureTypeList.clear();
+        mMockMotionEventDelegate.mGestureTypeList.clear();
         mGestureHandler.updateShouldDisableDoubleTap(false);
         event = MotionEvent.obtain(
                 downTime, downTime, MotionEvent.ACTION_DOWN,
@@ -1865,15 +1252,15 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
                 eventTime + 10, eventTime + 15, MotionEvent.ACTION_UP,
                 FAKE_COORD_X, FAKE_COORD_Y, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(ContentViewGestureHandler.GESTURE_DOUBLE_TAP,
-                mockDelegate.mMostRecentGestureEvent.mType);
+        assertEquals(GestureEventType.DOUBLE_TAP,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertFalse("A double tap should terminate the tap down.",
                 mGestureHandler.needsTapEndingEventForTesting());
 
         // A double tap drag gesture will trigger a tap-ending event.
         downTime += 20;
         eventTime += 20;
-        mockDelegate.mGestureTypeList.clear();
+        mMockMotionEventDelegate.mGestureTypeList.clear();
         mGestureHandler.updateShouldDisableDoubleTap(false);
         event = MotionEvent.obtain(
                 downTime, downTime, MotionEvent.ACTION_DOWN,
@@ -1894,10 +1281,10 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertFalse("A double tap drag should terminate the tap down.",
                 mGestureHandler.needsTapEndingEventForTesting());
-        assertTrue(mockDelegate.mGestureTypeList.contains(
-                ContentViewGestureHandler.GESTURE_SCROLL_START));
-        assertTrue(mockDelegate.mGestureTypeList.contains(
-                ContentViewGestureHandler.GESTURE_TAP_CANCEL));
+        assertTrue(mMockMotionEventDelegate.mGestureTypeList.contains(
+                GestureEventType.SCROLL_START));
+        assertTrue(mMockMotionEventDelegate.mGestureTypeList.contains(
+                GestureEventType.TAP_CANCEL));
         event = MotionEvent.obtain(
                 eventTime + 10, eventTime + 20, MotionEvent.ACTION_UP,
                 FAKE_COORD_X, FAKE_COORD_Y, 0);
@@ -1907,7 +1294,7 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         // A scroll event will trigger a tap-ending (cancel) event.
         downTime += 25;
         eventTime += 25;
-        mockDelegate.mGestureTypeList.clear();
+        mMockMotionEventDelegate.mGestureTypeList.clear();
         event = MotionEvent.obtain(
                 downTime, downTime, MotionEvent.ACTION_DOWN,
                 FAKE_COORD_X, FAKE_COORD_Y, 0);
@@ -1917,143 +1304,16 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
                 downTime, eventTime + 5, MotionEvent.ACTION_MOVE,
                 FAKE_COORD_X, FAKE_COORD_Y + 100, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
-        assertTrue(mockDelegate.mGestureTypeList.contains(
-                ContentViewGestureHandler.GESTURE_SCROLL_START));
-        assertTrue(mockDelegate.mGestureTypeList.contains(
-                ContentViewGestureHandler.GESTURE_TAP_CANCEL));
+        assertTrue(mMockMotionEventDelegate.mGestureTypeList.contains(
+                GestureEventType.SCROLL_START));
+        assertTrue(mMockMotionEventDelegate.mGestureTypeList.contains(
+                GestureEventType.TAP_CANCEL));
         assertFalse("A scroll should terminate the tap down.",
                    mGestureHandler.needsTapEndingEventForTesting());
         assertFalse(mGestureHandler.needsTapEndingEventForTesting());
     }
 
     /**
-     * Verify that touch move events are properly coalesced.
-     * @throws Exception
-     */
-    @SmallTest
-    @Feature({"Gestures"})
-    public void testTouchMoveCoalescing() throws Exception {
-        final long downTime = SystemClock.uptimeMillis();
-        final long eventTime = SystemClock.uptimeMillis();
-
-        mGestureHandler.hasTouchEventHandlers(true);
-
-        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        mGestureHandler.confirmTouchEvent(ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_CONSUMED);
-        assertEquals(TouchPoint.TOUCH_EVENT_TYPE_START, mMockMotionEventDelegate.mLastTouchAction);
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 5, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X * 5, FAKE_COORD_Y * 5, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertFalse("Should not have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
-        assertEquals("Initial move events should offered to javascript and added to the queue",
-                1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertEquals(TouchPoint.TOUCH_EVENT_TYPE_MOVE, mMockMotionEventDelegate.mLastTouchAction);
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X * 10, FAKE_COORD_Y * 10, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals("Move events already sent to javascript should not be coalesced",
-                2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 15, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X * 15, FAKE_COORD_Y * 15, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals("Similar pending move events should be coalesced",
-                2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        PointerProperties pp1 = new PointerProperties();
-        pp1.id = 0;
-        pp1.toolType = MotionEvent.TOOL_TYPE_FINGER;
-        PointerProperties pp2 = new PointerProperties();
-        pp2.id = 1;
-        pp2.toolType = MotionEvent.TOOL_TYPE_FINGER;
-        PointerProperties[] properties = new PointerProperties[] { pp1, pp2 };
-
-        PointerCoords pc1 = new PointerCoords();
-        pc1.x = FAKE_COORD_X * 10;
-        pc1.y = FAKE_COORD_Y * 10;
-        pc1.pressure = 1;
-        pc1.size = 1;
-        PointerCoords pc2 = new PointerCoords();
-        pc2.x = FAKE_COORD_X * 15;
-        pc2.y = FAKE_COORD_Y * 15;
-        pc2.pressure = 1;
-        pc2.size = 1;
-        PointerCoords[] coords = new PointerCoords[] { pc1, pc2 };
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 20, MotionEvent.ACTION_MOVE,
-                2, properties, coords, 0, 0, 1.0f, 1.0f, 0, 0, 0, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals("Move events with different pointer counts should not be coalesced",
-                3, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 25, MotionEvent.ACTION_MOVE,
-                2, properties, coords, 0, 0, 1.0f, 1.0f, 0, 0, 0, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals("Move events with similar pointer counts should be coalesced",
-                3, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals("Move events should not be coalesced with other events",
-                4, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-    }
-
-    /**
-     * Verify that synchronous confirmTouchEvent() calls made from the MotionEventDelegate behave
-     * properly.
-     * @throws Exception
-     */
-    @SmallTest
-    @Feature({"Gestures"})
-    public void testSynchronousConfirmTouchEvent() throws Exception {
-        final long downTime = SystemClock.uptimeMillis();
-        final long eventTime = SystemClock.uptimeMillis();
-
-        mGestureHandler.hasTouchEventHandlers(true);
-
-        mMockMotionEventDelegate.disableSynchronousConfirmTouchEvent();
-
-        // Queue an asynchronously handled event.
-        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        // Queue another event; this will remain in the queue until the first event is confirmed.
-        event = MotionEvent.obtain(
-                downTime, eventTime + 5, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X * 10, FAKE_COORD_Y * 10, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        // Enable synchronous event confirmation upon dispatch.
-        mMockMotionEventDelegate.enableSynchronousConfirmTouchEvent(
-                mGestureHandler, ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_CONSUMED);
-
-        // Confirm the original event; this should dispatch the second event and confirm it
-        // synchronously.
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_CONSUMED);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertEquals(TouchPoint.TOUCH_EVENT_TYPE_MOVE, mMockMotionEventDelegate.mLastTouchAction);
-
-        // Adding events to any empty queue will trigger synchronous dispatch and confirmation.
-        event = MotionEvent.obtain(
-                downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X * 5, FAKE_COORD_Y * 5, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-    }
-
-    /**
      * Verify that no double tap gestures are created if the gesture handler is
      * told to disable double tap gesture detection (according to the logic in
      * ContentViewCore.onRenderCoordinatesUpdated).
@@ -2065,10 +1325,6 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         final long downTime = SystemClock.uptimeMillis();
         final long eventTime = SystemClock.uptimeMillis();
 
-        GestureRecordingMotionEventDelegate mockDelegate =
-                new GestureRecordingMotionEventDelegate();
-        mGestureHandler = new ContentViewGestureHandler(
-                getInstrumentation().getTargetContext(), mockDelegate, mMockZoomManager);
         mGestureHandler.updateShouldDisableDoubleTap(true);
 
         MotionEvent event = MotionEvent.obtain(
@@ -2076,18 +1332,18 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
                 FAKE_COORD_X, FAKE_COORD_Y, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertEquals("Only GESTURE_TAP_DOWN should have been sent",
-                1, mockDelegate.mGestureTypeList.size());
+                1, mMockMotionEventDelegate.mGestureTypeList.size());
 
         event = MotionEvent.obtain(
                 downTime, eventTime + 5, MotionEvent.ACTION_UP,
                 FAKE_COORD_X, FAKE_COORD_Y, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertEquals("A GESTURE_SINGLE_TAP_CONFIRMED event should have been sent",
-                ContentViewGestureHandler.GESTURE_SINGLE_TAP_CONFIRMED,
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.SINGLE_TAP_CONFIRMED,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertEquals("Only GESTURE_TAP_DOWN and GESTURE_SINGLE_TAP_CONFIRMED " +
                 "should have been sent",
-                2, mockDelegate.mGestureTypeList.size());
+                2, mMockMotionEventDelegate.mGestureTypeList.size());
 
         event = MotionEvent.obtain(
                 eventTime + 10, eventTime + 10, MotionEvent.ACTION_DOWN,
@@ -2096,20 +1352,20 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         assertEquals("Only GESTURE_TAP_DOWN, " +
                 "GESTURE_SINGLE_TAP_CONFIRMED and " +
                 "GESTURE_TAP_DOWN should have been sent",
-                3, mockDelegate.mGestureTypeList.size());
+                3, mMockMotionEventDelegate.mGestureTypeList.size());
 
         event = MotionEvent.obtain(
                 eventTime + 10, eventTime + 15, MotionEvent.ACTION_UP,
                 FAKE_COORD_X, FAKE_COORD_Y, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertEquals("A double tap should not have occurred",
-                ContentViewGestureHandler.GESTURE_SINGLE_TAP_CONFIRMED,
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.SINGLE_TAP_CONFIRMED,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertEquals("Only GESTURE_TAP_DOWN, " +
                 "GESTURE_SINGLE_TAP_CONFIRMED, " +
                 "GESTURE_TAP_DOWN and " +
                 "GESTURE_SINGLE_TAP_CONFIRMED should have been sent",
-                4, mockDelegate.mGestureTypeList.size());
+                4, mMockMotionEventDelegate.mGestureTypeList.size());
     }
 
     /**
@@ -2125,10 +1381,6 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         final long downTime1 = SystemClock.uptimeMillis();
         final long downTime2 = downTime1 + 100;
 
-        GestureRecordingMotionEventDelegate mockDelegate =
-                new GestureRecordingMotionEventDelegate();
-        mGestureHandler = new ContentViewGestureHandler(
-                getInstrumentation().getTargetContext(), mockDelegate, mMockZoomManager);
         mGestureHandler.updateShouldDisableDoubleTap(true);
 
         MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime1, downTime1);
@@ -2152,33 +1404,33 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         // disabled.
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertTrue("GESTURE_SCROLL_START should have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_SCROLL_START));
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.SCROLL_START));
         assertFalse("No GESTURE_PINCH_BEGIN should have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_PINCH_BEGIN));
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.PINCH_BEGIN));
 
         event = MotionEvent.obtain(
                 downTime2, downTime2 + 10, MotionEvent.ACTION_MOVE,
                 FAKE_COORD_X, FAKE_COORD_Y + 200, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertEquals("GESTURE_SCROLL_BY should have been sent",
-                ContentViewGestureHandler.GESTURE_SCROLL_BY,
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.SCROLL_BY,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         assertEquals("GESTURE_SCROLL_BY should have been sent",
                 event.getEventTime(),
-                mockDelegate.mMostRecentGestureEvent.getTimeMs());
+                mMockMotionEventDelegate.mMostRecentGestureEvent.getTimeMs());
         assertTrue("No GESTURE_PINCH_BY should have been sent",
-                ContentViewGestureHandler.GESTURE_PINCH_BY !=
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.PINCH_BY !=
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
 
         event = MotionEvent.obtain(
                 downTime2, downTime2 + 15, MotionEvent.ACTION_UP,
                 FAKE_COORD_X, FAKE_COORD_Y + 200, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertFalse("No GESTURE_PINCH_END should have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_PINCH_END));
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.PINCH_END));
     }
 
     /**
@@ -2192,13 +1444,6 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
         long downTime1 = SystemClock.uptimeMillis();
         long downTime2 = downTime1 + 100;
 
-        GestureRecordingMotionEventDelegate mockDelegate =
-                new GestureRecordingMotionEventDelegate();
-        mGestureHandler = new ContentViewGestureHandler(
-                getInstrumentation().getTargetContext(), mockDelegate, mMockZoomManager);
-        mLongPressDetector = new LongPressDetector(
-                getInstrumentation().getTargetContext(), mGestureHandler);
-
         // Start a double-tap drag gesture.
         MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime1, downTime1);
         assertTrue(mGestureHandler.onTouchEvent(event));
@@ -2216,11 +1461,11 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
                 FAKE_COORD_X, FAKE_COORD_Y + 100, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertTrue("GESTURE_SCROLL_START should have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_SCROLL_START));
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.SCROLL_START));
         assertEquals("GESTURE_PINCH_BEGIN should have been sent",
-                ContentViewGestureHandler.GESTURE_PINCH_BEGIN,
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.PINCH_BEGIN,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
 
         // Simulate setting a fixed page scale (or a mobile viewport);
         // this should not disrupt the current double-tap gesture.
@@ -2232,25 +1477,25 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
                 FAKE_COORD_X, FAKE_COORD_Y + 200, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertTrue("GESTURE_SCROLL_BY should have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_SCROLL_BY));
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.SCROLL_BY));
         assertEquals("GESTURE_PINCH_BY should have been sent",
-                ContentViewGestureHandler.GESTURE_PINCH_BY,
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.PINCH_BY,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
         event = MotionEvent.obtain(
                 downTime2, downTime2 + 15, MotionEvent.ACTION_UP,
                 FAKE_COORD_X, FAKE_COORD_Y + 200, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertTrue("GESTURE_PINCH_END should have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_PINCH_END));
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.PINCH_END));
         assertEquals("GESTURE_SCROLL_END should have been sent",
-                ContentViewGestureHandler.GESTURE_SCROLL_END,
-                mockDelegate.mMostRecentGestureEvent.mType);
+                GestureEventType.SCROLL_END,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
 
         // The double-tap gesture has finished, but the page scale is fixed.
         // The same event sequence should not generate any double tap getsures.
-        mockDelegate.mGestureTypeList.clear();
+        mMockMotionEventDelegate.mGestureTypeList.clear();
         downTime1 += 200;
         downTime2 += 200;
 
@@ -2270,11 +1515,11 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
                 FAKE_COORD_X, FAKE_COORD_Y + 100, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertTrue("GESTURE_SCROLL_START should have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_SCROLL_START));
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.SCROLL_START));
         assertFalse("GESTURE_PINCH_BEGIN should not have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_PINCH_BEGIN));
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.PINCH_BEGIN));
 
         // Double tap zoom updates should not be sent.
         // Instead, the second tap drag becomes a scroll gesture sequence.
@@ -2283,284 +1528,204 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
                 FAKE_COORD_X, FAKE_COORD_Y + 200, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertTrue("GESTURE_SCROLL_BY should have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_SCROLL_BY));
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.SCROLL_BY));
         assertFalse("GESTURE_PINCH_BY should not have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_PINCH_BY));
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.PINCH_BY));
         event = MotionEvent.obtain(
                 downTime2, downTime2 + 15, MotionEvent.ACTION_UP,
                 FAKE_COORD_X, FAKE_COORD_Y + 200, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
         assertFalse("GESTURE_PINCH_END should not have been sent",
-                mockDelegate.mGestureTypeList.contains(
-                        ContentViewGestureHandler.GESTURE_PINCH_END));
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.PINCH_END));
     }
 
     /**
-     * Verify that a secondary pointer press with no consumer does not interfere
-     * with Javascript touch handling.
-     *
+     * Verify that pinch zoom sends the proper event sequence.
      * @throws Exception
      */
     @SmallTest
     @Feature({"Gestures"})
-    public void testSecondaryPointerWithNoConsumer() throws Exception {
+    public void testPinchZoom() throws Exception {
         final long downTime = SystemClock.uptimeMillis();
         final long eventTime = SystemClock.uptimeMillis();
+        final Context context = getInstrumentation().getTargetContext();
+        final int scaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
 
-        mGestureHandler.hasTouchEventHandlers(true);
-
-        // Queue a primary pointer press, a secondary pointer press and release,
-        // and a primary pointer move.
-        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        event = motionEvent(MotionEvent.ACTION_POINTER_DOWN, downTime, eventTime);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        event = motionEvent(MotionEvent.ACTION_POINTER_UP, downTime, eventTime + 10);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(3, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        event = MotionEvent.obtain(
-                downTime, eventTime + 15, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X * 5, FAKE_COORD_Y * 5, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(4, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        // Simulate preventDefault from Javascript, forcing all touch events to Javascript
-        // for the current sequence.
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_CONSUMED);
-        assertEquals(3, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
-        assertEquals("Even if the secondary pointer has no consumer, continue sending events",
-                2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
-        assertEquals("Even if the secondary pointer has no consumer, continue sending events",
-                1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-        assertEquals(0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
+        mGestureHandler.updateMultiTouchSupport(true);
 
-        assertEquals("No gestures should result from the Javascript-consumed sequence",
-                0, mMockMotionEventDelegate.mTotalSentGestureCount);
-    }
+        final int secondaryCoordX = FAKE_COORD_X + 20 * scaledTouchSlop;
+        final int secondaryCoordY = FAKE_COORD_Y + 20 * scaledTouchSlop;
 
-    /**
-     * Verify that multiple touch sequences in the queue are handled properly when
-     * the Javascript response is different for each.
-     *
-     * @throws Exception
-     */
-    @SmallTest
-    @Feature({"Gestures"})
-    public void testMultiplyEnqueuedTouches() throws Exception {
-        final long downTime = SystemClock.uptimeMillis();
-        final long eventTime = SystemClock.uptimeMillis();
+        PointerProperties pp0 = new PointerProperties();
+        pp0.id = 0;
+        pp0.toolType = MotionEvent.TOOL_TYPE_FINGER;
+        PointerProperties pp1 = new PointerProperties();
+        pp1.id = 1;
+        pp1.toolType = MotionEvent.TOOL_TYPE_FINGER;
 
-        mGestureHandler.hasTouchEventHandlers(true);
-        mGestureHandler.updateDoubleTapSupport(false);
+        PointerCoords pc0 = new PointerCoords();
+        pc0.x = FAKE_COORD_X;
+        pc0.y = FAKE_COORD_Y;
+        pc0.pressure = 1;
+        pc0.size = 1;
+        PointerCoords pc1 = new PointerCoords();
+        pc1.x = secondaryCoordX;
+        pc1.y = secondaryCoordY;
+        pc1.pressure = 1;
+        pc1.size = 1;
 
-        // Queue a tap sequence.
-        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
+        MotionEvent event = MotionEvent.obtain(
+                eventTime, eventTime, MotionEvent.ACTION_DOWN,
+                1, new PointerProperties[] { pp0 }, new PointerCoords[] { pc0 },
+                0, 0, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_CLASS_POINTER, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
+        assertEquals(GestureEventType.TAP_DOWN,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
+        assertEquals("Only GESTURE_TAP_DOWN should have been sent",
+                1, mMockMotionEventDelegate.mGestureTypeList.size());
 
-        event = motionEvent(MotionEvent.ACTION_UP, downTime, eventTime + 5);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
+        event = MotionEvent.obtain(
+                eventTime, eventTime, MotionEvent.ACTION_POINTER_DOWN,
+                2, new PointerProperties[] { pp1, pp0 }, new PointerCoords[] { pc1, pc0 },
+                0, 0, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_CLASS_POINTER, 0);
+        mGestureHandler.onTouchEvent(event);
+        assertEquals("No additional gestures should be triggered on a secondary pointer press",
+                1, mMockMotionEventDelegate.mGestureTypeList.size());
 
-        // Queue a scroll sequence.
-        event = motionEvent(MotionEvent.ACTION_DOWN, downTime + 10, downTime + 10);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(3, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
+        pc1.x = secondaryCoordX + 5 * scaledTouchSlop;
+        pc1.y = secondaryCoordY + 5 * scaledTouchSlop;
 
         event = MotionEvent.obtain(
-                downTime + 10, eventTime + 15, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X * 5, FAKE_COORD_Y * 5, 0);
+                eventTime, eventTime + 10, MotionEvent.ACTION_MOVE,
+                2, new PointerProperties[] { pp1, pp0 }, new PointerCoords[] { pc1, pc0 },
+                0, 0, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_CLASS_POINTER, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
-        assertFalse(mGestureHandler.isNativeScrolling());
-        assertEquals(4, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
+        assertEquals("Only GESTURE_TAP_DOWN, " +
+                "GESTURE_TAP_CANCEL, " +
+                "GESTURE_SCROLL_BEGIN, " +
+                "GESTURE_PINCH_BEGIN, " +
+                "GESTURE_SCROLL_BY, and " +
+                "GESTURE_PINCH_BY should have been sent",
+                6, mMockMotionEventDelegate.mGestureTypeList.size());
+        assertTrue(mMockMotionEventDelegate.mGestureTypeList.contains(
+                GestureEventType.PINCH_BEGIN));
+        assertTrue(mMockMotionEventDelegate.mGestureTypeList.contains(
+                GestureEventType.SCROLL_START));
+        assertTrue(mMockMotionEventDelegate.mGestureTypeList.contains(
+                GestureEventType.PINCH_BY));
+        assertTrue(mMockMotionEventDelegate.mGestureTypeList.contains(
+                GestureEventType.SCROLL_BY));
 
-        event = motionEvent(MotionEvent.ACTION_UP, downTime + 10, downTime + 20);
+        event = MotionEvent.obtain(
+                eventTime, eventTime + 10, MotionEvent.ACTION_POINTER_UP,
+                2, new PointerProperties[] { pp1, pp0 }, new PointerCoords[] { pc1, pc0 },
+                0, 0, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_CLASS_POINTER, 0);
         assertTrue(mGestureHandler.onTouchEvent(event));
-        assertEquals(5, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        // Consume the first gesture.
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_CONSUMED);
-        assertEquals(4, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_CONSUMED);
-        assertEquals(3, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        // Don't consume the second gesture; it should be fed to the gesture detector.
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-        assertEquals(2, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertEquals("The down touch event should have been sent to the gesture detector",
-                MotionEvent.ACTION_DOWN, mMockGestureDetector.mLastEvent.getActionMasked());
-        assertFalse(mGestureHandler.isNativeScrolling());
-
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-        assertEquals("The move touch event should have been sent to the gesture detector",
-                MotionEvent.ACTION_MOVE, mMockGestureDetector.mLastEvent.getActionMasked());
-    }
-
-    /**
-     * Verify that only complete gestures are forwarded to Javascript if we receive
-     * a touch handler notification.
-     * @throws Exception
-     */
-    @SmallTest
-    @Feature({"Gestures"})
-    public void testOnlyCompleteGesturesForwardedToTouchHandler() throws Exception {
-        final long downTime = SystemClock.uptimeMillis();
-        final long eventTime = SystemClock.uptimeMillis();
-
-        mGestureHandler.hasTouchEventHandlers(false);
-
-        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
-        mGestureHandler.onTouchEvent(event);
-        assertEquals("Initial down events should not be sent to Javascript without a touch handler",
-                0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertTrue("Should have a pending gesture", mMockGestureDetector.mLastEvent != null);
-        mMockGestureDetector.mLastEvent = null;
-
-        mGestureHandler.hasTouchEventHandlers(true);
+        assertEquals(GestureEventType.PINCH_END,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
+        assertEquals("Only GESTURE_PINCH_END should have been sent",
+                7, mMockMotionEventDelegate.mGestureTypeList.size());
 
         event = MotionEvent.obtain(
-                downTime, eventTime + 5, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X * 5, FAKE_COORD_Y * 5, 0);
-        mGestureHandler.onTouchEvent(event);
-        assertEquals("A move event should only be offered to javascript if the down was offered",
-                0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-        assertTrue("Should have a pending gesture", mMockGestureDetector.mLastEvent != null);
-
-        event = motionEvent(MotionEvent.ACTION_POINTER_DOWN, downTime, eventTime + 10);
-        mGestureHandler.onTouchEvent(event);
-        assertEquals("A pointer event should only be offered to Javascript if the down was offered",
-                0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        // Ensure that redundant notifications have no effect.
-        mGestureHandler.hasTouchEventHandlers(true);
-
-        event = motionEvent(MotionEvent.ACTION_POINTER_UP, downTime, eventTime + 15);
-        mGestureHandler.onTouchEvent(event);
-        assertEquals("A pointer event should only be offered to Javascript if the down was offered",
-                0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        event = motionEvent(MotionEvent.ACTION_UP, downTime, eventTime + 20);
-        mGestureHandler.onTouchEvent(event);
-        assertEquals("A pointer event should only be offered to Javascript if the down was offered",
-                0, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
-
-        event = motionEvent(MotionEvent.ACTION_DOWN, downTime + 25, downTime + 25);
+                eventTime, eventTime, MotionEvent.ACTION_UP,
+                1, new PointerProperties[] { pp0 }, new PointerCoords[] { pc0 },
+                0, 0, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_CLASS_POINTER, 0);
         mGestureHandler.onTouchEvent(event);
-        assertEquals("A down event should be offered to Javascript with a registered touch handler",
-                1, mGestureHandler.getNumberOfPendingMotionEventsForTesting());
+        assertEquals(GestureEventType.SCROLL_END,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
+        assertEquals("Only GESTURE_SCROLL_END should have been sent",
+                8, mMockMotionEventDelegate.mGestureTypeList.size());
     }
 
     /**
-     * Verify that no timeout-based gestures are triggered after a touch event
-     * is consumed.  In particular, LONG_PRESS and SHOW_PRESS should not fire
-     * if TouchStart went unconsumed, but subsequent TouchMoves are consumed.
+     * Verify that the timer of LONG_PRESS will be cancelled when scrolling begins so
+     * LONG_PRESS and LONG_TAP won't be triggered.
      *
      * @throws Exception
      */
     @SmallTest
     @Feature({"Gestures"})
-    public void testNoTimeoutGestureAfterTouchConsumed() throws Exception {
+    public void testGesturesCancelledAfterLongPressCausesLostFocus() throws Exception {
+        final long downTime = SystemClock.uptimeMillis();
+        final long eventTime = SystemClock.uptimeMillis();
+
         getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 setUp();
+                mGestureHandler = new ContentViewGestureHandler(
+                        getInstrumentation().getTargetContext(), mMockMotionEventDelegate);
+                MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
+                assertTrue(mGestureHandler.onTouchEvent(event));
+            }
+        });
 
-                final long downTime = SystemClock.uptimeMillis();
-                final long eventTime = SystemClock.uptimeMillis();
+        final long longPressTimeoutMs = ViewConfiguration.getLongPressTimeout()
+                + ViewConfiguration.getTapTimeout() + 10;
+        assertTrue(mMockMotionEventDelegate.mLongPressCalled.await(
+                ScalableTimeout.scaleTimeout(longPressTimeoutMs), TimeUnit.MILLISECONDS));
 
-                mGestureHandler.hasTouchEventHandlers(true);
+        assertEquals("A LONG_PRESS gesture should have been sent",
+                GestureEventType.LONG_PRESS,
+                        mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
 
-                MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, eventTime);
-                assertTrue(mGestureHandler.onTouchEvent(event));
-                mGestureHandler.confirmTouchEvent(
-                        ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-                assertTrue("Should have a pending LONG_PRESS",
-                        mLongPressDetector.hasPendingMessage());
+        mGestureHandler.onWindowFocusLost();
 
-                event = MotionEvent.obtain(
-                        downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
-                        FAKE_COORD_X, FAKE_COORD_Y + 200, 0);
-                assertTrue(mGestureHandler.onTouchEvent(event));
-                mGestureHandler.confirmTouchEvent(
-                        ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_CONSUMED);
-                assertFalse("Should not have a pending LONG_PRESS",
-                        mLongPressDetector.hasPendingMessage());
-            }
-        });
-        assertFalse(mMockListener.mShowPressCalled.await(
-                ScalableTimeout.ScaleTimeout(ViewConfiguration.getTapTimeout() + 10),
-                TimeUnit.MILLISECONDS));
-        assertFalse(mMockListener.mLongPressCalled.await(
-                ScalableTimeout.ScaleTimeout(ViewConfiguration.getLongPressTimeout() + 10),
-                TimeUnit.MILLISECONDS));
+        assertEquals("The LONG_PRESS should have been cancelled by loss of focus",
+                GestureEventType.TAP_CANCEL,
+                        mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
+
+        MotionEvent event = motionEvent(
+                MotionEvent.ACTION_UP, downTime, eventTime + longPressTimeoutMs);
+        mGestureHandler.onTouchEvent(event);
+        assertFalse("Tap cancellation should have prevented the LONG_TAP",
+                mMockMotionEventDelegate.mGestureTypeList.contains(
+                        GestureEventType.LONG_TAP));
     }
 
     /**
-     * Verify that a TAP_DOWN will be followed by a TAP_CANCEL if the first
-     * touch is unconsumed, but the subsequent touch is consumed.
+     * Verify that ignoring the remaining touch sequence triggers proper touch and gesture
+     * cancellation.
      *
      * @throws Exception
      */
     @SmallTest
     @Feature({"Gestures"})
-    public void testTapCancelledAfterTouchConsumed() throws Exception {
+    public void testSetIgnoreRemainingTouchEvents() throws Exception {
         final long downTime = SystemClock.uptimeMillis();
         final long eventTime = SystemClock.uptimeMillis();
 
-        GestureRecordingMotionEventDelegate mockDelegate =
-                new GestureRecordingMotionEventDelegate();
-        mGestureHandler = new ContentViewGestureHandler(
-                getInstrumentation().getTargetContext(), mockDelegate, mMockZoomManager);
-        mGestureHandler.hasTouchEventHandlers(true);
+        mGestureHandler.setIgnoreRemainingTouchEvents();
+        assertTrue("If there was no active touch sequence, ignoring it should be a no-op",
+                mMockMotionEventDelegate.mGestureTypeList.isEmpty());
+        assertEquals("No MotionEvents should have been generated",
+                -1, mMockMotionEventDelegate.mMostRecentMotionEventAction);
 
         MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime);
         assertTrue(mGestureHandler.onTouchEvent(event));
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-        assertEquals("A TAP_DOWN gesture should have been sent",
-                ContentViewGestureHandler.GESTURE_TAP_DOWN,
-                        mockDelegate.mMostRecentGestureEvent.mType);
+        assertEquals(GestureEventType.TAP_DOWN,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
 
-        event = MotionEvent.obtain(
-                downTime, eventTime + 10, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X, FAKE_COORD_Y + 200, 0);
-        assertTrue(mGestureHandler.onTouchEvent(event));
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_CONSUMED);
-        assertEquals("A TAP_CANCEL gesture should have been sent",
-                ContentViewGestureHandler.GESTURE_TAP_CANCEL,
-                        mockDelegate.mMostRecentGestureEvent.mType);
+        mGestureHandler.setIgnoreRemainingTouchEvents();
+        assertEquals("The TAP_DOWN should have been cancelled",
+                GestureEventType.TAP_CANCEL,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
+        assertEquals("An ACTION_CANCEL MotionEvent should have been inserted",
+                MotionEvent.ACTION_CANCEL, mMockMotionEventDelegate.mMostRecentMotionEventAction);
 
-        event = MotionEvent.obtain(
-                downTime, eventTime + 15, MotionEvent.ACTION_MOVE,
-                FAKE_COORD_X, FAKE_COORD_Y + 400, 0);
+        // Subsequent MotionEvent's are dropped until ACTION_DOWN.
+        event = motionEvent(MotionEvent.ACTION_MOVE, downTime, eventTime + 5);
+        assertFalse(mGestureHandler.onTouchEvent(event));
+
+        event = motionEvent(MotionEvent.ACTION_UP, downTime, eventTime + 10);
+        assertFalse(mGestureHandler.onTouchEvent(event));
+
+        event = motionEvent(MotionEvent.ACTION_DOWN, downTime + 15, downTime + 15);
         assertTrue(mGestureHandler.onTouchEvent(event));
-        mGestureHandler.confirmTouchEvent(
-                ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-        assertEquals("No further gestures should be sent",
-                ContentViewGestureHandler.GESTURE_TAP_CANCEL,
-                        mockDelegate.mMostRecentGestureEvent.mType);
+        assertEquals(GestureEventType.TAP_DOWN,
+                mMockMotionEventDelegate.mMostRecentGestureEvent.mType);
     }
 }