blob: a89a285c4b58b19e5254371695218d5c93dfaaa6 [file] [log] [blame]
// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.content.browser;
import android.os.SystemClock;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.SmallTest;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.ScalableTimeout;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* Test suite for LongPressDetector.
*/
public class LongPressDetectorTest extends InstrumentationTestCase {
private static final int FAKE_COORD_X = 42;
private static final int FAKE_COORD_Y = 24;
private LongPressDetector mLongPressDetector;
private MotionEvent motionEvent(int action, long downTime, long eventTime) {
return MotionEvent.obtain(downTime, eventTime, action, FAKE_COORD_X, FAKE_COORD_Y, 0);
}
@Override
public void setUp() {
mLongPressDetector = new LongPressDetector(getInstrumentation().getTargetContext(), null);
}
/**
* Verify a DOWN without a corresponding UP will have a pending DOWN.
*
* @throws Exception
*/
@SmallTest
@Feature({"AndroidWebView"})
public void testGestureSimpleLongPress() throws Exception {
final long downTime = SystemClock.uptimeMillis();
final long eventTime = SystemClock.uptimeMillis();
MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, eventTime);
mLongPressDetector.startLongPressTimerIfNeeded(event);
assertTrue("Should have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
}
private void gestureNoLongPressTestHelper(int cancelActionType) throws Exception {
final long downTime = SystemClock.uptimeMillis();
final long eventTime = SystemClock.uptimeMillis();
MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, eventTime);
mLongPressDetector.startLongPressTimerIfNeeded(event);
assertTrue("Should have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
event = motionEvent(cancelActionType, downTime, eventTime + 10);
mLongPressDetector.cancelLongPressIfNeeded(event);
assertTrue("Should not have a pending LONG_PRESS", !mLongPressDetector.hasPendingMessage());
}
/**
* Verify a DOWN with a corresponding UP will not have a pending Gesture.
*
* @throws Exception
*/
@SmallTest
@Feature({"AndroidWebView"})
public void testGestureNoLongPressOnUp() throws Exception {
gestureNoLongPressTestHelper(MotionEvent.ACTION_UP);
}
/**
* Verify a DOWN with a corresponding CANCEL will not have a pending Gesture.
*
* @throws Exception
*/
@SmallTest
@Feature({"AndroidWebView"})
public void testGestureNoLongPressOnCancel() throws Exception {
gestureNoLongPressTestHelper(MotionEvent.ACTION_CANCEL);
}
/**
* Verify that a DOWN followed by an UP after the long press timer would
* detect a long press (that is, the UP will not trigger a tap or cancel the
* long press).
*
* @throws Exception
*/
@SmallTest
@Feature({"AndroidWebView"})
public void testGestureLongWithDelayedUp() throws Exception {
final long downTime = SystemClock.uptimeMillis();
final long eventTime = SystemClock.uptimeMillis();
MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, eventTime);
mLongPressDetector.startLongPressTimerIfNeeded(event);
assertTrue("Should have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage());
// Event time must be larger than LONG_PRESS_TIMEOUT.
event = motionEvent(MotionEvent.ACTION_UP, downTime, eventTime + 1000);
mLongPressDetector.cancelLongPressIfNeeded(event);
assertTrue("Should still have a pending gesture", mLongPressDetector.hasPendingMessage());
}
/**
* Verify that the touch move threshold (slop) is working for events offered to native.
*/
@SmallTest
@Feature({"AndroidWebView"})
public void testConfirmOfferMoveEventToNative() {
final int slop = ViewConfiguration.get(getInstrumentation().getTargetContext())
.getScaledTouchSlop();
long eventTime = SystemClock.uptimeMillis();
final MotionEvent downEvent = MotionEvent.obtain(
eventTime, eventTime, MotionEvent.ACTION_DOWN, FAKE_COORD_X, FAKE_COORD_Y, 0);
// Test a small move, where confirmOfferMoveEventToNative should return false.
mLongPressDetector.onOfferTouchEventToJavaScript(downEvent);
eventTime = SystemClock.uptimeMillis();
final MotionEvent smallMove = MotionEvent.obtain(
eventTime, eventTime, MotionEvent.ACTION_MOVE,
FAKE_COORD_X + slop / 2, FAKE_COORD_Y + slop / 2, 0);
assertFalse(mLongPressDetector.confirmOfferMoveEventToJavaScript(smallMove));
// Test a big move, where confirmOfferMoveEventToNative should return true.
mLongPressDetector.onOfferTouchEventToJavaScript(downEvent);
eventTime = SystemClock.uptimeMillis();
final MotionEvent largeMove = MotionEvent.obtain(
eventTime, eventTime, MotionEvent.ACTION_MOVE,
FAKE_COORD_X + slop * 2, FAKE_COORD_Y + slop * 2, 0);
assertTrue(mLongPressDetector.confirmOfferMoveEventToJavaScript(largeMove));
}
/**
* This is an example of a large test running delayed messages.
* It exercises GestureDetector itself, and expects the onLongPress to be called.
* Note that GestureDetector creates a Handler and posts message to it for detecting
* long press. It needs to be created on the Main thread.
*
* @throws Exception
*/
@LargeTest
@Feature({"AndroidWebView"})
public void testGestureLongPressDetected() throws Exception {
final CountDownLatch longPressCalled = new CountDownLatch(1);
getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
LongPressDetector longPressDetector = new LongPressDetector(
getInstrumentation().getTargetContext(),
new LongPressDetector.LongPressDelegate() {
@Override
public void onLongPress(MotionEvent event) {
longPressCalled.countDown();
}
});
final long downTime = SystemClock.uptimeMillis();
final long eventTime = SystemClock.uptimeMillis();
MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, eventTime);
longPressDetector.startLongPressTimerIfNeeded(event);
}
});
assertTrue(longPressCalled.await(
ScalableTimeout.ScaleTimeout(1000), TimeUnit.MILLISECONDS));
}
}