/** * Verify that LONG_TAP is triggered after LongPress followed by an UP. * * @throws Exception */ @SmallTest @Feature({"Gestures"}) public void testGestureLongTap() throws Exception { final long downTime = SystemClock.uptimeMillis(); final long eventTime = SystemClock.uptimeMillis(); GestureRecordingMotionEventDelegate mockDelegate = new GestureRecordingMotionEventDelegate(); mGestureHandler = new ContentViewGestureHandler( getInstrumentation().getTargetContext(), mockDelegate, new MockZoomManager(getInstrumentation().getTargetContext(), null)); mLongPressDetector = mGestureHandler.getLongPressDetector(); MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime); assertTrue(mGestureHandler.onTouchEvent(event)); assertNotNull(mockDelegate.getMostRecentGestureEvent()); assertTrue("Should have a pending LONG_PRESS", mLongPressDetector.hasPendingMessage()); mLongPressDetector.sendLongPressGestureForTest(); assertEquals( "A LONG_PRESS gesture should have been sent", ContentViewGestureHandler.GESTURE_LONG_PRESS, mockDelegate.mMostRecentGestureEvent.mType); event = motionEvent(MotionEvent.ACTION_UP, downTime, eventTime + 1000); assertTrue(mGestureHandler.onTouchEvent(event)); assertEquals( "A LONG_TAP gesture should have been sent", ContentViewGestureHandler.GESTURE_LONG_TAP, mockDelegate.mMostRecentGestureEvent.mType); }
/** * 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 testLongPressAndTapCancelWhenScrollBegins() throws Exception { final long downTime = SystemClock.uptimeMillis(); final long eventTime = SystemClock.uptimeMillis(); GestureRecordingMotionEventDelegate mockDelegate = new GestureRecordingMotionEventDelegate(); mGestureHandler = new ContentViewGestureHandler( getInstrumentation().getTargetContext(), mockDelegate, new MockZoomManager(getInstrumentation().getTargetContext(), null)); mLongPressDetector = mGestureHandler.getLongPressDetector(); MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime); assertTrue(mGestureHandler.onTouchEvent(event)); assertNotNull(mockDelegate.getMostRecentGestureEvent()); 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()); // No LONG_TAP because LONG_PRESS timer is cancelled. assertFalse( "No LONG_PRESS should be sent", mockDelegate.mGestureTypeList.contains(ContentViewGestureHandler.GESTURE_LONG_PRESS)); assertFalse( "No LONG_TAP should be sent", mockDelegate.mGestureTypeList.contains(ContentViewGestureHandler.GESTURE_LONG_TAP)); }
/** * Verify that a DOWN followed shortly by an UP will trigger a single tap. * * @throws Exception */ @SmallTest @Feature({"Gestures"}) public void testGestureSingleClick() throws Exception { 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 a recent show pressed state gesture is canceled when double tap occurs. * * @throws Exception */ @SmallTest @Feature({"Gestures"}) public void testShowPressCancelOnDoubleTap() throws Exception { final long downTime = SystemClock.uptimeMillis(); final long eventTime = SystemClock.uptimeMillis(); GestureRecordingMotionEventDelegate mockDelegate = new GestureRecordingMotionEventDelegate(); mGestureHandler = new ContentViewGestureHandler( getInstrumentation().getTargetContext(), mockDelegate, new MockZoomManager(getInstrumentation().getTargetContext(), null)); 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); assertEquals( "Only flingCancel and showPressedState should have been sent", 2, mockDelegate.mGestureTypeList.size()); event = MotionEvent.obtain( downTime, eventTime + 5, MotionEvent.ACTION_UP, FAKE_COORD_X, FAKE_COORD_Y, 0); mGestureHandler.onTouchEvent(event); assertEquals("The first tap should not do anything", 2, mockDelegate.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 double tap should have occurred", ContentViewGestureHandler.GESTURE_DOUBLE_TAP, mockDelegate.mMostRecentGestureEvent.mType); assertTrue( "A show press cancel event should have been sent", mockDelegate.mGestureTypeList.contains( ContentViewGestureHandler.GESTURE_SHOW_PRESS_CANCEL)); assertEquals( "Only flingCancel, showPressedState," + "flingCancel, showPressCancel and doubleTap should have been sent", 5, mockDelegate.mGestureTypeList.size()); }
/** * 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(); 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(MotionEvent.ACTION_UP, downTime, eventTime + 5); 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()); }
/** * Verify that a DOWN followed by a MOVE will trigger fling (but not LONG). * * @throws Exception */ @SmallTest @Feature({"Gestures"}) public void testGestureFlingAndCancelLongClick() throws Exception { 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.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); }
/** * Verify that a recent show pressed state gesture is canceled when scrolling begins. * * @throws Exception */ @SmallTest @Feature({"Gestures"}) public void testShowPressCancelWhenScrollBegins() throws Exception { final long downTime = SystemClock.uptimeMillis(); final long eventTime = SystemClock.uptimeMillis(); GestureRecordingMotionEventDelegate mockDelegate = new GestureRecordingMotionEventDelegate(); mGestureHandler = new ContentViewGestureHandler( getInstrumentation().getTargetContext(), mockDelegate, new MockZoomManager(getInstrumentation().getTargetContext(), null)); 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); assertEquals( "Only flingCancel and showPressedState should have been sent", 2, mockDelegate.mGestureTypeList.size()); event = MotionEvent.obtain( downTime, eventTime + 10, MotionEvent.ACTION_MOVE, FAKE_COORD_X * 5, FAKE_COORD_Y * 5, 0); assertTrue(mGestureHandler.onTouchEvent(event)); assertEquals( "We should have started scrolling", ContentViewGestureHandler.GESTURE_SCROLL_BY, mockDelegate.mMostRecentGestureEvent.mType); assertTrue( "A show press cancel event should have been sent", mockDelegate.mGestureTypeList.contains( ContentViewGestureHandler.GESTURE_SHOW_PRESS_CANCEL)); assertEquals( "Only flingCancel, showPressedState," + "showPressCancel, scrollBegin and scrollBy should have been sent", 5, mockDelegate.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); assertTrue( "A scroll end event should not have been sent", !mockDelegate.mGestureTypeList.contains(ContentViewGestureHandler.GESTURE_SCROLL_END)); assertEquals( "The last up should have caused flingCancel and flingStart to be sent", 7, mockDelegate.mGestureTypeList.size()); }
/** * 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); }
/** * 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(), new MockZoomManager(getInstrumentation().getTargetContext(), null)); mLongPressDetector = new LongPressDetector(getInstrumentation().getTargetContext(), mGestureHandler); MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, downTime, downTime); mGestureHandler.hasTouchEventHandlers(true); 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 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); }