From 13f1af418f4ea419fcdfb7c53e15d676ea9c069e Mon Sep 17 00:00:00 2001 From: Jean Chen Date: Thu, 7 Dec 2023 22:36:20 +0800 Subject: fix(MultiFingerMultiTap): Two-Finger triple tap while zoomed in doesn't zoom out full screen magnification The root cause lies in the state transitioning to another state before the multi-finger multi-tap gesture is completed. After test, we still need to implement a delay to determine whether the gesture is a single tap or a multi-tap. If it is a multi-tap, the ACTION_UP event will interrupt the magnification transition to the panning state. Otherwise, we need to interrupt the magnification transition to the delegating state in ACTION_MOVE to ensure the reachability of the two-finger triple tap (triggerable with ACTION_UP) NO_IFTTT=add the multi-finger multi-tap feature without syncing to the old state Bug: 315225078 Test: manual Test: atest FullScreenMagnificationGestureHandlerTest Change-Id: Ic6176857baf3f006b26b7737a913efe69b7e061f --- .../FullScreenMagnificationGestureHandler.java | 17 +++++---- .../FullScreenMagnificationGestureHandlerTest.java | 40 ++++++++++++++++++++++ 2 files changed, 51 insertions(+), 6 deletions(-) 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 f55ecb05c55f..0a2a780adf45 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 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH 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 91140276cde0..a9967f63b3b3 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 @@ public class FullScreenMagnificationGestureHandlerTest { } @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 @@ public class FullScreenMagnificationGestureHandlerTest { } @Test + @RequiresFlagsDisabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) public void testSecondFingerSwipe_twoPointerDownAndShortcutTriggeredState_panningState() { goFromStateIdleTo(STATE_SHORTCUT_TRIGGERED); PointF pointer1 = DEFAULT_POINT; -- cgit v1.2.3-59-g8ed1b