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

Commit 908614ab authored by Wei Sheng Shih's avatar Wei Sheng Shih Committed by Android (Google) Code Review
Browse files

Merge "Allow a back gesture to interrupt a transition." into main

parents 3bf1d949 95d39939
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -73,6 +73,13 @@ public final class BackNavigationInfo implements Parcelable {
     */
    public static final int TYPE_CALLBACK = 4;

    /**
     * A {@link OnBackInvokedCallback} is not available due to a transition is happening.
     * <p>
     * @hide
     */
    public static final int TYPE_IN_TRANSITION = 5;

    /**
     * Key to access the boolean value passed in {#mOnBackNavigationDone} result bundle
     * that represents if back navigation has been triggered.
@@ -106,7 +113,8 @@ public final class BackNavigationInfo implements Parcelable {
            TYPE_RETURN_TO_HOME,
            TYPE_CROSS_ACTIVITY,
            TYPE_CROSS_TASK,
            TYPE_CALLBACK
            TYPE_CALLBACK,
            TYPE_IN_TRANSITION
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface BackTargetType {
@@ -339,6 +347,8 @@ public final class BackNavigationInfo implements Parcelable {
                return "TYPE_CROSS_TASK";
            case TYPE_CALLBACK:
                return "TYPE_CALLBACK";
            case TYPE_IN_TRANSITION:
                return "TYPE_IN_TRANSITION";
        }
        return String.valueOf(type);
    }
+10 −0
Original line number Diff line number Diff line
@@ -404,6 +404,16 @@ flag {
    }
}

flag {
    name: "predictive_back_intercept_transition"
    namespace: "windowing_frontend"
    description: "Allows back gesture to intercept a running transition."
    bug: "426448018"
    metadata {
      purpose: PURPOSE_BUGFIX
    }
}

flag {
    name: "current_animator_scale_uses_shared_memory"
    namespace: "wear_system_health"
+48 −17
Original line number Diff line number Diff line
@@ -159,6 +159,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
     * (and navigation) associated with {@link #mCurrentTracker} have not yet finished.
     */
    private BackTouchTracker mQueuedTracker = new BackTouchTracker();
    private final TransitionIdleRunner mTransitionIdleRunner = new TransitionIdleRunner();

    private final BackTransitionObserver mBackTransitionObserver =
            new BackTransitionObserver();
@@ -470,9 +471,17 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
            tryPilferPointers();
        }

        if (predictiveBackDelayWmTransition()) {
        startPredictiveBackAnimationIfNeeded();
    }

    private void startPredictiveBackAnimationIfNeeded() {
        if (!predictiveBackDelayWmTransition() || !mThresholdCrossed) {
            return;
        }
        mShellExecutor.execute(() -> {
                if (shouldDispatchToAnimator()) {
            if (!shouldDispatchToAnimator()) {
                return;
            }
            try {
                mActivityTaskManager.startPredictiveBackAnimation();
            } catch (RemoteException r) {
@@ -485,10 +494,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
                mActiveCallback = null;
            }
            requestTopUi(true, backType);
                }
        });
    }
    }

    private boolean isAppProgressGenerationAllowed() {
        return mBackNavigationInfo.isAppProgressGenerationAllowed()
@@ -624,6 +631,22 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
        }
    }

    private class TransitionIdleRunner implements Runnable {
        boolean mIsEnable;

        @Override
        public void run() {
            if (!mIsEnable || !mCurrentTracker.isActive()) {
                return;
            }
            ProtoLog.d(WM_SHELL_BACK_PREVIEW, "Gesture hasn't finish after transition "
                    + "idle, start back navigation again.");
            mIsEnable = false;
            startBackNavigation(mCurrentTracker);
            startPredictiveBackAnimationIfNeeded();
        }
    }

    private void onBackNavigationInfoReceived(@Nullable BackNavigationInfo backNavigationInfo,
            @NonNull BackTouchTracker touchTracker) {
        ProtoLog.d(WM_SHELL_BACK_PREVIEW, "Received backNavigationInfo:%s", backNavigationInfo);
@@ -635,6 +658,13 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
            return;
        }
        final int backType = backNavigationInfo.getType();
        if (backType == BackNavigationInfo.TYPE_IN_TRANSITION) {
            mBackNavigationInfo = null;
            tryPilferPointers();
            mTransitionIdleRunner.mIsEnable = true;
            mTransitions.runOnIdle(() -> mShellExecutor.execute(mTransitionIdleRunner));
            return;
        }
        final boolean shouldDispatchToAnimator = shouldDispatchToAnimator();
        if (shouldDispatchToAnimator) {
            if (!predictiveBackDelayWmTransition()) {
@@ -859,6 +889,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
        mPointersPilfered = false;
        mBackGestureStarted = false;
        activeTouchTracker.setState(BackTouchTracker.TouchTrackerState.FINISHED);
        mTransitionIdleRunner.mIsEnable = false;

        if (mPostCommitAnimationInProgress) {
            ProtoLog.w(WM_SHELL_BACK_PREVIEW, "Animation is still running");
+15 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.platform.test.annotations.EnableFlags;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.IRemoteAnimationRunner;
@@ -81,6 +82,7 @@ import android.window.WindowContainerToken;
import androidx.annotation.Nullable;
import androidx.test.filters.SmallTest;

import com.android.window.flags.Flags;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.TestShellExecutor;
@@ -276,6 +278,19 @@ public class BackAnimationControllerTest extends ShellTestCase {
        }
    }

    @EnableFlags(Flags.FLAG_PREDICTIVE_BACK_INTERCEPT_TRANSITION)
    @Test
    public void noStartInTransition() throws RemoteException {
        registerAnimation(BackNavigationInfo.TYPE_RETURN_TO_HOME);
        createNavigationInfo(BackNavigationInfo.TYPE_IN_TRANSITION,
                /* enableAnimation = */ true,
                /* isAnimationCallback = */ false);

        doStartEvents(0, 100);
        verify(mAppCallback, never()).onBackStarted(any());
        verify(mTransitions).runOnIdle(any());
    }

    @Test
    public void backToHome_dispatchesEvents() throws RemoteException {
        registerAnimation(BackNavigationInfo.TYPE_RETURN_TO_HOME);
+16 −4
Original line number Diff line number Diff line
@@ -98,9 +98,13 @@ class BackNavigationController {
    // back animation.
    private AnimationHandler.ScheduleAnimationBuilder mCurrentAnimationBuilder;

    // This will be set if the back navigation is in progress and the current transition is still
    // running. The pending animation builder will do the animation stuff includes creating leashes,
    // re-parenting leashes and set launch behind, etc. Will be handled when transition finished.
    /**
     * This will be set if the back navigation is in progress and the current transition is still
     * running. The pending animation builder will do the animation stuff includes creating leashes,
     * re-parenting leashes and set launch behind, etc. Will be handled when transition finished.
     *
     * @deprecated Remove after Flags#predictive_back_intercept_transition
     */
    private AnimationHandler.ScheduleAnimationBuilder mPendingAnimationBuilder;

    private static int sDefaultAnimationResId;
@@ -228,6 +232,13 @@ class BackNavigationController {
                return null;
            }

            if (Flags.predictiveBackInterceptTransition()
                    && window.mTransitionController.inTransition()) {
                infoBuilder.setType(BackNavigationInfo.TYPE_IN_TRANSITION);
                ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "A transition is happening.");
                return infoBuilder.build();
            }

            final ArrayList<EmbeddedWindowController.EmbeddedWindow> embeddedWindows = wmService
                    .mEmbeddedWindowController.getByHostWindow(window);

@@ -2223,7 +2234,8 @@ class BackNavigationController {
    }

    private void scheduleAnimationInner(AnimationHandler.ScheduleAnimationBuilder builder) {
        if (mWindowManagerService.mAtmService.getTransitionController().inTransition()) {
        if (!Flags.predictiveBackInterceptTransition()
                && mWindowManagerService.mAtmService.getTransitionController().inTransition()) {
            ProtoLog.w(WM_DEBUG_BACK_PREVIEW,
                    "Pending back animation due to another animation is running");
            mPendingAnimationBuilder = builder;
Loading