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

Commit 5341d1c7 authored by lumark's avatar lumark
Browse files

Make WC#applyAnimation can apply on Task / TaskStack layer (1/N)

- Use WC#getDisplayContent instead WC#mDisplayContent in
WC#okToAnimation and WC#okToAnimate.

- Fix some places that calls isAnimating() needs to add PARENTS flag.

- Add unit tests to verify Task / Stack can applyAnimation with expected
  animation state.

- In Task#createRemoteAnimationTarget(), use WC#getTopMostActivity to
  get top most activity rather than using getTopVisibleActivity, to
  prevent closing activity may not get corresponding activity instance
  case.

- Fix WC#isWaitingForTransitionStart and WC#isAppTransition won't get
  correct result when animating app transition on Task / TaskStack container.

- To ensure onAppTransitionFinished will be called when enabling
  hierarchical animation, needs to let activity.onAnimationFinished()
  also be called.

- Implement Task#getAnimationBounds to get stack's bounds when
appStackClipMode is STACK_CLIP_BEFORE_ANIM.

Bug: 142617871
Bug: 131661052
Test: atest WindowContainerTests

Change-Id: Id97087819cab54ba35fb4b9ae4b5b95a572ad377
parent c4a819f5
Loading
Loading
Loading
Loading
+10 −10
Original line number Original line Diff line number Diff line
@@ -555,7 +555,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A


    private RemoteAnimationDefinition mRemoteAnimationDefinition;
    private RemoteAnimationDefinition mRemoteAnimationDefinition;


    private AnimatingActivityRegistry mAnimatingActivityRegistry;
    AnimatingActivityRegistry mAnimatingActivityRegistry;


    private Task mLastParent;
    private Task mLastParent;


@@ -3089,7 +3089,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A


        ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
        ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
                "Removing app %s delayed=%b animation=%s animating=%b", this, delayed,
                "Removing app %s delayed=%b animation=%s animating=%b", this, delayed,
                getAnimation(), isAnimating(TRANSITION));
                getAnimation(), isAnimating(PARENTS | TRANSITION));


        ProtoLog.v(WM_DEBUG_ADD_REMOVE, "removeAppToken: %s"
        ProtoLog.v(WM_DEBUG_ADD_REMOVE, "removeAppToken: %s"
                + " delayed=%b Callers=%s", this, delayed, Debug.getCallers(4));
                + " delayed=%b Callers=%s", this, delayed, Debug.getCallers(4));
@@ -3101,7 +3101,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // If this window was animating, then we need to ensure that the app transition notifies
        // If this window was animating, then we need to ensure that the app transition notifies
        // that animations have completed in DisplayContent.handleAnimatingStoppedAndTransition(),
        // that animations have completed in DisplayContent.handleAnimatingStoppedAndTransition(),
        // so add to that list now
        // so add to that list now
        if (isAnimating(TRANSITION)) {
        if (isAnimating(PARENTS | TRANSITION)) {
            getDisplayContent().mNoAnimationNotifyOnTransitionFinished.add(token);
            getDisplayContent().mNoAnimationNotifyOnTransitionFinished.add(token);
        }
        }


@@ -3437,7 +3437,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
     *         color mode set to avoid jank in the middle of the transition.
     *         color mode set to avoid jank in the middle of the transition.
     */
     */
    boolean canShowWindows() {
    boolean canShowWindows() {
        return allDrawn && !(isAnimating() && hasNonDefaultColorWindow());
        return allDrawn && !(isAnimating(PARENTS) && hasNonDefaultColorWindow());
    }
    }


    /**
    /**
@@ -5345,13 +5345,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        if (!allDrawn && w.mightAffectAllDrawn()) {
        if (!allDrawn && w.mightAffectAllDrawn()) {
            if (DEBUG_VISIBILITY || WM_DEBUG_ORIENTATION.isLogToLogcat()) {
            if (DEBUG_VISIBILITY || WM_DEBUG_ORIENTATION.isLogToLogcat()) {
                Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
                Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
                        + ", isAnimationSet=" + isAnimating(TRANSITION));
                        + ", isAnimationSet=" + isAnimating(PARENTS | TRANSITION));
                if (!w.isDrawnLw()) {
                if (!w.isDrawnLw()) {
                    Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceController
                    Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceController
                            + " pv=" + w.isVisibleByPolicy()
                            + " pv=" + w.isVisibleByPolicy()
                            + " mDrawState=" + winAnimator.drawStateToString()
                            + " mDrawState=" + winAnimator.drawStateToString()
                            + " ph=" + w.isParentWindowHidden() + " th=" + mVisibleRequested
                            + " ph=" + w.isParentWindowHidden() + " th=" + mVisibleRequested
                            + " a=" + isAnimating(TRANSITION));
                            + " a=" + isAnimating(PARENTS | TRANSITION));
                }
                }
            }
            }


@@ -5952,7 +5952,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A


    @Override
    @Override
    void prepareSurfaces() {
    void prepareSurfaces() {
        final boolean show = isVisible() || isAnimating();
        final boolean show = isVisible() || isAnimating(PARENTS);


        if (mSurfaceControl != null) {
        if (mSurfaceControl != null) {
            if (show && !mLastSurfaceShowing) {
            if (show && !mLastSurfaceShowing) {
@@ -5980,7 +5980,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    }
    }


    void attachThumbnailAnimation() {
    void attachThumbnailAnimation() {
        if (!isAnimating()) {
        if (!isAnimating(PARENTS)) {
            return;
            return;
        }
        }
        final GraphicBuffer thumbnailHeader =
        final GraphicBuffer thumbnailHeader =
@@ -6000,7 +6000,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
     * {@link android.app.ActivityOptions#ANIM_OPEN_CROSS_PROFILE_APPS} animation.
     * {@link android.app.ActivityOptions#ANIM_OPEN_CROSS_PROFILE_APPS} animation.
     */
     */
    void attachCrossProfileAppsThumbnailAnimation() {
    void attachCrossProfileAppsThumbnailAnimation() {
        if (!isAnimating()) {
        if (!isAnimating(PARENTS)) {
            return;
            return;
        }
        }
        clearThumbnail();
        clearThumbnail();
@@ -7512,7 +7512,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        super.dumpDebug(proto, WINDOW_TOKEN, logLevel);
        super.dumpDebug(proto, WINDOW_TOKEN, logLevel);
        proto.write(LAST_SURFACE_SHOWING, mLastSurfaceShowing);
        proto.write(LAST_SURFACE_SHOWING, mLastSurfaceShowing);
        proto.write(IS_WAITING_FOR_TRANSITION_START, isWaitingForTransitionStart());
        proto.write(IS_WAITING_FOR_TRANSITION_START, isWaitingForTransitionStart());
        proto.write(IS_ANIMATING, isAnimating());
        proto.write(IS_ANIMATING, isAnimating(PARENTS));
        if (mThumbnail != null){
        if (mThumbnail != null){
            mThumbnail.dumpDebug(proto, THUMBNAIL);
            mThumbnail.dumpDebug(proto, THUMBNAIL);
        }
        }
+12 −0
Original line number Original line Diff line number Diff line
@@ -4889,6 +4889,18 @@ class ActivityStack extends WindowContainer<WindowContainer> implements BoundsAn
        }
        }
    }
    }


    @Override
    protected void onAnimationFinished() {
        super.onAnimationFinished();
        // TODO(b/142617871): we may need to add animation type parameter on onAnimationFinished to
        //  identify if the callback is for launch animation finish and then calling
        //  activity#onAnimationFinished.
        final ActivityRecord activity = getTopMostActivity();
        if (activity != null) {
            activity.onAnimationFinished();
        }
    }

    /**
    /**
     * Sets the current picture-in-picture aspect ratio.
     * Sets the current picture-in-picture aspect ratio.
     */
     */
+1 −1
Original line number Original line Diff line number Diff line
@@ -3360,7 +3360,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
                // to look at all windows below the current target that are in this app, finding the
                // to look at all windows below the current target that are in this app, finding the
                // highest visible one in layering.
                // highest visible one in layering.
                WindowState highestTarget = null;
                WindowState highestTarget = null;
                if (activity.isAnimating(TRANSITION)) {
                if (activity.isAnimating(PARENTS | TRANSITION)) {
                    highestTarget = activity.getHighestAnimLayerWindow(curTarget);
                    highestTarget = activity.getHighestAnimLayerWindow(curTarget);
                }
                }


+3 −2
Original line number Original line Diff line number Diff line
@@ -378,9 +378,10 @@ class RemoteAnimationController implements DeathRecipient {


        int getMode() {
        int getMode() {
            final DisplayContent dc = mWindowContainer.getDisplayContent();
            final DisplayContent dc = mWindowContainer.getDisplayContent();
            if (dc.mOpeningApps.contains(mWindowContainer)) {
            final ActivityRecord topActivity = mWindowContainer.getTopMostActivity();
            if (dc.mOpeningApps.contains(topActivity)) {
                return RemoteAnimationTarget.MODE_OPENING;
                return RemoteAnimationTarget.MODE_OPENING;
            } else if (dc.mChangingApps.contains(mWindowContainer)) {
            } else if (dc.mChangingApps.contains(topActivity)) {
                return RemoteAnimationTarget.MODE_CHANGING;
                return RemoteAnimationTarget.MODE_CHANGING;
            } else {
            } else {
                return RemoteAnimationTarget.MODE_CLOSING;
                return RemoteAnimationTarget.MODE_CLOSING;
+24 −1
Original line number Original line Diff line number Diff line
@@ -94,6 +94,7 @@ import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;


import static java.lang.Integer.MAX_VALUE;
import static java.lang.Integer.MAX_VALUE;


@@ -2555,6 +2556,16 @@ class Task extends WindowContainer<WindowContainer> {
        return getAppAnimationLayer(ANIMATION_LAYER_HOME);
        return getAppAnimationLayer(ANIMATION_LAYER_HOME);
    }
    }


    @Override
    Rect getAnimationBounds(int appStackClipMode) {
        // TODO(b/131661052): we should remove appStackClipMode with hierarchical animations.
        if (appStackClipMode == STACK_CLIP_BEFORE_ANIM && getStack() != null) {
            // Using the stack bounds here effectively applies the clipping before animation.
            return getStack().getBounds();
        }
        return super.getAnimationBounds(appStackClipMode);
    }

    boolean shouldAnimate() {
    boolean shouldAnimate() {
        // Don't animate while the task runs recents animation but only if we are in the mode
        // Don't animate while the task runs recents animation but only if we are in the mode
        // where we cancel with deferred screenshot, which means that the controller has
        // where we cancel with deferred screenshot, which means that the controller has
@@ -2567,6 +2578,18 @@ class Task extends WindowContainer<WindowContainer> {
        return true;
        return true;
    }
    }


    @Override
    protected void onAnimationFinished() {
        super.onAnimationFinished();
        // TODO(b/142617871): we may need to add animation type parameter on onAnimationFinished to
        //  identify if the callback is for launch animation finish and then calling
        //  activity#onAnimationFinished.
        final ActivityRecord activity = getTopMostActivity();
        if (activity != null) {
            activity.onAnimationFinished();
        }
    }

    @Override
    @Override
    SurfaceControl.Builder makeSurface() {
    SurfaceControl.Builder makeSurface() {
        return super.makeSurface().setMetadata(METADATA_TASK_ID, mTaskId);
        return super.makeSurface().setMetadata(METADATA_TASK_ID, mTaskId);
@@ -2594,7 +2617,7 @@ class Task extends WindowContainer<WindowContainer> {
    @Override
    @Override
    RemoteAnimationTarget createRemoteAnimationTarget(
    RemoteAnimationTarget createRemoteAnimationTarget(
            RemoteAnimationController.RemoteAnimationRecord record) {
            RemoteAnimationController.RemoteAnimationRecord record) {
        final ActivityRecord activity = getTopVisibleActivity();
        final ActivityRecord activity = getTopMostActivity();
        return activity != null ? activity.createRemoteAnimationTarget(record) : null;
        return activity != null ? activity.createRemoteAnimationTarget(record) : null;
    }
    }


Loading