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

Commit 5210e944 authored by Eugene Susla's avatar Eugene Susla
Browse files

Couple fixes for M11nGestureHandler

1. Added missing defensive copy for a MotionEvent that is posted
asynchronously with delay, and thus might get recycled
2. Fixed transitioning to viewport dragging on 3tap/shortcut+swipe

Test: manually ensure the fix is working
Bug: 73359125
Change-Id: Iae8cd3a83512ee363abe9f0b5702287d7616c092
parent aa2c46cc
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -86,4 +86,16 @@ public class ExceptionUtils {
        while (t.getCause() != null) t = t.getCause();
        return t;
    }

    /**
     * Appends {@code cause} at the end of the causal chain of {@code t}
     *
     * @return {@code t} for convenience
     */
    public static @NonNull Throwable appendCause(@NonNull Throwable t, @Nullable Throwable cause) {
        if (cause != null) {
            getRootCause(t).initCause(cause);
        }
        return t;
    }
}
 No newline at end of file
+10 −8
Original line number Diff line number Diff line
@@ -402,9 +402,9 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation {
                    com.android.internal.R.dimen.config_screen_magnification_scaling_threshold,
                    scaleValue, false);
            mScalingThreshold = scaleValue.getFloat();
            mScaleGestureDetector = new ScaleGestureDetector(context, this);
            mScaleGestureDetector = new ScaleGestureDetector(context, this, Handler.getMain());
            mScaleGestureDetector.setQuickScaleEnabled(false);
            mScrollGestureDetector = new GestureDetector(context, this);
            mScrollGestureDetector = new GestureDetector(context, this, Handler.getMain());
        }

        @Override
@@ -638,7 +638,7 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation {

        @VisibleForTesting boolean mShortcutTriggered;

        @VisibleForTesting Handler mHandler = new Handler(this);
        @VisibleForTesting Handler mHandler = new Handler(Looper.getMainLooper(), this);

        public DetectingState(Context context) {
            mLongTapMinDelay = ViewConfiguration.getLongPressTimeout();
@@ -654,7 +654,9 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation {
            final int type = message.what;
            switch (type) {
                case MESSAGE_ON_TRIPLE_TAP_AND_HOLD: {
                    onTripleTapAndHold(/* down */ (MotionEvent) message.obj);
                    MotionEvent down = (MotionEvent) message.obj;
                    transitionToViewportDraggingStateAndClear(down);
                    down.recycle();
                }
                break;
                case MESSAGE_TRANSITION_TO_DELEGATING_STATE: {
@@ -720,8 +722,7 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation {
                        // over insta-delegating on 3tap&swipe
                        // (which is a rare combo to be used aside from magnification)
                        if (isMultiTapTriggered(2 /* taps */)) {
                            transitionTo(mViewportDraggingState);
                            clear();
                            transitionToViewportDraggingStateAndClear(event);
                        } else {
                            transitionToDelegatingStateAndClear();
                        }
@@ -806,7 +807,8 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation {
        /** -> {@link ViewportDraggingState} */
        public void afterLongTapTimeoutTransitionToDraggingState(MotionEvent event) {
            mHandler.sendMessageDelayed(
                    mHandler.obtainMessage(MESSAGE_ON_TRIPLE_TAP_AND_HOLD, event),
                    mHandler.obtainMessage(MESSAGE_ON_TRIPLE_TAP_AND_HOLD,
                            MotionEvent.obtain(event)),
                    ViewConfiguration.getLongPressTimeout());
        }

@@ -890,7 +892,7 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation {
            }
        }

        void onTripleTapAndHold(MotionEvent down) {
        void transitionToViewportDraggingStateAndClear(MotionEvent down) {

            if (DEBUG_DETECTING) Slog.i(LOG_TAG, "onTripleTapAndHold()");
            clear();
+17 −3
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@ import static org.mockito.Mockito.verify;

import android.annotation.NonNull;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
@@ -49,9 +48,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.concurrent.CompletableFuture;
import java.util.function.IntConsumer;
import java.util.function.Supplier;


/**
@@ -283,6 +280,19 @@ public class MagnificationGestureHandlerTest {
        verify(mMgh.getNext(), times(2)).onMotionEvent(any(), any(), anyInt());
    }

    @Test
    public void testTripleTapAndHold_zoomsImmediately() {
        assertZoomsImmediatelyOnSwipeFrom(STATE_2TAPS);
        assertZoomsImmediatelyOnSwipeFrom(STATE_SHORTCUT_TRIGGERED);
    }

    private void assertZoomsImmediatelyOnSwipeFrom(int state) {
        goFromStateIdleTo(state);
        swipeAndHold();
        assertIn(STATE_DRAGGING_TMP);
        returnToNormalFrom(STATE_DRAGGING_TMP);
    }

    private void assertTransition(int fromState, Runnable transitionAction, int toState) {
        goFromStateIdleTo(fromState);
        transitionAction.run();
@@ -339,11 +349,13 @@ public class MagnificationGestureHandlerTest {
                check(tapCount() == 2, state);
            } break;
            case STATE_DRAGGING: {
                check(isZoomed(), state);
                check(mMgh.mCurrentState == mMgh.mViewportDraggingState,
                        state);
                check(mMgh.mViewportDraggingState.mZoomedInBeforeDrag, state);
            } break;
            case STATE_DRAGGING_TMP: {
                check(isZoomed(), state);
                check(mMgh.mCurrentState == mMgh.mViewportDraggingState,
                        state);
                check(!mMgh.mViewportDraggingState.mZoomedInBeforeDrag, state);
@@ -353,11 +365,13 @@ public class MagnificationGestureHandlerTest {
                check(!isZoomed(), state);
            } break;
            case STATE_PANNING: {
                check(isZoomed(), state);
                check(mMgh.mCurrentState == mMgh.mPanningScalingState,
                        state);
                check(!mMgh.mPanningScalingState.mScaling, state);
            } break;
            case STATE_SCALING_AND_PANNING: {
                check(isZoomed(), state);
                check(mMgh.mCurrentState == mMgh.mPanningScalingState,
                        state);
                check(mMgh.mPanningScalingState.mScaling, state);
+4 −3
Original line number Diff line number Diff line
@@ -16,10 +16,11 @@
package com.android.server.testutils;


import static android.util.ExceptionUtils.getRootCause;
import static android.util.ExceptionUtils.appendCause;
import static android.util.ExceptionUtils.propagate;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.util.ArrayMap;
@@ -60,7 +61,7 @@ public class TestHandler extends Handler {
    }

    public TestHandler(Callback callback, LongSupplier clock) {
        super(callback);
        super(Looper.getMainLooper(), callback);
        mClock = clock;
    }

@@ -132,7 +133,7 @@ public class TestHandler extends Handler {
        } catch (Throwable t) {
            // Append stack trace of this message being posted as a cause for a helpful
            // test error message
            throw propagate(getRootCause(t).initCause(msg.postPoint));
            throw propagate(appendCause(t, msg.postPoint));
        } finally {
            msg.message.recycle();
        }