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

Commit eb2ef423 authored by wilsonshih's avatar wilsonshih
Browse files

[PB] Handle close transition in prepare_open transition.

If the closing activity isn't launch from home, the activity will be
finish instead of moveTaskToBack, so the prepare_open transition can
also collecting the closing transition.
Check whether the closing target is inside the transition info, if it
does exists in prepare_open transition, handle it as close transition.

Flag: com.android.window.flags.migrate_predictive_back_transition
Bug: 358422448
Test: launch activity by command, close the app with gesture quickly
and verify the BackTransitionHandler can consume that transition.

Change-Id: I4981862687d204e80df8427c4eb862df5e872895
parent 81100970
Loading
Loading
Loading
Loading
+36 −18
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ import com.android.wm.shell.transition.Transitions;

import java.io.PrintWriter;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;

/**
 * Controls the window animation run when a user initiates a back gesture.
@@ -1209,7 +1210,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
            }

            if (info.getType() != WindowManager.TRANSIT_PREPARE_BACK_NAVIGATION
                    && !isGestureBackTransition(info)) {
                    && isNotGestureBackTransition(info)) {
                return false;
            }

@@ -1364,7 +1365,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
            // try to handle unexpected transition
            mergePendingTransitions(info);

            if (!isGestureBackTransition(info) || shouldCancelAnimation(info)
            if (isNotGestureBackTransition(info) || shouldCancelAnimation(info)
                    || !mCloseTransitionRequested) {
                if (mPrepareOpenTransition != null) {
                    applyFinishOpenTransition();
@@ -1395,8 +1396,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont

        // Cancel close animation if something happen unexpected, let another handler to handle
        private boolean shouldCancelAnimation(@NonNull TransitionInfo info) {
            final boolean noCloseAllowed =
                    info.getType() == WindowManager.TRANSIT_PREPARE_BACK_NAVIGATION;
            final boolean noCloseAllowed = !mCloseTransitionRequested
                    && info.getType() == WindowManager.TRANSIT_PREPARE_BACK_NAVIGATION;
            boolean unableToHandle = false;
            boolean filterTargets = false;
            for (int i = info.getChanges().size() - 1; i >= 0; --i) {
@@ -1455,7 +1456,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
            if (info.getType() != WindowManager.TRANSIT_PREPARE_BACK_NAVIGATION) {
                return false;
            }

            // Must have open target, must not have close target.
            if (hasAnimationInMode(info, TransitionUtil::isClosingMode)
                    || !hasAnimationInMode(info, TransitionUtil::isOpeningMode)) {
                return false;
            }
            SurfaceControl openingLeash = null;
            if (mApps != null) {
                for (int i = mApps.length - 1; i >= 0; --i) {
@@ -1482,17 +1487,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
            return true;
        }

        private boolean isGestureBackTransition(@NonNull TransitionInfo info) {
            for (int i = info.getChanges().size() - 1; i >= 0; --i) {
                final TransitionInfo.Change c = info.getChanges().get(i);
                if (c.hasFlags(FLAG_BACK_GESTURE_ANIMATED)
                        && (TransitionUtil.isOpeningMode(c.getMode())
                        || TransitionUtil.isClosingMode(c.getMode()))) {
                    return true;
                }
            }
            return false;
        }
        /**
         * Check whether this transition is triggered from back gesture commitment.
         * Reparent the transition targets to animation leashes, so the animation won't be broken.
@@ -1501,10 +1495,18 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
                @NonNull SurfaceControl.Transaction st,
                @NonNull SurfaceControl.Transaction ft,
                @NonNull Transitions.TransitionFinishCallback finishCallback) {
            if (info.getType() == WindowManager.TRANSIT_PREPARE_BACK_NAVIGATION
                    || !mCloseTransitionRequested) {
            if (!mCloseTransitionRequested) {
                return false;
            }
            // must have close target
            if (!hasAnimationInMode(info, TransitionUtil::isClosingMode)) {
                return false;
            }
            if (mApps == null) {
                // animation is done
                applyAndFinish(st, ft, finishCallback);
                return true;
            }
            SurfaceControl openingLeash = null;
            SurfaceControl closingLeash = null;
            for (int i = mApps.length - 1; i >= 0; --i) {
@@ -1522,6 +1524,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
                        final Point offset = c.getEndRelOffset();
                        st.setPosition(c.getLeash(), offset.x, offset.y);
                        st.reparent(c.getLeash(), openingLeash);
                        st.setAlpha(c.getLeash(), 1.0f);
                    } else if (TransitionUtil.isClosingMode(c.getMode())) {
                        st.reparent(c.getLeash(), closingLeash);
                    }
@@ -1592,6 +1595,21 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
        }
    }

    private static boolean isNotGestureBackTransition(@NonNull TransitionInfo info) {
        return !hasAnimationInMode(info, TransitionUtil::isOpenOrCloseMode);
    }

    private static boolean hasAnimationInMode(@NonNull TransitionInfo info,
            Predicate<Integer> mode) {
        for (int i = info.getChanges().size() - 1; i >= 0; --i) {
            final TransitionInfo.Change c = info.getChanges().get(i);
            if (c.hasFlags(FLAG_BACK_GESTURE_ANIMATED) && mode.test(c.getMode())) {
                return true;
            }
        }
        return false;
    }

    private static ComponentName findComponentName(TransitionInfo.Change change) {
        final ComponentName componentName = change.getActivityComponent();
        if (componentName != null) {