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

Commit bf611354 authored by Evan Rosky's avatar Evan Rosky
Browse files

Set-up transition-related leashes on start transaction

Was previously just setting up on the pending transaction.
Now that operations put on pending transactions will wait
until the ongoing sync transaction, the ordering was wrong.

This CL puts all the changes onto the transition start
transaction.

Bug: 229907442
Test: launch landscape app, close (back) to portrait.
Change-Id: I3e4abc5f8ab80b4cb7a23cd59ca9561d9c953e9f
parent b075a1d6
Loading
Loading
Loading
Loading
+19 −11
Original line number Diff line number Diff line
@@ -420,7 +420,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
        for (int i = mTargets.size() - 1; i >= 0; --i) {
            final WindowContainer target = mTargets.get(i);
            if (target.getParent() != null) {
                final SurfaceControl targetLeash = getLeashSurface(target);
                final SurfaceControl targetLeash = getLeashSurface(target, null /* t */);
                final SurfaceControl origParent = getOrigParentSurface(target);
                // Ensure surfaceControls are re-parented back into the hierarchy.
                t.reparent(targetLeash, origParent);
@@ -676,7 +676,8 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe

        // Resolve the animating targets from the participants
        mTargets = calculateTargets(mParticipants, mChanges);
        final TransitionInfo info = calculateTransitionInfo(mType, mFlags, mTargets, mChanges);
        final TransitionInfo info = calculateTransitionInfo(mType, mFlags, mTargets, mChanges,
                transaction);
        if (mOverrideOptions != null) {
            info.setAnimationOptions(mOverrideOptions);
        }
@@ -1234,8 +1235,15 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
        }
    }

    /** Gets the leash surface for a window container */
    private static SurfaceControl getLeashSurface(WindowContainer wc) {
    /**
     * Gets the leash surface for a window container.
     * @param t a transaction to create leashes on when necessary (fixed rotation at token-level).
     *          If t is null, then this will not create any leashes, just use one if it is there --
     *          this is relevant for building the finishTransaction since it needs to match the
     *          start state and not erroneously create a leash of its own.
     */
    private static SurfaceControl getLeashSurface(WindowContainer wc,
            @Nullable SurfaceControl.Transaction t) {
        final DisplayContent asDC = wc.asDisplayContent();
        if (asDC != null) {
            // DisplayContent is the "root", so we use the windowing layer instead to avoid
@@ -1247,7 +1255,8 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
            if (asToken != null) {
                // WindowTokens can have a fixed-rotation applied to them. In the current
                // implementation this fact is hidden from the player, so we must create a leash.
                final SurfaceControl leash = asToken.getOrCreateFixedRotationLeash();
                final SurfaceControl leash = t != null ? asToken.getOrCreateFixedRotationLeash(t)
                        : asToken.getFixedRotationLeash();
                if (leash != null) return leash;
            }
        }
@@ -1276,12 +1285,14 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
     * Construct a TransitionInfo object from a set of targets and changes. Also populates the
     * root surface.
     * @param sortedTargets The targets sorted by z-order from top (index 0) to bottom.
     * @param startT The start transaction - used to set-up new leashes.
     */
    @VisibleForTesting
    @NonNull
    static TransitionInfo calculateTransitionInfo(@TransitionType int type, int flags,
            ArrayList<WindowContainer> sortedTargets,
            ArrayMap<WindowContainer, ChangeInfo> changes) {
            ArrayMap<WindowContainer, ChangeInfo> changes,
            @Nullable SurfaceControl.Transaction startT) {
        final TransitionInfo out = new TransitionInfo(type, flags);

        WindowContainer<?> topApp = null;
@@ -1319,10 +1330,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
        }
        final SurfaceControl rootLeash = leashReference.makeAnimationLeash().setName(
                "Transition Root: " + leashReference.getName()).build();
        SurfaceControl.Transaction t = ancestor.mWmService.mTransactionFactory.get();
        t.setLayer(rootLeash, leashReference.getLastLayer());
        t.apply();
        t.close();
        startT.setLayer(rootLeash, leashReference.getLastLayer());
        out.setRootLeash(rootLeash, ancestor.getBounds().left, ancestor.getBounds().top);

        // Convert all the resolved ChangeInfos into TransactionInfo.Change objects in order.
@@ -1332,7 +1340,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
            final ChangeInfo info = changes.get(target);
            final TransitionInfo.Change change = new TransitionInfo.Change(
                    target.mRemoteToken != null ? target.mRemoteToken.toWindowContainerToken()
                            : null, getLeashSurface(target));
                            : null, getLeashSurface(target, startT));
            // TODO(shell-transitions): Use leash for non-organized windows.
            if (info.mParent != null) {
                change.setParent(info.mParent.mRemoteToken.toWindowContainerToken());
+11 −2
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import static com.android.server.wm.WindowTokenProto.WAITING_TO_SHOW;
import static com.android.server.wm.WindowTokenProto.WINDOW_CONTAINER;

import android.annotation.CallSuper;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.res.Configuration;
import android.graphics.Rect;
@@ -569,13 +570,12 @@ class WindowToken extends WindowContainer<WindowState> {
     * the same rotation.
     */
    @Nullable
    SurfaceControl getOrCreateFixedRotationLeash() {
    SurfaceControl getOrCreateFixedRotationLeash(@NonNull SurfaceControl.Transaction t) {
        if (!mTransitionController.isShellTransitionsEnabled()) return null;
        final int rotation = getRelativeDisplayRotation();
        if (rotation == Surface.ROTATION_0) return mFixedRotationTransformLeash;
        if (mFixedRotationTransformLeash != null) return mFixedRotationTransformLeash;

        final SurfaceControl.Transaction t = getSyncTransaction();
        final SurfaceControl leash = makeSurface().setContainerLayer()
                .setParent(getParentSurfaceControl())
                .setName(getSurfaceControl() + " - rotation-leash")
@@ -591,6 +591,15 @@ class WindowToken extends WindowContainer<WindowState> {
        return mFixedRotationTransformLeash;
    }

    /**
     * @return the leash which represents this window as if it was non-rotated. Will be null if
     *         there isn't one.
     */
    @Nullable
    SurfaceControl getFixedRotationLeash() {
        return mFixedRotationTransformLeash;
    }

    void removeFixedRotationLeash() {
        if (mFixedRotationTransformLeash == null) return;
        final SurfaceControl.Transaction t = getSyncTransaction();
+24 −17
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ import java.util.function.Function;
@Presubmit
@RunWith(WindowTestRunner.class)
public class TransitionTests extends WindowTestsBase {
    final SurfaceControl.Transaction mMockT = mock(SurfaceControl.Transaction.class);

    private Transition createTestTransition(int transitType) {
        TransitionController controller = mock(TransitionController.class);
@@ -121,7 +122,8 @@ public class TransitionTests extends WindowTestsBase {
        participants.add(oldTask);
        participants.add(newTask);
        ArrayList<WindowContainer> targets = Transition.calculateTargets(participants, changes);
        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes,
                mMockT);
        assertEquals(2, info.getChanges().size());
        assertEquals(transit, info.getType());

@@ -129,7 +131,7 @@ public class TransitionTests extends WindowTestsBase {
        participants.add(opening);
        participants.add(closing);
        targets = Transition.calculateTargets(participants, changes);
        info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
        info = Transition.calculateTransitionInfo(transit, flags, targets, changes, mMockT);
        assertEquals(2, info.getChanges().size());
        assertNotNull(info.getChange(newTask.mRemoteToken.toWindowContainerToken()));
        assertNotNull(info.getChange(oldTask.mRemoteToken.toWindowContainerToken()));
@@ -137,7 +139,7 @@ public class TransitionTests extends WindowTestsBase {
        // Check combined prune and promote
        participants.remove(newTask);
        targets = Transition.calculateTargets(participants, changes);
        info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
        info = Transition.calculateTransitionInfo(transit, flags, targets, changes, mMockT);
        assertEquals(2, info.getChanges().size());
        assertNotNull(info.getChange(newTask.mRemoteToken.toWindowContainerToken()));
        assertNotNull(info.getChange(oldTask.mRemoteToken.toWindowContainerToken()));
@@ -145,7 +147,7 @@ public class TransitionTests extends WindowTestsBase {
        // Check multi promote
        participants.remove(oldTask);
        targets = Transition.calculateTargets(participants, changes);
        info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
        info = Transition.calculateTransitionInfo(transit, flags, targets, changes, mMockT);
        assertEquals(2, info.getChanges().size());
        assertNotNull(info.getChange(newTask.mRemoteToken.toWindowContainerToken()));
        assertNotNull(info.getChange(oldTask.mRemoteToken.toWindowContainerToken()));
@@ -186,7 +188,8 @@ public class TransitionTests extends WindowTestsBase {
        participants.add(opening);
        participants.add(opening2);
        ArrayList<WindowContainer> targets = Transition.calculateTargets(participants, changes);
        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes,
                mMockT);
        assertEquals(2, info.getChanges().size());
        assertEquals(transit, info.getType());
        assertNotNull(info.getChange(newTask.mRemoteToken.toWindowContainerToken()));
@@ -195,7 +198,7 @@ public class TransitionTests extends WindowTestsBase {
        // Check that unchanging but visible descendant of sibling prevents promotion
        participants.remove(opening2);
        targets = Transition.calculateTargets(participants, changes);
        info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
        info = Transition.calculateTransitionInfo(transit, flags, targets, changes, mMockT);
        assertEquals(2, info.getChanges().size());
        assertNotNull(info.getChange(newNestedTask.mRemoteToken.toWindowContainerToken()));
        assertNotNull(info.getChange(oldTask.mRemoteToken.toWindowContainerToken()));
@@ -232,7 +235,8 @@ public class TransitionTests extends WindowTestsBase {
        participants.add(showing);
        participants.add(showing2);
        ArrayList<WindowContainer> targets = Transition.calculateTargets(participants, changes);
        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes,
                mMockT);
        assertEquals(1, info.getChanges().size());
        assertEquals(transit, info.getType());
        assertNotNull(info.getChange(tda.mRemoteToken.toWindowContainerToken()));
@@ -240,14 +244,14 @@ public class TransitionTests extends WindowTestsBase {
        // Check that organized tasks get reported even if not top
        makeTaskOrganized(showTask);
        targets = Transition.calculateTargets(participants, changes);
        info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
        info = Transition.calculateTransitionInfo(transit, flags, targets, changes, mMockT);
        assertEquals(2, info.getChanges().size());
        assertNotNull(info.getChange(tda.mRemoteToken.toWindowContainerToken()));
        assertNotNull(info.getChange(showTask.mRemoteToken.toWindowContainerToken()));
        // Even if DisplayArea explicitly participating
        participants.add(tda);
        targets = Transition.calculateTargets(participants, changes);
        info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
        info = Transition.calculateTransitionInfo(transit, flags, targets, changes, mMockT);
        assertEquals(2, info.getChanges().size());
    }

@@ -271,7 +275,7 @@ public class TransitionTests extends WindowTestsBase {
        ArrayList<WindowContainer> targets = Transition.calculateTargets(
                transition.mParticipants, transition.mChanges);
        TransitionInfo info = Transition.calculateTransitionInfo(
                0, 0, targets, transition.mChanges);
                0, 0, targets, transition.mChanges, mMockT);
        assertEquals(2, info.getChanges().size());
        // There was an existence change on open, so it should be OPEN rather than SHOW
        assertEquals(TRANSIT_OPEN,
@@ -308,7 +312,7 @@ public class TransitionTests extends WindowTestsBase {
        ArrayList<WindowContainer> targets = Transition.calculateTargets(
                transition.mParticipants, transition.mChanges);
        TransitionInfo info = Transition.calculateTransitionInfo(
                0, 0, targets, transition.mChanges);
                0, 0, targets, transition.mChanges, mMockT);
        assertEquals(taskCount, info.getChanges().size());
        // verify order is top-to-bottem
        for (int i = 0; i < taskCount; ++i) {
@@ -358,7 +362,7 @@ public class TransitionTests extends WindowTestsBase {
        ArrayList<WindowContainer> targets = Transition.calculateTargets(
                transition.mParticipants, transition.mChanges);
        TransitionInfo info = Transition.calculateTransitionInfo(
                0, 0, targets, transition.mChanges);
                0, 0, targets, transition.mChanges, mMockT);
        // verify that wallpaper is at bottom
        assertEquals(taskCount + 1, info.getChanges().size());
        // The wallpaper is not organized, so it won't have a token; however, it will be marked
@@ -392,7 +396,7 @@ public class TransitionTests extends WindowTestsBase {
        ArrayList<WindowContainer> targets = Transition.calculateTargets(
                transition.mParticipants, transition.mChanges);
        TransitionInfo info = Transition.calculateTransitionInfo(
                0, 0, targets, transition.mChanges);
                0, 0, targets, transition.mChanges, mMockT);
        // The wallpaper is not organized, so it won't have a token; however, it will be marked
        // as IS_WALLPAPER
        assertEquals(FLAG_IS_WALLPAPER, info.getChanges().get(0).getFlags());
@@ -474,7 +478,8 @@ public class TransitionTests extends WindowTestsBase {
        participants.add(changeTask);
        final ArrayList<WindowContainer> targets =
                Transition.calculateTargets(participants, changes);
        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes,
                mMockT);
        // Root changes should always be considered independent
        assertTrue(isIndependent(
                info.getChange(openTask.mRemoteToken.toWindowContainerToken()), info));
@@ -526,7 +531,8 @@ public class TransitionTests extends WindowTestsBase {
        participants.add(oldTask);
        participants.add(newTask);
        ArrayList<WindowContainer> targets = Transition.calculateTargets(participants, changes);
        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes,
                mMockT);
        assertEquals(2, info.getChanges().size());
        assertEquals(transit, info.getType());

@@ -566,7 +572,8 @@ public class TransitionTests extends WindowTestsBase {
        participants.add(oldTask);
        participants.add(newTask);
        ArrayList<WindowContainer> targets = Transition.calculateTargets(participants, changes);
        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes,
                mMockT);
        assertEquals(2, info.getChanges().size());
        assertEquals(transit, info.getType());

@@ -608,7 +615,7 @@ public class TransitionTests extends WindowTestsBase {
            final int flags = 0;
            final TransitionInfo info = Transition.calculateTransitionInfo(transition.mType, flags,
                    Transition.calculateTargets(transition.mParticipants, transition.mChanges),
                    transition.mChanges);
                    transition.mChanges, mMockT);
            transition.abort();
            return info.getChanges().get(0);
        };