Loading services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java +2 −0 Original line number Diff line number Diff line Loading @@ -221,6 +221,8 @@ public class TouchExplorer extends BaseEventStreamTransformation mSendTouchInteractionEndDelayed.cancel(); // Clear the gesture detector mGestureDetector.clear(); // Clear the offset data by long pressing. mDispatcher.clear(); // Go to initial state. mState.clear(); mAms.onTouchInteractionEnd(); Loading services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java +58 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.accessibility.gestures; import static android.view.ViewConfiguration.getDoubleTapTimeout; import static com.android.server.accessibility.gestures.TouchState.STATE_CLEAR; import static com.android.server.accessibility.gestures.TouchState.STATE_DELEGATING; import static com.android.server.accessibility.gestures.TouchState.STATE_DRAGGING; Loading @@ -23,6 +25,7 @@ import static com.android.server.accessibility.gestures.TouchState.STATE_TOUCH_E import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import android.content.Context; Loading Loading @@ -53,6 +56,8 @@ import java.util.List; public class TouchExplorerTest { private static final String LOG_TAG = "TouchExplorerTest"; // The constant of mDetermineUserIntentTimeout. private static final int USER_INTENT_TIMEOUT = getDoubleTapTimeout(); private static final int FLAG_1FINGER = 0x8000; private static final int FLAG_2FINGERS = 0x0100; private static final int FLAG_3FINGERS = 0x0200; Loading Loading @@ -94,7 +99,9 @@ public class TouchExplorerTest { public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) { mEvents.add(0, event.copy()); // LastEvent may not match if we're clearing the state if (mLastEvent != null) { // The last event becomes ACTION_UP event when sending the ACTION_CANCEL event, // so ignoring the ACTION_CANCEL event checking. if (mLastEvent != null && rawEvent.getActionMasked() != MotionEvent.ACTION_CANCEL) { MotionEventMatcher lastEventMatcher = new MotionEventMatcher(mLastEvent); assertThat(rawEvent, lastEventMatcher); } Loading @@ -121,6 +128,43 @@ public class TouchExplorerTest { mTouchExplorer.setNext(mCaptor); } /** * Test the case where the event location is correct when clicking after the following * situation happened: entering the delegate state through doubleTapAndHold gesture and * receiving a cancel event to return the clear state. */ @Test public void testClick_afterCanceledDoubleTapAndHold_eventLocationIsCorrect() throws InterruptedException { // Generates the click position by this click operation, otherwise the offset used // while delegating could not be set. send(downEvent(DEFAULT_X + 10, DEFAULT_Y + 10)); // Waits for transition to touch exploring state. Thread.sleep(2 * USER_INTENT_TIMEOUT); send(upEvent()); // Simulates detecting the doubleTapAndHold gesture and enters the delegate state. final MotionEvent sendEvent = fromTouchscreen(downEvent(DEFAULT_X + 100, DEFAULT_Y + 100)); mTouchExplorer.onDoubleTapAndHold(sendEvent, sendEvent, 0); assertState(STATE_DELEGATING); send(cancelEvent()); // Generates the click operation, and checks the event location of the ACTION_HOVER_ENTER // event is correct. send(downEvent()); // Waits for transition to touch exploring state. Thread.sleep(2 * USER_INTENT_TIMEOUT); send(upEvent()); final List<MotionEvent> events = getCapturedEvents(); assertTrue(events.stream().anyMatch( motionEvent -> motionEvent.getActionMasked() == MotionEvent.ACTION_HOVER_ENTER && motionEvent.getX() == DEFAULT_X && motionEvent.getY() == DEFAULT_Y)); } @Test public void testTwoFingersMove_shouldDelegatingAndInjectActionDownPointerDown() { goFromStateClearTo(STATE_MOVING_2FINGERS); Loading Loading @@ -294,6 +338,19 @@ public class TouchExplorerTest { return ((EventCaptor) mCaptor).mEvents; } private MotionEvent cancelEvent() { mLastDownTime = SystemClock.uptimeMillis(); return fromTouchscreen( MotionEvent.obtain(mLastDownTime, mLastDownTime, MotionEvent.ACTION_CANCEL, DEFAULT_X, DEFAULT_Y, 0)); } private MotionEvent downEvent(float x, float y) { mLastDownTime = SystemClock.uptimeMillis(); return fromTouchscreen( MotionEvent.obtain(mLastDownTime, mLastDownTime, MotionEvent.ACTION_DOWN, x, y, 0)); } private MotionEvent downEvent() { mLastDownTime = SystemClock.uptimeMillis(); return fromTouchscreen( Loading Loading
services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java +2 −0 Original line number Diff line number Diff line Loading @@ -221,6 +221,8 @@ public class TouchExplorer extends BaseEventStreamTransformation mSendTouchInteractionEndDelayed.cancel(); // Clear the gesture detector mGestureDetector.clear(); // Clear the offset data by long pressing. mDispatcher.clear(); // Go to initial state. mState.clear(); mAms.onTouchInteractionEnd(); Loading
services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java +58 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.accessibility.gestures; import static android.view.ViewConfiguration.getDoubleTapTimeout; import static com.android.server.accessibility.gestures.TouchState.STATE_CLEAR; import static com.android.server.accessibility.gestures.TouchState.STATE_DELEGATING; import static com.android.server.accessibility.gestures.TouchState.STATE_DRAGGING; Loading @@ -23,6 +25,7 @@ import static com.android.server.accessibility.gestures.TouchState.STATE_TOUCH_E import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import android.content.Context; Loading Loading @@ -53,6 +56,8 @@ import java.util.List; public class TouchExplorerTest { private static final String LOG_TAG = "TouchExplorerTest"; // The constant of mDetermineUserIntentTimeout. private static final int USER_INTENT_TIMEOUT = getDoubleTapTimeout(); private static final int FLAG_1FINGER = 0x8000; private static final int FLAG_2FINGERS = 0x0100; private static final int FLAG_3FINGERS = 0x0200; Loading Loading @@ -94,7 +99,9 @@ public class TouchExplorerTest { public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) { mEvents.add(0, event.copy()); // LastEvent may not match if we're clearing the state if (mLastEvent != null) { // The last event becomes ACTION_UP event when sending the ACTION_CANCEL event, // so ignoring the ACTION_CANCEL event checking. if (mLastEvent != null && rawEvent.getActionMasked() != MotionEvent.ACTION_CANCEL) { MotionEventMatcher lastEventMatcher = new MotionEventMatcher(mLastEvent); assertThat(rawEvent, lastEventMatcher); } Loading @@ -121,6 +128,43 @@ public class TouchExplorerTest { mTouchExplorer.setNext(mCaptor); } /** * Test the case where the event location is correct when clicking after the following * situation happened: entering the delegate state through doubleTapAndHold gesture and * receiving a cancel event to return the clear state. */ @Test public void testClick_afterCanceledDoubleTapAndHold_eventLocationIsCorrect() throws InterruptedException { // Generates the click position by this click operation, otherwise the offset used // while delegating could not be set. send(downEvent(DEFAULT_X + 10, DEFAULT_Y + 10)); // Waits for transition to touch exploring state. Thread.sleep(2 * USER_INTENT_TIMEOUT); send(upEvent()); // Simulates detecting the doubleTapAndHold gesture and enters the delegate state. final MotionEvent sendEvent = fromTouchscreen(downEvent(DEFAULT_X + 100, DEFAULT_Y + 100)); mTouchExplorer.onDoubleTapAndHold(sendEvent, sendEvent, 0); assertState(STATE_DELEGATING); send(cancelEvent()); // Generates the click operation, and checks the event location of the ACTION_HOVER_ENTER // event is correct. send(downEvent()); // Waits for transition to touch exploring state. Thread.sleep(2 * USER_INTENT_TIMEOUT); send(upEvent()); final List<MotionEvent> events = getCapturedEvents(); assertTrue(events.stream().anyMatch( motionEvent -> motionEvent.getActionMasked() == MotionEvent.ACTION_HOVER_ENTER && motionEvent.getX() == DEFAULT_X && motionEvent.getY() == DEFAULT_Y)); } @Test public void testTwoFingersMove_shouldDelegatingAndInjectActionDownPointerDown() { goFromStateClearTo(STATE_MOVING_2FINGERS); Loading Loading @@ -294,6 +338,19 @@ public class TouchExplorerTest { return ((EventCaptor) mCaptor).mEvents; } private MotionEvent cancelEvent() { mLastDownTime = SystemClock.uptimeMillis(); return fromTouchscreen( MotionEvent.obtain(mLastDownTime, mLastDownTime, MotionEvent.ACTION_CANCEL, DEFAULT_X, DEFAULT_Y, 0)); } private MotionEvent downEvent(float x, float y) { mLastDownTime = SystemClock.uptimeMillis(); return fromTouchscreen( MotionEvent.obtain(mLastDownTime, mLastDownTime, MotionEvent.ACTION_DOWN, x, y, 0)); } private MotionEvent downEvent() { mLastDownTime = SystemClock.uptimeMillis(); return fromTouchscreen( Loading