Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0232d29e authored by Rhed Jao's avatar Rhed Jao
Browse files

Fix delay when multi-tap out of distance slop.

Triple tap gesture didn't consider the case when user tap quickly
and out of distance slop. Just send out all delay motion events
if we detect a tap with out of the distance slop.

Bug: 122623669
Test: atest MagnificationGestureHandlerTest
Change-Id: Iadd05441e10f720f57297b6091f4acff5d198b7c
parent 66f91878
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -667,6 +667,10 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation {
                        // 3tap and hold
                        afterLongTapTimeoutTransitionToDraggingState(event);

                    } else if (isTapOutOfDistanceSlop()) {

                        transitionToDelegatingStateAndClear();

                    } else if (mDetectTripleTap
                            // If magnified, delay an ACTION_DOWN for mMultiTapMaxDelay
                            // to ensure reachability of
@@ -906,6 +910,31 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation {
            mShortcutTriggered = state;
            mMagnificationController.setForceShowMagnifiableBounds(state);
        }

        /**
         * Detects if last action down is out of distance slop between with previous
         * one, when triple tap is enabled.
         *
         * @return true if tap is out of distance slop
         */
        boolean isTapOutOfDistanceSlop() {
            if (!mDetectTripleTap) return false;
            if (mPreLastDown == null || mLastDown == null) {
                return false;
            }
            final boolean outOfDistanceSlop =
                    GestureUtils.distance(mPreLastDown, mLastDown) > mMultiTapMaxDistance;
            if (tapCount() > 0) {
                return outOfDistanceSlop;
            }
            // There's no tap in the queue here. We still need to check if this is the case that
            // user tap screen quickly and out of distance slop.
            if (outOfDistanceSlop
                    && !GestureUtils.isTimedOut(mPreLastDown, mLastDown, mMultiTapMaxDelay)) {
                return true;
            }
            return false;
        }
    }

    private void zoomOn(float centerX, float centerY) {
+35 −4
Original line number Diff line number Diff line
@@ -302,6 +302,24 @@ public class MagnificationGestureHandlerTest {
        assertZoomsImmediatelyOnSwipeFrom(STATE_SHORTCUT_TRIGGERED);
    }

    @Test
    public void testMultiTap_outOfDistanceSlop_shouldInIdle() {
        // All delay motion events should be sent, if multi-tap with out of distance slop.
        // STATE_IDLE will check if tapCount() < 2.
        allowEventDelegation();
        assertStaysIn(STATE_IDLE, () -> {
            tap();
            tap(DEFAULT_X * 2, DEFAULT_Y * 2);
        });
        assertStaysIn(STATE_IDLE, () -> {
            tap();
            tap(DEFAULT_X * 2, DEFAULT_Y * 2);
            tap();
            tap(DEFAULT_X * 2, DEFAULT_Y * 2);
            tap();
        });
    }

    private void assertZoomsImmediatelyOnSwipeFrom(int state) {
        goFromStateIdleTo(state);
        swipeAndHold();
@@ -525,6 +543,11 @@ public class MagnificationGestureHandlerTest {
        send(upEvent());
    }

    private void tap(float x, float y) {
        send(downEvent(x, y));
        send(upEvent(x, y));
    }

    private void swipe() {
        swipeAndHold();
        send(upEvent());
@@ -566,18 +589,26 @@ public class MagnificationGestureHandlerTest {
    }

    private MotionEvent downEvent() {
        return downEvent(DEFAULT_X, DEFAULT_Y);
    }

    private MotionEvent downEvent(float x, float y) {
        mLastDownTime = mClock.now();
        return fromTouchscreen(MotionEvent.obtain(mLastDownTime, mLastDownTime,
                ACTION_DOWN, DEFAULT_X, DEFAULT_Y, 0));
                ACTION_DOWN, x, y, 0));
    }

    private MotionEvent upEvent() {
        return upEvent(mLastDownTime);
        return upEvent(DEFAULT_X, DEFAULT_Y, mLastDownTime);
    }

    private MotionEvent upEvent(float x, float y) {
        return upEvent(x, y, mLastDownTime);
    }

    private MotionEvent upEvent(long downTime) {
    private MotionEvent upEvent(float x, float y, long downTime) {
        return fromTouchscreen(MotionEvent.obtain(downTime, mClock.now(),
                MotionEvent.ACTION_UP, DEFAULT_X, DEFAULT_Y, 0));
                MotionEvent.ACTION_UP, x, y, 0));
    }

    private MotionEvent pointerEvent(int action, float x, float y) {