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

Commit 9fd48528 authored by Evan Rosky's avatar Evan Rosky
Browse files

Add support for the no-animation intent option

Port this over from legacy transitions. The heuristic
is slightly different since shell and legacy work differently
but it should be pretty close: basically if the no-animation
is the only non-going-invisible participant, then we'll
skip the animation.

Bug: 262314590
Test: atest TransitionTests#testCreateInfo_NoAnimation
Change-Id: I5d5bc5b83417c20f03358160326ba18e3dd7f461
parent 0f0b247b
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -141,8 +141,11 @@ public final class TransitionInfo implements Parcelable {
    /** The window was animated by back gesture. */
    public static final int FLAG_BACK_GESTURE_ANIMATED = 1 << 17;

    /** The window should have no animation (by policy). */
    public static final int FLAG_NO_ANIMATION = 1 << 18;

    /** The first unused bit. This can be used by remotes to attach custom flags to this change. */
    public static final int FLAG_FIRST_CUSTOM = 1 << 18;
    public static final int FLAG_FIRST_CUSTOM = 1 << 19;

    /** The change belongs to a window that won't contain activities. */
    public static final int FLAGS_IS_NON_APP_WINDOW =
@@ -169,6 +172,7 @@ public final class TransitionInfo implements Parcelable {
            FLAG_IS_OCCLUDED,
            FLAG_IS_SYSTEM_WINDOW,
            FLAG_BACK_GESTURE_ANIMATED,
            FLAG_NO_ANIMATION,
            FLAG_FIRST_CUSTOM
    })
    public @interface ChangeFlags {}
@@ -387,6 +391,9 @@ public final class TransitionInfo implements Parcelable {
        if ((flags & FLAG_BACK_GESTURE_ANIMATED) != 0) {
            sb.append(sb.length() == 0 ? "" : "|").append("FLAG_BACK_GESTURE_ANIMATED");
        }
        if ((flags & FLAG_NO_ANIMATION) != 0) {
            sb.append(sb.length() == 0 ? "" : "|").append("NO_ANIMATION");
        }
        if ((flags & FLAG_FIRST_CUSTOM) != 0) {
            sb.append(sb.length() == 0 ? "" : "|").append("FIRST_CUSTOM");
        }
+8 −0
Original line number Diff line number Diff line
@@ -301,6 +301,14 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
            return true;
        }

        // check if no-animation and skip animation if so.
        if (Transitions.isAllNoAnimation(info)) {
            startTransaction.apply();
            finishTransaction.apply();
            finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */);
            return true;
        }

        if (mAnimations.containsKey(transition)) {
            throw new IllegalStateException("Got a duplicate startAnimation call for "
                    + transition);
+29 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.view.WindowManager.fixScale;
import static android.window.TransitionInfo.FLAG_IS_OCCLUDED;
import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
import static android.window.TransitionInfo.FLAG_NO_ANIMATION;
import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;

import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
@@ -448,6 +449,34 @@ public class Transitions implements RemoteCallable<Transitions> {
        return -1;
    }

    /**
     * Look through a transition and see if all non-closing changes are no-animation. If so, no
     * animation should play.
     */
    static boolean isAllNoAnimation(TransitionInfo info) {
        if (isClosingType(info.getType())) {
            // no-animation is only relevant for launching (open) activities.
            return false;
        }
        boolean hasNoAnimation = false;
        final int changeSize = info.getChanges().size();
        for (int i = changeSize - 1; i >= 0; --i) {
            final TransitionInfo.Change change = info.getChanges().get(i);
            if (isClosingType(change.getMode())) {
                // ignore closing apps since they are a side-effect of the transition and don't
                // animate.
                continue;
            }
            if (change.hasFlags(FLAG_NO_ANIMATION)) {
                hasNoAnimation = true;
            } else {
                // at-least one relevant participant *is* animated, so we need to animate.
                return false;
            }
        }
        return hasNoAnimation;
    }

    @VisibleForTesting
    void onTransitionReady(@NonNull IBinder transitionToken, @NonNull TransitionInfo info,
            @NonNull SurfaceControl.Transaction t, @NonNull SurfaceControl.Transaction finishT) {
+1 −1
Original line number Diff line number Diff line
@@ -5029,10 +5029,10 @@ class Task extends TaskFragment {
            final DisplayContent dc = mDisplayContent;
            if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
                    "Prepare open transition: starting " + r);
            // TODO(shell-transitions): record NO_ANIMATION flag somewhere.
            if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
                dc.prepareAppTransition(TRANSIT_NONE);
                mTaskSupervisor.mNoAnimActivities.add(r);
                mTransitionController.setNoAnimation(r);
            } else {
                dc.prepareAppTransition(TRANSIT_OPEN);
                mTaskSupervisor.mNoAnimActivities.remove(r);
+29 −1
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import static android.window.TransitionInfo.FLAG_IS_DISPLAY;
import static android.window.TransitionInfo.FLAG_IS_INPUT_METHOD;
import static android.window.TransitionInfo.FLAG_IS_VOICE_INTERACTION;
import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
import static android.window.TransitionInfo.FLAG_NO_ANIMATION;
import static android.window.TransitionInfo.FLAG_OCCLUDES_KEYGUARD;
import static android.window.TransitionInfo.FLAG_SHOW_WALLPAPER;
import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
@@ -916,6 +917,14 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
        return mRemoteTransition;
    }

    void setNoAnimation(WindowContainer wc) {
        final ChangeInfo change = mChanges.get(wc);
        if (change == null) {
            throw new IllegalStateException("Can't set no-animation property of non-participant");
        }
        change.mFlags |= ChangeInfo.FLAG_CHANGE_NO_ANIMATION;
    }

    @Override
    public void onTransactionReady(int syncId, SurfaceControl.Transaction transaction) {
        if (syncId != mSyncId) {
@@ -1442,6 +1451,11 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
                i++;
                targets.add(parent);
            }
            if ((changes.get(target).mFlags & ChangeInfo.FLAG_CHANGE_NO_ANIMATION) != 0) {
                changes.get(parent).mFlags |= ChangeInfo.FLAG_CHANGE_NO_ANIMATION;
            } else {
                changes.get(parent).mFlags |= ChangeInfo.FLAG_CHANGE_YES_ANIMATION;
            }
        }
    }

@@ -1880,11 +1894,21 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
        private static final int FLAG_TRANSIENT_LAUNCH = 2;
        private static final int FLAG_ABOVE_TRANSIENT_LAUNCH = 4;

        /** This container explicitly requested no-animation (usually Activity level). */
        private static final int FLAG_CHANGE_NO_ANIMATION = 0x8;
        /**
         * This container has at-least one child which IS animating (not marked NO_ANIMATION).
         * Used during promotion. This trumps `FLAG_NO_ANIMATION` (if both are set).
         */
        private static final int FLAG_CHANGE_YES_ANIMATION = 0x10;

        @IntDef(prefix = { "FLAG_" }, value = {
                FLAG_NONE,
                FLAG_SEAMLESS_ROTATION,
                FLAG_TRANSIENT_LAUNCH,
                FLAG_ABOVE_TRANSIENT_LAUNCH
                FLAG_ABOVE_TRANSIENT_LAUNCH,
                FLAG_CHANGE_NO_ANIMATION,
                FLAG_CHANGE_YES_ANIMATION
        })
        @Retention(RetentionPolicy.SOURCE)
        @interface Flag {}
@@ -2055,6 +2079,10 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
            if (occludesKeyguard(wc)) {
                flags |= FLAG_OCCLUDES_KEYGUARD;
            }
            if ((mFlags & FLAG_CHANGE_NO_ANIMATION) != 0
                    && (mFlags & FLAG_CHANGE_YES_ANIMATION) == 0) {
                flags |= FLAG_NO_ANIMATION;
            }
            return flags;
        }

Loading