Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(577)

Unified Diff: content/public/android/javatests/src/org/chromium/content/browser/GestureDetectorProxyTest.java

Issue 10690190: Upstream GestureDetectorProxyTest (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/public/android/javatests/src/org/chromium/content/browser/GestureDetectorProxyTest.java
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/GestureDetectorProxyTest.java b/content/public/android/javatests/src/org/chromium/content/browser/GestureDetectorProxyTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..68d3200e8a759b0a84cfca7d075b6a51c28e8ed5
--- /dev/null
+++ b/content/public/android/javatests/src/org/chromium/content/browser/GestureDetectorProxyTest.java
@@ -0,0 +1,300 @@
+// Copyright (c) 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.
+
+/**
+ * Test suite for GestureDetectorProxy.
+ */
+
+package org.chromium.content.browser;
+
+import android.content.Context;
+import android.os.SystemClock;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.GestureDetector;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.chromium.base.test.Feature;
+import org.chromium.base.test.ScalableTimeout;
+
+public class GestureDetectorProxyTest extends InstrumentationTestCase {
+ final int mTouchSlop = 37;
+ MockListener mMockListener;
+ MockGestureDetector mMockDetector;
+ GestureDetectorProxy mProxy;
+
+ class MockListener extends GestureDetector.SimpleOnGestureListener {
+ MotionEvent mLastLongPress;
+ MotionEvent mLastSingleTap;
+ MotionEvent mLastFling1;
+ MotionEvent mLastFling2;
+ CountDownLatch mLongPressCalled;
+ MotionEvent mLastScroll1;
+ MotionEvent mLastScroll2;
+ float mLastScrollDistanceX;
+ float mLastScrollDistanceY;
+
+ public MockListener() {
+ mLongPressCalled = new CountDownLatch(1);
+ }
+
+ @Override
+ public void onLongPress(MotionEvent e) {
+ mLastLongPress = MotionEvent.obtain(e);
+ mLongPressCalled.countDown();
+ }
+
+ @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) {
+ mLastScroll1 = e1;
+ mLastScroll2 = e2;
+ mLastScrollDistanceX = distanceX;
+ mLastScrollDistanceY = distanceY;
+ return true;
+ }
+
+ @Override
+ public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
+ mLastFling1 = e1;
+ mLastFling2 = e2;
+ return true;
+ }
+ }
+
+ class MockGestureDetector extends GestureDetector {
+ MotionEvent mLastEvent;
+ public MockGestureDetector(Context context, OnGestureListener listener) {
+ super(context, listener);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ mLastEvent = MotionEvent.obtain(ev);
+ return super.onTouchEvent(ev);
+ }
+ }
+
+ private MotionEvent motionEvent(int action, long downTime, long eventTime) {
+ final int fakeCoordX = 42;
+ final int fakeCoordY = 24;
+ return MotionEvent.obtain(downTime, eventTime, action, fakeCoordX, fakeCoordY, 0);
+ }
+
+ @Override
+ public void setUp() {
+ mMockListener = new MockListener();
+ mMockDetector = new MockGestureDetector(getInstrumentation().getTargetContext(),
+ mMockListener);
+ mProxy = new GestureDetectorProxy(getInstrumentation().getTargetContext(),
+ mMockDetector, mMockListener);
+ }
+
+ /**
+ * Verify a DOWN without a corresponding UP will have a pending DOWN.
+ *
+ * @throws Exception
+ */
+ @SmallTest
+ @Feature({"Android-WebView"})
+ public void testProxySimpleLongPress() throws Exception {
+ final long downTime = SystemClock.uptimeMillis();
+ final long eventTime = SystemClock.uptimeMillis();
+
+ MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, eventTime);
+
+ assertFalse(mProxy.onTouchEvent(event));
+ assertTrue("Should have a pending gesture", mMockDetector.mLastEvent != null);
+ assertTrue("Should have a pending LONG_PRESS", mProxy.hasPendingMessage());
+ }
+
+ /**
+ * Verify a DOWN with a corresponding UP will not have a pending Gesture.
+ *
+ * @throws Exception
+ */
+ @SmallTest
+ @Feature({"Android-WebView"})
+ public void testProxyNoLongPress() throws Exception {
+ final long downTime = SystemClock.uptimeMillis();
+ final long eventTime = SystemClock.uptimeMillis();
+
+ MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, eventTime);
+
+ assertFalse(mProxy.onTouchEvent(event));
+ assertTrue("Should have a pending gesture", mMockDetector.mLastEvent != null);
+ assertTrue("Should have a pending LONG_PRESS", mProxy.hasPendingMessage());
+
+ event = motionEvent(MotionEvent.ACTION_UP, downTime, eventTime + 10);
+ mProxy.cancelLongPressIfNeeded(event);
+ assertTrue("Should not have a pending LONG_PRESS", !mProxy.hasPendingMessage());
+ }
+
+ /**
+ * 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({"Android-WebView"})
+ public void testProxyLongWithDelayedUp() throws Exception {
+ final long downTime = SystemClock.uptimeMillis();
+ final long eventTime = SystemClock.uptimeMillis();
+
+ MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, eventTime);
+
+ assertFalse(mProxy.onTouchEvent(event));
+ assertTrue("Should have a pending gesture", mMockDetector.mLastEvent != null);
+ assertTrue("Should have a pending LONG_PRESS", mProxy.hasPendingMessage());
+
+ // Event time must be larger than LONG_PRESS_TIMEOUT.
+ event = motionEvent(MotionEvent.ACTION_UP, downTime, eventTime + 1000);
+ mProxy.cancelLongPressIfNeeded(event);
+ assertTrue("Should still have a pending gesture", mProxy.hasPendingMessage());
+ }
+
+ /**
+ * Verify that a DOWN followed shortly by an UP will trigger a single tap.
+ *
+ * @throws Exception
+ */
+ @SmallTest
+ @Feature({"Android-WebView"})
+ public void testProxySingleClick() throws Exception {
+ final long downTime = SystemClock.uptimeMillis();
+ final long eventTime = SystemClock.uptimeMillis();
+
+ MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, eventTime);
+
+ assertFalse(mProxy.onTouchEvent(event));
+ assertTrue("Should have a pending gesture", mMockDetector.mLastEvent != null);
+ assertTrue("Should have a pending LONG_PRESS", mProxy.hasPendingMessage());
+
+ event = motionEvent(MotionEvent.ACTION_UP, downTime, eventTime + 10);
+ mProxy.cancelLongPressIfNeeded(event);
+ assertTrue("Should not have a pending LONG_PRESS", !mProxy.hasPendingMessage());
+ assertTrue(mProxy.onTouchEvent(event));
+ // Synchronous, no need to wait.
+ assertTrue("Should have a single tap", mMockListener.mLastSingleTap != null);
+ }
+
+ /**
+ * Verify that a DOWN followed by a MOVE will trigger fling (but not LONG).
+ * @throws Exception
+ */
+ @SmallTest
+ @Feature({"Android-WebView"})
+ public void testProxyFlingAndCancelLongClick() throws Exception {
+ final long downTime = SystemClock.uptimeMillis();
+ final long eventTime = SystemClock.uptimeMillis();
+
+ MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, eventTime);
+
+ assertFalse(mProxy.onTouchEvent(event));
+ assertTrue("Should have a pending gesture", mMockDetector.mLastEvent != null);
+ assertTrue("Should have a pending LONG_PRESS", mProxy.hasPendingMessage());
+
+ event = MotionEvent.obtain(downTime, eventTime + 5, MotionEvent.ACTION_MOVE, 420, 420, 0);
+ mProxy.cancelLongPressIfNeeded(event);
+ assertTrue("Should not have a pending LONG_PRESS", !mProxy.hasPendingMessage());
+ assertTrue(mProxy.onTouchEvent(event));
+
+ event = MotionEvent.obtain(downTime, eventTime + 10, MotionEvent.ACTION_UP, 420, 420, 0);
+ assertTrue(mProxy.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);
+ }
+
+
+ class MainThreadTestHelper {
+ MockListener mMockListenerUI;
+ MockGestureDetector mMockDetectorUI;
+ GestureDetectorProxy mProxyUI;
+
+ void setUp() {
+ mMockListenerUI = new MockListener();
+ mMockDetectorUI = new MockGestureDetector(getInstrumentation().getTargetContext(),
+ mMockListenerUI);
+ mProxyUI = new GestureDetectorProxy(getInstrumentation().getTargetContext(),
+ mMockDetectorUI, mMockListenerUI);
+ }
+ }
+
+ /**
+ * 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({"Android-WebView"})
+ public void testProxyLongPressDetected() throws Exception {
+ final MainThreadTestHelper mainThreadTestHelper = new MainThreadTestHelper();
+
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ mainThreadTestHelper.setUp();
+ final long downTime = SystemClock.uptimeMillis();
+ final long eventTime = SystemClock.uptimeMillis();
+ MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, eventTime);
+ mainThreadTestHelper.mProxyUI.onTouchEvent(event);
+ }
+ });
+ assertTrue(mainThreadTestHelper.mMockListenerUI
+ .mLongPressCalled.await(ScalableTimeout.ScaleTimeout(1000), TimeUnit.MILLISECONDS));
+ }
+
+ /**
+ * Verify that the touch move threshold (slop) is working for events offered to native.
+ */
+ @SmallTest
+ @Feature({"Android-WebView"})
+ public void testConfirmOfferMoveEventToNative() {
+ final int slop = ViewConfiguration.get(getInstrumentation().getTargetContext())
+ .getScaledTouchSlop();
+
+ final int downX = 100;
+ final int downY = 200;
+ long eventTime = SystemClock.uptimeMillis();
+ final MotionEvent downEvent = MotionEvent.obtain(eventTime, eventTime,
+ MotionEvent.ACTION_DOWN, downX, downY, 0);
+
+ // Test a small move, where confirmOfferMoveEventToNative should return false.
+ mProxy.onOfferTouchEventToNative(downEvent);
+ eventTime = SystemClock.uptimeMillis();
+ final MotionEvent smallMove = MotionEvent.obtain(eventTime, eventTime,
+ MotionEvent.ACTION_MOVE, downX + slop / 2, downY + slop / 2, 0);
+ assertFalse(mProxy.confirmOfferMoveEventToNative(smallMove));
+
+ // Test a big move, where confirmOfferMoveEventToNative should return true.
+ mProxy.onOfferTouchEventToNative(downEvent);
+ eventTime = SystemClock.uptimeMillis();
+ final MotionEvent largeMove = MotionEvent.obtain(eventTime, eventTime,
+ MotionEvent.ACTION_MOVE, downX + slop * 2, downY + slop * 2, 0);
+ assertTrue(mProxy.confirmOfferMoveEventToNative(largeMove));
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698