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

Commit 6997899d authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Remove legacy activity transition animation callback

The callback methods are only used by legacy transition, which are
no longer used.

The operation of DisplayContent#onWindowAnimationFinished is replaced
by Transition#finishTransition -> removeImeSurfaceImmediately.

Bug: 365884835
Flag: EXEMPT remove unused code
Test: CtsWindowManagerDeviceWindow
Change-Id: I5742d5e257b2a0edb1dd9ec7e2ca497dec94bf34
parent 440faf35
Loading
Loading
Loading
Loading
+0 −128
Original line number Diff line number Diff line
@@ -98,7 +98,6 @@ import static android.os.Build.VERSION_CODES.HONEYCOMB;
import static android.os.Build.VERSION_CODES.O;
import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
import static android.os.Process.SYSTEM_UID;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.ACTIVITY_EMBEDDING_GUARD_WITH_ANDROID_15;
import static android.view.WindowManager.ENABLE_ACTIVITY_EMBEDDING_FOR_ANDROID_15;
@@ -109,7 +108,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED;
import static android.view.WindowManager.PROPERTY_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING_STATE_SHARING;
import static android.view.WindowManager.TRANSIT_OLD_UNSET;
import static android.view.WindowManager.TRANSIT_RELAUNCH;
import static android.view.WindowManager.hasWindowExtensionsEnabled;
import static android.window.TransitionInfo.FLAGS_IS_OCCLUDED_NO_ANIMATION;
@@ -117,9 +115,7 @@ import static android.window.TransitionInfo.FLAG_IS_OCCLUDED;
import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;

import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_ADD_REMOVE;
import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_ANIM;
import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_APP_TRANSITIONS;
import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_APP_TRANSITIONS_ANIM;
import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_CONFIGURATION;
import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_CONTAINERS;
import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_FOCUS;
@@ -135,8 +131,6 @@ import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANG
import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_SIZE_COMPAT_MODE;
import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__STATE__NOT_LETTERBOXED;
import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__STATE__NOT_VISIBLE;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
import static com.android.server.wm.ActivityRecord.State.DESTROYED;
import static com.android.server.wm.ActivityRecord.State.DESTROYING;
import static com.android.server.wm.ActivityRecord.State.FINISHING;
@@ -364,7 +358,6 @@ import com.android.server.uri.GrantUri;
import com.android.server.uri.NeededUriGrants;
import com.android.server.uri.UriPermissionOwner;
import com.android.server.wm.ActivityMetricsLogger.TransitionInfoSnapshot;
import com.android.server.wm.SurfaceAnimator.AnimationType;
import com.android.server.wm.WindowManagerService.H;
import com.android.window.flags.Flags;

@@ -7199,40 +7192,6 @@ final class ActivityRecord extends WindowToken {
        return candidate;
    }

    @Override
    public SurfaceControl getAnimationLeashParent() {
        // For transitions in the root pinned task (menu activity) we just let them occur as a child
        // of the root pinned task.
        // All normal app transitions take place in an animation layer which is below the root
        // pinned task but may be above the parent tasks of the given animating apps by default.
        // When a new hierarchical animation is enabled, we just let them occur as a child of the
        // parent task, i.e. the hierarchy of the surfaces is unchanged.
        if (inPinnedWindowingMode()) {
            return getRootTask().getSurfaceControl();
        } else {
            return super.getAnimationLeashParent();
        }
    }

    @VisibleForTesting
    boolean shouldAnimate() {
        return task == null || task.shouldAnimate();
    }

    /**
     * Creates a layer to apply crop to an animation.
     */
    private SurfaceControl createAnimationBoundsLayer(Transaction t) {
        ProtoLog.i(WM_DEBUG_APP_TRANSITIONS_ANIM, "Creating animation bounds layer");
        final SurfaceControl.Builder builder = makeAnimationLeash()
                .setParent(getAnimationLeashParent())
                .setName(getSurfaceControl() + " - animation-bounds")
                .setCallsite("ActivityRecord.createAnimationBoundsLayer");
        final SurfaceControl boundsLayer = builder.build();
        t.show(boundsLayer);
        return boundsLayer;
    }

    boolean isTransitionForward() {
        return (mStartingData != null && mStartingData.mIsTransitionForward)
                || mDisplayContent.isNextTransitionForward();
@@ -7243,25 +7202,6 @@ final class ActivityRecord extends WindowToken {
        // Noop as Activity may be offset for letterbox
    }

    @Override
    public void onLeashAnimationStarting(Transaction t, SurfaceControl leash) {
        // If the animation needs to be cropped then an animation bounds layer is created as a
        // child of the root pinned task or animation layer. The leash is then reparented to this
        // new layer.
        if (mNeedsAnimationBoundsLayer) {
            mTmpRect.setEmpty();
            task.getBounds(mTmpRect);
            mAnimationBoundsLayer = createAnimationBoundsLayer(t);

            // Crop to root task bounds.
            t.setLayer(leash, 0);
            t.setLayer(mAnimationBoundsLayer, getLastLayer());

            // Reparent leash to animation bounds layer.
            t.reparent(leash, mAnimationBoundsLayer);
        }
    }

    @Override
    boolean showSurfaceOnCreation() {
        return false;
@@ -7301,74 +7241,6 @@ final class ActivityRecord extends WindowToken {
        return mLastSurfaceShowing;
    }

    @Override
    public void onAnimationLeashLost(Transaction t) {
        super.onAnimationLeashLost(t);
        if (mAnimationBoundsLayer != null) {
            t.remove(mAnimationBoundsLayer);
            mAnimationBoundsLayer = null;
        }

        mNeedsAnimationBoundsLayer = false;
    }

    @Override
    protected void onAnimationFinished(@AnimationType int type, AnimationAdapter anim) {
        super.onAnimationFinished(type, anim);

        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "AR#onAnimationFinished");
        mTransit = TRANSIT_OLD_UNSET;
        mTransitFlags = 0;

        setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM | FINISH_LAYOUT_REDO_WALLPAPER,
                "ActivityRecord");

        setClientVisible(isVisible() || mVisibleRequested);

        getDisplayContent().computeImeTargetIfNeeded(this);

        ProtoLog.v(WM_DEBUG_ANIM, "Animation done in %s"
                + ": reportedVisible=%b okToDisplay=%b okToAnimate=%b startingDisplayed=%b",
                this, reportedVisible, okToDisplay(), okToAnimate(),
                isStartingWindowDisplayed());

        // WindowState.onExitAnimationDone might modify the children list, so make a copy and then
        // traverse the copy.
        final ArrayList<WindowState> children = new ArrayList<>(mChildren);
        children.forEach(WindowState::onExitAnimationDone);
        // The starting window could transfer to another activity after app transition started, in
        // that case the latest top activity might not receive exit animation done callback if the
        // starting window didn't applied exit animation success. Notify animation finish to the
        // starting window if needed.
        if (task != null && startingMoved) {
            final WindowState transferredStarting = task.getWindow(w ->
                    w.mAttrs.type == TYPE_APPLICATION_STARTING);
            if (transferredStarting != null && transferredStarting.mAnimatingExit
                    && !transferredStarting.isSelfAnimating(0 /* flags */,
                    ANIMATION_TYPE_WINDOW_ANIMATION)) {
                transferredStarting.onExitAnimationDone();
            }
        }

        scheduleAnimation();

        // Schedule to handle the stopping and finishing activities which the animation is done
        // because the activities which were animating have not been stopped yet.
        mTaskSupervisor.scheduleProcessStoppingAndFinishingActivitiesIfNeeded();
        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
    }

    void clearAnimatingFlags() {
        boolean wallpaperMightChange = false;
        for (int i = mChildren.size() - 1; i >= 0; i--) {
            final WindowState win = mChildren.get(i);
            wallpaperMightChange |= win.clearAnimatingFlags();
        }
        if (wallpaperMightChange) {
            requestUpdateWallpaperIfNeeded();
        }
    }

    public @TransitionOldType int getTransit() {
        return mTransit;
    }
+0 −16
Original line number Diff line number Diff line
@@ -4982,22 +4982,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        return win != null;
    }

    /**
     * Callbacks when the given type of {@link WindowContainer} animation finished running in the
     * hierarchy.
     */
    void onWindowAnimationFinished(@NonNull WindowContainer wc, int type) {
        if (mImeScreenshot != null) {
            ProtoLog.i(WM_DEBUG_IME,
                    "onWindowAnimationFinished, wc=%s, type=%s, imeSnapshot=%s, target=%s",
                    wc, SurfaceAnimator.animationTypeToString(type), mImeScreenshot,
                    mImeScreenshot.getImeTarget());
        }
        if ((type & WindowState.EXIT_ANIMATING_TYPES) != 0) {
            removeImeSurfaceByTarget(wc);
        }
    }

    // TODO: Super unexpected long method that should be broken down...
    void applySurfaceChangesTransaction() {
        final WindowSurfacePlacer surfacePlacer = mWmService.mWindowPlacerLocked;
+0 −82
Original line number Diff line number Diff line
@@ -55,14 +55,12 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;

import android.annotation.CallSuper;
import android.annotation.ColorInt;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.pm.ActivityInfo;
import android.content.pm.ActivityInfo.ScreenOrientation;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Debug;
@@ -105,7 +103,6 @@ import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -218,14 +215,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
    protected final WindowManagerService mWmService;
    final TransitionController mTransitionController;

    /**
     * Sources which triggered a surface animation on this container. An animation target can be
     * promoted to higher level, for example, from a set of {@link ActivityRecord}s to
     * {@link Task}. In this case, {@link ActivityRecord}s are set on this variable while
     * the animation is running, and reset after finishing it.
     */
    private final ArraySet<WindowContainer> mSurfaceAnimationSources = new ArraySet<>();

    private final Point mTmpPos = new Point();
    protected final Point mLastSurfacePosition = new Point();
    protected @Surface.Rotation int mLastDeltaRotation = Surface.ROTATION_0;
@@ -279,17 +268,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
     */
    int mTransitFlags;

    /** Layer used to constrain the animation to a container's stack bounds. */
    SurfaceControl mAnimationBoundsLayer;

    /** Whether this container needs to create mAnimationBoundsLayer for cropping animations. */
    boolean mNeedsAnimationBoundsLayer;

    /**
     * This gets used during some open/close transitions as well as during a change transition
     * where it represents the starting-state snapshot.
     */
    final Point mTmpPoint = new Point();
    protected final Rect mTmpRect = new Rect();
    final Rect mTmpPrevBounds = new Rect();

@@ -2961,7 +2939,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
    }

    void cancelAnimation() {
        doAnimationFinished(mSurfaceAnimator.getAnimationType(), mSurfaceAnimator.getAnimation());
        mSurfaceAnimator.cancelAnimation();
    }

@@ -2992,10 +2969,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
                || (getParent() != null && getParent().inPinnedWindowingMode());
    }

    ArraySet<WindowContainer> getAnimationSources() {
        return mSurfaceAnimationSources;
    }

    @Override
    public Builder makeAnimationLeash() {
        return makeSurface().setContainerLayer();
@@ -3094,21 +3067,10 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
        return mAnimationLeash;
    }

    private void doAnimationFinished(@AnimationType int type, AnimationAdapter anim) {
        for (int i = 0; i < mSurfaceAnimationSources.size(); ++i) {
            mSurfaceAnimationSources.valueAt(i).onAnimationFinished(type, anim);
        }
        mSurfaceAnimationSources.clear();
        if (mDisplayContent != null) {
            mDisplayContent.onWindowAnimationFinished(this, type);
        }
    }

    /**
     * Called when an animation has finished running.
     */
    protected void onAnimationFinished(@AnimationType int type, AnimationAdapter anim) {
        doAnimationFinished(type, anim);
        mWmService.onAnimationFinished();
    }

@@ -3821,50 +3783,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
        return true;
    }

    private class AnimationRunnerBuilder {
        /**
         * Runs when the surface stops animating
         */
        private final List<Runnable> mOnAnimationFinished = new LinkedList<>();
        /**
         * Runs when the animation is cancelled but the surface is still animating
         */
        private final List<Runnable> mOnAnimationCancelled = new LinkedList<>();

        private void setTaskBackgroundColor(@ColorInt int backgroundColor) {
            TaskDisplayArea taskDisplayArea = getTaskDisplayArea();

            if (taskDisplayArea != null && backgroundColor != Color.TRANSPARENT) {
                taskDisplayArea.setBackgroundColor(backgroundColor);

                // Atomic counter to make sure the clearColor callback is only called one.
                // It will be called twice in the case we cancel the animation without restart
                // (in that case it will run as the cancel and finished callbacks).
                final AtomicInteger callbackCounter = new AtomicInteger(0);
                final Runnable clearBackgroundColorHandler = () -> {
                    if (callbackCounter.getAndIncrement() == 0) {
                        taskDisplayArea.clearBackgroundColor();
                    }
                };

                // We want to make sure this is called both when the surface stops animating and
                // also when an animation is cancelled (i.e. animation is replaced by another
                // animation but and so the surface is still animating)
                mOnAnimationFinished.add(clearBackgroundColorHandler);
                mOnAnimationCancelled.add(clearBackgroundColorHandler);
            }
        }

        private IAnimationStarter build() {
            return (Transaction t, AnimationAdapter adapter, boolean hidden,
                    @AnimationType int type, @Nullable AnimationAdapter snapshotAnim) -> {
                startAnimation(getPendingTransaction(), adapter, !isVisible(), type,
                        (animType, anim) -> mOnAnimationFinished.forEach(Runnable::run),
                        () -> mOnAnimationCancelled.forEach(Runnable::run), snapshotAnim);
            };
        }
    }

    private interface IAnimationStarter {
        void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
                @AnimationType int type, @Nullable AnimationAdapter snapshotAnim);
+0 −34
Original line number Diff line number Diff line
@@ -4689,40 +4689,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        return super.handleCompleteDeferredRemoval();
    }

    boolean clearAnimatingFlags() {
        boolean didSomething = false;
        // We also don't clear the mAnimatingExit flag for windows which have the
        // mRemoveOnExit flag. This indicates an explicit remove request has been issued
        // by the client. We should let animation proceed and not clear this flag or
        // they won't eventually be removed by WindowStateAnimator#finishExit.
        if (!mRemoveOnExit) {
            // Clear mAnimating flag together with mAnimatingExit. When animation
            // changes from exiting to entering, we need to clear this flag until the
            // new animation gets applied, so that isAnimationStarting() becomes true
            // until then.
            // Otherwise applySurfaceChangesTransaction will fail to skip surface
            // placement for this window during this period, one or more frame will
            // show up with wrong position or scale.
            if (mAnimatingExit) {
                mAnimatingExit = false;
                ProtoLog.d(WM_DEBUG_ANIM, "Clear animatingExit: reason=clearAnimatingFlags win=%s",
                        this);
                didSomething = true;
            }
            if (mDestroying) {
                mDestroying = false;
                mWmService.mDestroySurface.remove(this);
                didSomething = true;
            }
        }

        for (int i = mChildren.size() - 1; i >= 0; --i) {
            didSomething |= (mChildren.get(i)).clearAnimatingFlags();
        }

        return didSomething;
    }

    public boolean isRtl() {
        return getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
    }
+0 −20
Original line number Diff line number Diff line
@@ -561,26 +561,6 @@ public class WindowStateTests extends WindowTestsBase {
        assertTrue(child2.isSelfOrAncestorWindowAnimatingExit());
    }

    @Test
    public void testDeferredRemovalByAnimating() {
        final WindowState appWindow = newWindowBuilder("appWindow", TYPE_APPLICATION).build();
        makeWindowVisible(appWindow);
        spyOn(appWindow.mWinAnimator);
        doReturn(true).when(appWindow.mWinAnimator).getShown();
        final AnimationAdapter animation = mock(AnimationAdapter.class);
        final ActivityRecord activity = appWindow.mActivityRecord;
        activity.startAnimation(appWindow.getPendingTransaction(),
                animation, false /* hidden */, SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION);

        appWindow.removeIfPossible();
        assertTrue(appWindow.mAnimatingExit);
        assertFalse(appWindow.mRemoved);

        activity.cancelAnimation();
        assertFalse(appWindow.mAnimatingExit);
        assertTrue(appWindow.mRemoved);
    }

    @Test
    public void testOnExitAnimationDone() {
        final WindowState parent = newWindowBuilder("parent", TYPE_APPLICATION).build();