From bc96e7ef333315f5404ca947067b439c33ce4931 Mon Sep 17 00:00:00 2001 From: Jacky Kao Date: Tue, 13 Oct 2020 13:59:35 +0800 Subject: [PATCH] Fix the focus not move to the place where the finger clicks User does the triple tap operation, but the gesture detection becomes to doubleTapAndHold because the timing of the motion event. Then the long pressing data is created but not be cleared when the state returns to STATE_CLEAR. Adding the long pressing data reset to fix this issue. Bug: 163298552 Test: a11y CTS & unit tests Change-Id: I5fc23a14b0a4ae3c7c012cb4ed8dc924c00e7fe9 --- .../accessibility/gestures/TouchExplorer.java | 2 + .../gestures/TouchExplorerTest.java | 51 +++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java index 5460e80a2802b..e37225264af93 100644 --- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java +++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java @@ -245,6 +245,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(); diff --git a/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java index dda81ffded4f3..0e32ea6ce057c 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java @@ -16,6 +16,7 @@ package com.android.server.accessibility.gestures; +import static android.view.MotionEvent.ACTION_CANCEL; import static android.view.MotionEvent.ACTION_DOWN; import static android.view.MotionEvent.ACTION_HOVER_ENTER; import static android.view.MotionEvent.ACTION_HOVER_EXIT; @@ -33,6 +34,7 @@ import static com.android.server.accessibility.gestures.TouchState.STATE_GESTURE import static com.android.server.accessibility.gestures.TouchState.STATE_TOUCH_EXPLORING; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import android.content.Context; @@ -173,6 +175,42 @@ public class TouchExplorerTest { ACTION_HOVER_EXIT); } + /** + * 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() { + // 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. + mHandler.fastForward(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. + mHandler.fastForward(2 * USER_INTENT_TIMEOUT); + send(upEvent()); + + final List events = getCapturedEvents(); + assertTrue(events.stream().anyMatch( + motionEvent -> motionEvent.getActionMasked() == ACTION_HOVER_ENTER + && motionEvent.getX() == DEFAULT_X + && motionEvent.getY() == DEFAULT_Y)); + } + /** * Test the case where ACTION_POINTER_DOWN is followed by a number of ACTION_MOVE events that do * not change the coordinates. @@ -449,6 +487,19 @@ public class TouchExplorerTest { return ((EventCaptor) mCaptor).mEvents; } + private MotionEvent cancelEvent() { + mLastDownTime = SystemClock.uptimeMillis(); + return fromTouchscreen( + MotionEvent.obtain(mLastDownTime, mLastDownTime, ACTION_CANCEL, + DEFAULT_X, DEFAULT_Y, 0)); + } + + private MotionEvent downEvent(float x, float y) { + mLastDownTime = SystemClock.uptimeMillis(); + return fromTouchscreen( + MotionEvent.obtain(mLastDownTime, mLastDownTime, ACTION_DOWN, x, y, 0)); + } + private MotionEvent downEvent() { mLastDownTime = SystemClock.uptimeMillis(); return fromTouchscreen(