Merge "fix(MultiFingerMultiTap): Two-Finger triple tap while zoomed in doesn't zoom out full screen magnification" into main
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
index f55ecb0..0a2a780 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
@@ -981,17 +981,22 @@
                                 transitionToDelegatingStateAndClear();
                             }
                             transitToSinglePanningStateAndClear();
-                        } else {
+                        } else if (!mIsTwoFingerCountReached) {
+                            // If it is a two-finger gesture, do not transition to the
+                            // delegating state to ensure the reachability of
+                            // the two-finger triple tap (triggerable with ACTION_UP)
                             transitionToDelegatingStateAndClear();
                         }
                     } else if (isActivated() && pointerDownValid(mSecondPointerDownLocation)
                             && distanceClosestPointerToPoint(
-                            mSecondPointerDownLocation, /* move */ event) > mSwipeMinDistance
-                            // If mCompleteTapCount is not zero, it means that it is a multi tap
-                            // gesture. So, we should not transit to the PanningScalingState.
-                            && mCompletedTapCount == 0) {
+                            mSecondPointerDownLocation, /* move */ event) > mSwipeMinDistance) {
                         // Second pointer is swiping, so transit to PanningScalingState
-                        transitToPanningScalingStateAndClear();
+                        // Delay an ACTION_MOVE for tap timeout to ensure it is not trigger from
+                        // multi finger multi tap
+                        storePointerDownLocation(mSecondPointerDownLocation, event);
+                        mHandler.sendEmptyMessageDelayed(
+                                MESSAGE_TRANSITION_TO_PANNINGSCALING_STATE,
+                                ViewConfiguration.getTapTimeout());
                     }
                 }
                 break;
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
index 9114027..a9967f6 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
@@ -717,6 +717,45 @@
     }
 
     @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
+    public void testSecondFingerSwipe_twoPointerDownAndActivatedState_shouldInPanningState() {
+        goFromStateIdleTo(STATE_ACTIVATED);
+        PointF pointer1 = DEFAULT_POINT;
+        PointF pointer2 = new PointF(DEFAULT_X * 1.5f, DEFAULT_Y);
+
+        send(downEvent());
+        send(pointerEvent(ACTION_POINTER_DOWN, new PointF[] {pointer1, pointer2}, 1));
+        //The minimum movement to transit to panningState.
+        final float sWipeMinDistance = ViewConfiguration.get(mContext).getScaledTouchSlop();
+        pointer2.offset(sWipeMinDistance + 1, 0);
+        send(pointerEvent(ACTION_MOVE, new PointF[] {pointer1, pointer2}, 1));
+        fastForward(ViewConfiguration.getTapTimeout());
+        assertIn(STATE_PANNING);
+
+        returnToNormalFrom(STATE_PANNING);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
+    public void testTowFingerSwipe_twoPointerDownAndShortcutTriggeredState_shouldInPanningState() {
+        goFromStateIdleTo(STATE_SHORTCUT_TRIGGERED);
+        PointF pointer1 = DEFAULT_POINT;
+        PointF pointer2 = new PointF(DEFAULT_X * 1.5f, DEFAULT_Y);
+
+        send(downEvent());
+        send(pointerEvent(ACTION_POINTER_DOWN, new PointF[] {pointer1, pointer2}, 1));
+        //The minimum movement to transit to panningState.
+        final float sWipeMinDistance = ViewConfiguration.get(mContext).getScaledTouchSlop();
+        pointer2.offset(sWipeMinDistance + 1, 0);
+        send(pointerEvent(ACTION_MOVE, new PointF[] {pointer1, pointer2}, 1));
+        fastForward(ViewConfiguration.getTapTimeout());
+        assertIn(STATE_PANNING);
+
+        returnToNormalFrom(STATE_PANNING);
+    }
+
+    @Test
+    @RequiresFlagsDisabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
     public void testSecondFingerSwipe_twoPointerDownAndActivatedState_panningState() {
         goFromStateIdleTo(STATE_ACTIVATED);
         PointF pointer1 = DEFAULT_POINT;
@@ -734,6 +773,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
     public void testSecondFingerSwipe_twoPointerDownAndShortcutTriggeredState_panningState() {
         goFromStateIdleTo(STATE_SHORTCUT_TRIGGERED);
         PointF pointer1 = DEFAULT_POINT;