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