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

Commit efd99108 authored by Shan Huang's avatar Shan Huang Committed by Android (Google) Code Review
Browse files

Merge "Delay onBackStarted() until the pointer is pilfered." into main

parents a3a17cad b0980cb3
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -48,6 +48,11 @@ public interface BackAnimation {
            int keyAction,
            @BackEvent.SwipeEdge int swipeEdge);

    /**
     * Called when the input pointers are pilfered.
     */
    void onPilferPointers();

    /**
     * Sets whether the back gesture is past the trigger threshold or not.
     */
+28 −5
Original line number Diff line number Diff line
@@ -111,6 +111,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont

    /** Tracks if we should start the back gesture on the next motion move event */
    private boolean mShouldStartOnNextMoveEvent = false;
    private boolean mOnBackStartDispatched = false;

    private final FlingAnimationUtils mFlingAnimationUtils;

@@ -303,6 +304,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
                    /* swipeEdge = */ swipeEdge));
        }

        @Override
        public void onPilferPointers() {
            BackAnimationController.this.onPilferPointers();
        }

        @Override
        public void setTriggerBack(boolean triggerBack) {
            mShellExecutor.execute(() -> BackAnimationController.this.setTriggerBack(triggerBack));
@@ -384,6 +390,16 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
        return null;
    }

    @VisibleForTesting
    void onPilferPointers() {
        mCurrentTracker.updateStartLocation();
        // Dispatch onBackStarted, only to app callbacks.
        // System callbacks will receive onBackStarted when the remote animation starts.
        if (!shouldDispatchToAnimator()) {
            tryDispatchOnBackStarted(mActiveCallback, mCurrentTracker.createStartEvent(null));
        }
    }

    /**
     * Called when a new motion event needs to be transferred to this
     * {@link BackAnimationController}
@@ -483,12 +499,15 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
            mActiveCallback = mBackNavigationInfo.getOnBackInvokedCallback();
            // App is handling back animation. Cancel system animation latency tracking.
            cancelLatencyTracking();
            dispatchOnBackStarted(mActiveCallback, touchTracker.createStartEvent(null));
            tryDispatchOnBackStarted(mActiveCallback, touchTracker.createStartEvent(null));
        }
    }

    private void onMove() {
        if (!mBackGestureStarted || mBackNavigationInfo == null || mActiveCallback == null) {
        if (!mBackGestureStarted
                || mBackNavigationInfo == null
                || mActiveCallback == null
                || !mOnBackStartDispatched) {
            return;
        }
        // Skip dispatching if the move corresponds to the queued instead of the current gesture
@@ -524,13 +543,14 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
                && mBackNavigationInfo.isPrepareRemoteAnimation();
    }

    private void dispatchOnBackStarted(IOnBackInvokedCallback callback,
    private void tryDispatchOnBackStarted(IOnBackInvokedCallback callback,
            BackMotionEvent backEvent) {
        if (callback == null) {
        if (callback == null || mOnBackStartDispatched) {
            return;
        }
        try {
            callback.onBackStarted(backEvent);
            mOnBackStartDispatched = true;
        } catch (RemoteException e) {
            Log.e(TAG, "dispatchOnBackStarted error: ", e);
        }
@@ -828,6 +848,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
    void finishBackNavigation(boolean triggerBack) {
        ProtoLog.d(WM_SHELL_BACK_PREVIEW, "BackAnimationController: finishBackNavigation()");
        mActiveCallback = null;
        mShouldStartOnNextMoveEvent = false;
        mOnBackStartDispatched = false;
        mShellBackAnimationRegistry.resetDefaultCrossActivity();
        cancelLatencyTracking();
        if (mBackNavigationInfo != null) {
@@ -909,7 +931,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
                                                                    ::onBackAnimationFinished));

                                    if (apps.length >= 1) {
                                        dispatchOnBackStarted(
                                        mCurrentTracker.updateStartLocation();
                                        tryDispatchOnBackStarted(
                                                mActiveCallback,
                                                mCurrentTracker.createStartEvent(apps[0]));
                                    }
+9 −0
Original line number Diff line number Diff line
@@ -104,6 +104,15 @@ class TouchTracker {
        mStartThresholdX = mInitTouchX;
    }

    /** Update the start location used to compute the progress
     * to the latest touch location.
     */
    void updateStartLocation() {
        mInitTouchX = mLatestTouchX;
        mInitTouchY = mLatestTouchY;
        mStartThresholdX = mInitTouchX;
    }

    void reset() {
        mInitTouchX = 0;
        mInitTouchY = 0;
+17 −21
Original line number Diff line number Diff line
@@ -182,8 +182,7 @@ public class BackAnimationControllerTest extends ShellTestCase {
    }

    private void triggerBackGesture() {
        doMotionEvent(MotionEvent.ACTION_DOWN, 0);
        doMotionEvent(MotionEvent.ACTION_MOVE, 0);
        doStartEvents(0, 0);
        mController.setTriggerBack(true);
    }

@@ -244,10 +243,7 @@ public class BackAnimationControllerTest extends ShellTestCase {
                /* enableAnimation = */ true,
                /* isAnimationCallback = */ false);

        doMotionEvent(MotionEvent.ACTION_DOWN, 0);

        // Check that back start and progress is dispatched when first move.
        doMotionEvent(MotionEvent.ACTION_MOVE, 100);
        doStartEvents(0, 100);

        simulateRemoteAnimationStart();

@@ -270,10 +266,8 @@ public class BackAnimationControllerTest extends ShellTestCase {
                /* enableAnimation = */ true,
                /* isAnimationCallback = */ true);

        doMotionEvent(MotionEvent.ACTION_DOWN, 0);

        // Check that back start and progress is dispatched when first move.
        doMotionEvent(MotionEvent.ACTION_MOVE, 100, 3000);
        doStartEvents(0, 100);

        simulateRemoteAnimationStart();

@@ -359,8 +353,7 @@ public class BackAnimationControllerTest extends ShellTestCase {
                .injectInputEvent(any(KeyEvent.class), any(Integer.class));

        // Verify that we start accepting gestures again once transition finishes.
        doMotionEvent(MotionEvent.ACTION_DOWN, 0);
        doMotionEvent(MotionEvent.ACTION_MOVE, 100);
        doStartEvents(0, 100);

        simulateRemoteAnimationStart();
        verify(mAnimatorCallback).onBackStarted(any());
@@ -399,8 +392,7 @@ public class BackAnimationControllerTest extends ShellTestCase {
                .injectInputEvent(any(KeyEvent.class), any(Integer.class));

        // Verify that we start accepting gestures again once transition finishes.
        doMotionEvent(MotionEvent.ACTION_DOWN, 0);
        doMotionEvent(MotionEvent.ACTION_MOVE, 100);
        doStartEvents(0, 100);

        simulateRemoteAnimationStart();
        verify(mAnimatorCallback).onBackStarted(any());
@@ -427,8 +419,7 @@ public class BackAnimationControllerTest extends ShellTestCase {
        mShellExecutor.flushAll();
        reset(mAnimatorCallback);

        doMotionEvent(MotionEvent.ACTION_DOWN, 0);
        doMotionEvent(MotionEvent.ACTION_MOVE, 100);
        doStartEvents(0, 100);
        simulateRemoteAnimationStart();
        verify(mAnimatorCallback).onBackStarted(any());
    }
@@ -441,9 +432,7 @@ public class BackAnimationControllerTest extends ShellTestCase {
                /* enableAnimation = */ true,
                /* isAnimationCallback = */ false);

        doMotionEvent(MotionEvent.ACTION_DOWN, 0);
        // Check that back start and progress is dispatched when first move.
        doMotionEvent(MotionEvent.ACTION_MOVE, 100);
        doStartEvents(0, 100);

        simulateRemoteAnimationStart();
        verify(mAnimatorCallback).onBackStarted(any());
@@ -563,10 +552,8 @@ public class BackAnimationControllerTest extends ShellTestCase {
                /* enableAnimation = */ true,
                /* isAnimationCallback = */ false);

        doMotionEvent(MotionEvent.ACTION_DOWN, 0);

        // Check that back start and progress is dispatched when first move.
        doMotionEvent(MotionEvent.ACTION_MOVE, 100);
        doStartEvents(0, 100);

        simulateRemoteAnimationStart();

@@ -593,6 +580,15 @@ public class BackAnimationControllerTest extends ShellTestCase {
                /* swipeEdge */ BackEvent.EDGE_LEFT);
    }

    /**
     * Simulate event sequence that starts a back navigation.
     */
    private void doStartEvents(int startX, int moveX) {
        doMotionEvent(MotionEvent.ACTION_DOWN, startX);
        mController.onPilferPointers();
        doMotionEvent(MotionEvent.ACTION_MOVE, moveX);
    }

    private void simulateRemoteAnimationStart() throws RemoteException {
        RemoteAnimationTarget animationTarget = createAnimationTarget();
        RemoteAnimationTarget[] targets = new RemoteAnimationTarget[]{animationTarget};
+2 −1
Original line number Diff line number Diff line
@@ -69,7 +69,6 @@ import androidx.annotation.DimenRes;

import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.policy.GestureNavigationSettingsObserver;
import com.android.systemui.res.R;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.flags.FeatureFlags;
@@ -81,6 +80,7 @@ import com.android.systemui.plugins.NavigationEdgeBackPlugin;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.PluginManager;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.res.R;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.InputChannelCompat;
@@ -1113,6 +1113,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
                            // Capture inputs
                            mInputMonitor.pilferPointers();
                            if (mBackAnimation != null) {
                                mBackAnimation.onPilferPointers();
                                // Notify FalsingManager that an intentional gesture has occurred.
                                mFalsingManager.isFalseTouch(BACK_GESTURE);
                            }