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: 162521649 and 163298552
Test: a11y CTS & unit tests
Change-Id: I40d89ea958bee619c64799de591be96bf92efbfc
Merged-In: I5fc23a14b0a4ae3c7c012cb4ed8dc924c00e7fe9
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 bfb59f4..71d2c2c 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
@@ -221,6 +221,8 @@
         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 c18cad4..13587bc 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,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;
@@ -23,6 +25,7 @@
 
 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;
@@ -53,6 +56,8 @@
 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;
@@ -94,7 +99,9 @@
         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);
             }
@@ -121,6 +128,43 @@
         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);
@@ -294,6 +338,19 @@
         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(