1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)package org.chromium.content.browser;
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.os.SystemClock;
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.test.InstrumentationTestCase;
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.test.suitebuilder.annotation.LargeTest;
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.test.suitebuilder.annotation.SmallTest;
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.view.MotionEvent;
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.view.ViewConfiguration;
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import org.chromium.base.test.util.Feature;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import org.chromium.base.test.util.ScalableTimeout;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import java.util.concurrent.CountDownLatch;
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import java.util.concurrent.TimeUnit;
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Test suite for LongPressDetector.
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public class LongPressDetectorTest extends InstrumentationTestCase {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final int FAKE_COORD_X = 42;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final int FAKE_COORD_Y = 24;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private LongPressDetector mLongPressDetector;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private MotionEvent motionEvent(int action, long downTime, long eventTime) {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return MotionEvent.obtain(downTime, eventTime, action, FAKE_COORD_X, FAKE_COORD_Y, 0);
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @Override
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public void setUp() {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mLongPressDetector = new LongPressDetector(getInstrumentation().getTargetContext(), null);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Verify a DOWN without a corresponding UP will have a pending DOWN.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @throws Exception
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @SmallTest
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @Feature({"AndroidWebView"})
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public void testGestureSimpleLongPress() throws Exception {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        final long downTime = SystemClock.uptimeMillis();
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        final long eventTime = SystemClock.uptimeMillis();
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, eventTime);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mLongPressDetector.startLongPressTimerIfNeeded(event);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        assertTrue("Should have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private void gestureNoLongPressTestHelper(int cancelActionType) throws Exception {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        final long downTime = SystemClock.uptimeMillis();
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        final long eventTime = SystemClock.uptimeMillis();
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, eventTime);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mLongPressDetector.startLongPressTimerIfNeeded(event);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        assertTrue("Should have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        event = motionEvent(cancelActionType, downTime, eventTime + 10);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mLongPressDetector.cancelLongPressIfNeeded(event);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        assertTrue("Should not have a pending LONG_PRESS", !mLongPressDetector.hasPendingMessage());
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * Verify a DOWN with a corresponding UP will not have a pending Gesture.
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     *
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * @throws Exception
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @SmallTest
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @Feature({"AndroidWebView"})
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    public void testGestureNoLongPressOnUp() throws Exception {
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gestureNoLongPressTestHelper(MotionEvent.ACTION_UP);
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /**
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * Verify a DOWN with a corresponding CANCEL will not have a pending Gesture.
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     *
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * @throws Exception
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @SmallTest
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @Feature({"AndroidWebView"})
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    public void testGestureNoLongPressOnCancel() throws Exception {
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gestureNoLongPressTestHelper(MotionEvent.ACTION_CANCEL);
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /**
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Verify that a DOWN followed by an UP after the long press timer would
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * detect a long press (that is, the UP will not trigger a tap or cancel the
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * long press).
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @throws Exception
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @SmallTest
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @Feature({"AndroidWebView"})
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public void testGestureLongWithDelayedUp() throws Exception {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        final long downTime = SystemClock.uptimeMillis();
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        final long eventTime = SystemClock.uptimeMillis();
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, eventTime);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mLongPressDetector.startLongPressTimerIfNeeded(event);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        assertTrue("Should have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Event time must be larger than LONG_PRESS_TIMEOUT.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        event = motionEvent(MotionEvent.ACTION_UP, downTime, eventTime + 1000);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mLongPressDetector.cancelLongPressIfNeeded(event);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        assertTrue("Should still have a pending gesture", mLongPressDetector.hasPendingMessage());
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Verify that the touch move threshold (slop) is working for events offered to native.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @SmallTest
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @Feature({"AndroidWebView"})
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public void testConfirmOfferMoveEventToNative() {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        final int slop = ViewConfiguration.get(getInstrumentation().getTargetContext())
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                .getScaledTouchSlop();
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        long eventTime = SystemClock.uptimeMillis();
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        final MotionEvent downEvent = MotionEvent.obtain(
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                eventTime, eventTime, MotionEvent.ACTION_DOWN, FAKE_COORD_X, FAKE_COORD_Y, 0);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Test a small move, where confirmOfferMoveEventToNative should return false.
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mLongPressDetector.onOfferTouchEventToJavaScript(downEvent);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        eventTime = SystemClock.uptimeMillis();
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        final MotionEvent smallMove = MotionEvent.obtain(
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                eventTime, eventTime, MotionEvent.ACTION_MOVE,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                FAKE_COORD_X + slop / 2, FAKE_COORD_Y + slop / 2, 0);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        assertFalse(mLongPressDetector.confirmOfferMoveEventToJavaScript(smallMove));
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Test a big move, where confirmOfferMoveEventToNative should return true.
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mLongPressDetector.onOfferTouchEventToJavaScript(downEvent);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        eventTime = SystemClock.uptimeMillis();
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        final MotionEvent largeMove = MotionEvent.obtain(
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                eventTime, eventTime, MotionEvent.ACTION_MOVE,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                FAKE_COORD_X + slop * 2, FAKE_COORD_Y + slop * 2, 0);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        assertTrue(mLongPressDetector.confirmOfferMoveEventToJavaScript(largeMove));
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * This is an example of a large test running delayed messages.
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * It exercises GestureDetector itself, and expects the onLongPress to be called.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Note that GestureDetector creates a Handler and posts message to it for detecting
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * long press. It needs to be created on the Main thread.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @throws Exception
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @LargeTest
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @Feature({"AndroidWebView"})
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public void testGestureLongPressDetected() throws Exception {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        final CountDownLatch longPressCalled = new CountDownLatch(1);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        getInstrumentation().runOnMainSync(new Runnable() {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            @Override
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            public void run() {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                LongPressDetector longPressDetector = new LongPressDetector(
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        getInstrumentation().getTargetContext(),
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        new LongPressDetector.LongPressDelegate() {
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            @Override
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            public void onLongPress(MotionEvent event) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                longPressCalled.countDown();
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                });
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                final long downTime = SystemClock.uptimeMillis();
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                final long eventTime = SystemClock.uptimeMillis();
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, eventTime);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                longPressDetector.startLongPressTimerIfNeeded(event);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        });
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        assertTrue(longPressCalled.await(
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ScalableTimeout.ScaleTimeout(1000), TimeUnit.MILLISECONDS));
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
178