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

Commit 3c1c2c04 authored by wilsonshih's avatar wilsonshih
Browse files

Fix the regression that closing transition disappeared.

For hierarchical animation, there are missing some handling
around mNeedsZBoost, when closing an activity the transition did
not applied.

1. Move some codes around mNeedsZBoost from ActivityRecord to
WindowContainer so Task can also benefit from it.
2. TaskDisplayArea#assignChildLayers should combined needsZBoost
so this attribute can apply on root task.
3. If next top activity will move to top in #finishIfPossible
and the finishing activity is on top, provide it a higher layer
to remain on top. Otherwise user will see flicker because the
transition need to be applied until next activity resumed.

Bug: 159200318
Test: atest ActivityRecordTests TaskDisplayAreaTests
AppWindowTokenAnimationTests TransitionSelectionTests

Change-Id: I85ec3307b31444e09179abca30298af2ce538834
parent 616f0731
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -2580,7 +2580,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                if (DEBUG_VISIBILITY || DEBUG_TRANSITION) {
                    Slog.v(TAG_TRANSITION, "Prepare close transition: finishing " + this);
                }
                getDisplay().mDisplayContent.prepareAppTransition(transit, false);
                mDisplayContent.prepareAppTransition(transit, false);

                // When finishing the activity preemptively take the snapshot before the app window
                // is marked as hidden and any configuration changes take place
@@ -2605,6 +2605,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A

                if (endTask) {
                    mAtmService.getLockTaskController().clearLockedTask(task);
                    // This activity was in the top focused stack and this is the last activity in
                    // that task, give this activity a higher layer so it can stay on top before the
                    // closing task transition be executed.
                    if (mayAdjustTop) {
                        mNeedsZBoost = true;
                        mDisplayContent.assignWindowLayers(false /* setLayoutNeeded */);
                    }
                }
            } else if (!isState(PAUSING)) {
                if (mVisibleRequested) {
@@ -6105,7 +6112,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "AR#onAnimationFinished");
        mTransit = TRANSIT_UNSET;
        mTransitFlags = 0;
        mNeedsZBoost = false;
        mNeedsAnimationBoundsLayer = false;

        setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM | FINISH_LAYOUT_REDO_WALLPAPER,
+60 −23
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.os.UserHandle;
import android.util.IntArray;
import android.util.Slog;
import android.view.SurfaceControl;
import android.window.WindowContainerTransaction;
@@ -106,6 +107,9 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
    private final ArrayList<ActivityStack> mTmpAlwaysOnTopStacks = new ArrayList<>();
    private final ArrayList<ActivityStack> mTmpNormalStacks = new ArrayList<>();
    private final ArrayList<ActivityStack> mTmpHomeStacks = new ArrayList<>();
    private final IntArray mTmpNeedsZBoostIndexes = new IntArray();
    private int mTmpLayerForSplitScreenDividerAnchor;
    private int mTmpLayerForAnimationLayer;

    private ArrayList<Task> mTmpTasks = new ArrayList<>();

@@ -633,37 +637,70 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {

        int layer = 0;
        // Place home stacks to the bottom.
        for (int i = 0; i < mTmpHomeStacks.size(); i++) {
            mTmpHomeStacks.get(i).assignLayer(t, layer++);
        }
        layer = adjustRootTaskLayer(t, mTmpHomeStacks, layer, false /* normalStacks */);
        // The home animation layer is between the home stacks and the normal stacks.
        final int layerForHomeAnimationLayer = layer++;
        int layerForSplitScreenDividerAnchor = layer++;
        int layerForAnimationLayer = layer++;
        for (int i = 0; i < mTmpNormalStacks.size(); i++) {
            final ActivityStack s = mTmpNormalStacks.get(i);
            s.assignLayer(t, layer++);
        mTmpLayerForSplitScreenDividerAnchor = layer++;
        mTmpLayerForAnimationLayer = layer++;
        layer = adjustRootTaskLayer(t, mTmpNormalStacks, layer, true /* normalStacks */);

        // The boosted animation layer is between the normal stacks and the always on top
        // stacks.
        final int layerForBoostedAnimationLayer = layer++;
        adjustRootTaskLayer(t, mTmpAlwaysOnTopStacks, layer, false /* normalStacks */);

        t.setLayer(mHomeAppAnimationLayer, layerForHomeAnimationLayer);
        t.setLayer(mAppAnimationLayer, mTmpLayerForAnimationLayer);
        t.setLayer(mSplitScreenDividerAnchor, mTmpLayerForSplitScreenDividerAnchor);
        t.setLayer(mBoostedAppAnimationLayer, layerForBoostedAnimationLayer);
    }

    private int adjustNormalStackLayer(ActivityStack s, int layer) {
        if (s.inSplitScreenWindowingMode()) {
            // The split screen divider anchor is located above the split screen window.
                layerForSplitScreenDividerAnchor = layer++;
            mTmpLayerForSplitScreenDividerAnchor = layer++;
        }
        if (s.isTaskAnimating() || s.isAppTransitioning()) {
            // The animation layer is located above the highest animating stack and no
            // higher.
                layerForAnimationLayer = layer++;
            mTmpLayerForAnimationLayer = layer++;
        }
        return layer;
    }

    /**
     * Adjusts the layer of the stack which belongs to the same group.
     * Note that there are three stack groups: home stacks, always on top stacks, and normal stacks.
     *
     * @param startLayer The beginning layer of this group of stacks.
     * @param normalStacks Set {@code true} if this group is neither home nor always on top.
     * @return The adjusted layer value.
     */
    private int adjustRootTaskLayer(SurfaceControl.Transaction t, ArrayList<ActivityStack> stacks,
            int startLayer, boolean normalStacks) {
        mTmpNeedsZBoostIndexes.clear();
        final int stackSize = stacks.size();
        for (int i = 0; i < stackSize; i++) {
            final ActivityStack stack = stacks.get(i);
            if (!stack.needsZBoost()) {
                stack.assignLayer(t, startLayer++);
                if (normalStacks) {
                    startLayer = adjustNormalStackLayer(stack, startLayer);
                }
            } else {
                mTmpNeedsZBoostIndexes.add(i);
            }
        // The boosted animation layer is between the normal stacks and the always on top
        // stacks.
        final int layerForBoostedAnimationLayer = layer++;
        for (int i = 0; i < mTmpAlwaysOnTopStacks.size(); i++) {
            mTmpAlwaysOnTopStacks.get(i).assignLayer(t, layer++);
        }

        t.setLayer(mHomeAppAnimationLayer, layerForHomeAnimationLayer);
        t.setLayer(mAppAnimationLayer, layerForAnimationLayer);
        t.setLayer(mSplitScreenDividerAnchor, layerForSplitScreenDividerAnchor);
        t.setLayer(mBoostedAppAnimationLayer, layerForBoostedAnimationLayer);
        final int zBoostSize = mTmpNeedsZBoostIndexes.size();
        for (int i = 0; i < zBoostSize; i++) {
            final ActivityStack stack = stacks.get(mTmpNeedsZBoostIndexes.get(i));
            stack.assignLayer(t, startLayer++);
            if (normalStacks) {
                startLayer = adjustNormalStackLayer(stack, startLayer);
            }
        }
        return startLayer;
    }

    @Override
+1 −0
Original line number Diff line number Diff line
@@ -2440,6 +2440,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
    protected void onAnimationFinished(@AnimationType int type, AnimationAdapter anim) {
        doAnimationFinished(type, anim);
        mWmService.onAnimationFinished();
        mNeedsZBoost = false;
    }

    /**