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

Commit 0c86ced0 authored by Evan Rosky's avatar Evan Rosky
Browse files

Add boundsChangeTransaction for Task pending mode change

This associates a surfaceflinger bounds change with a task's
surface provided that task will become organized by the end
of a WindowContainer transaction. Without this, there's no
way to synchronize a new frame due to bounds-change with
said bounds-change if the bounds-change is a result of
changing windowing-modes (and thus becoming organized).

This also records the original Task that a bounds-change
transaction was associated with along with the transaction.
This is needed anytime tasks are nested (eg. with home
task or with split-screen tasks).

Bug: 153579514
Test: See test entry for end of commit chain
Change-Id: If14ea07eca17ef9146537d5aae7122dd7c2dc045
parent c83fbdea
Loading
Loading
Loading
Loading
+46 −0
Original line number Diff line number Diff line
@@ -140,6 +140,36 @@ public final class WindowContainerTransaction implements Parcelable {
        return this;
    }

    /**
     * Like {@link #setBoundsChangeTransaction} but instead queues up a setPosition/WindowCrop
     * on a container's surface control. This is useful when a boundsChangeTransaction needs to be
     * queued up on a Task that won't be organized until the end of this window-container
     * transaction.
     *
     * This requires that, at the end of this transaction, `task` will be organized; otherwise
     * the server will throw an IllegalArgumentException.
     *
     * WARNING: Use this carefully. Whatever is set here should match the expected bounds after
     *          the transaction completes since it will likely be replaced by it. This call is
     *          intended to pre-emptively set bounds on a surface in sync with a buffer when
     *          otherwise the new bounds and the new buffer would update on different frames.
     *
     * TODO(b/134365562): remove once TaskOrg drives full-screen or BLAST is enabled.
     *
     * @hide
     */
    @NonNull
    public WindowContainerTransaction setBoundsChangeTransaction(
            @NonNull WindowContainerToken task, @NonNull Rect surfaceBounds) {
        Change chg = getOrCreateChange(task.asBinder());
        if (chg.mBoundsChangeSurfaceBounds == null) {
            chg.mBoundsChangeSurfaceBounds = new Rect();
        }
        chg.mBoundsChangeSurfaceBounds.set(surfaceBounds);
        chg.mChangeMask |= Change.CHANGE_BOUNDS_TRANSACTION_RECT;
        return this;
    }

    /**
     * Set the windowing mode of children of a given root task, without changing
     * the windowing mode of the Task itself. This can be used during transitions
@@ -287,6 +317,7 @@ public final class WindowContainerTransaction implements Parcelable {
        public static final int CHANGE_BOUNDS_TRANSACTION = 1 << 1;
        public static final int CHANGE_PIP_CALLBACK = 1 << 2;
        public static final int CHANGE_HIDDEN = 1 << 3;
        public static final int CHANGE_BOUNDS_TRANSACTION_RECT = 1 << 4;

        private final Configuration mConfiguration = new Configuration();
        private boolean mFocusable = true;
@@ -297,6 +328,7 @@ public final class WindowContainerTransaction implements Parcelable {

        private Rect mPinnedBounds = null;
        private SurfaceControl.Transaction mBoundsChangeTransaction = null;
        private Rect mBoundsChangeSurfaceBounds = null;

        private int mActivityWindowingMode = -1;
        private int mWindowingMode = -1;
@@ -318,6 +350,10 @@ public final class WindowContainerTransaction implements Parcelable {
                mBoundsChangeTransaction =
                    SurfaceControl.Transaction.CREATOR.createFromParcel(in);
            }
            if ((mChangeMask & Change.CHANGE_BOUNDS_TRANSACTION_RECT) != 0) {
                mBoundsChangeSurfaceBounds = new Rect();
                mBoundsChangeSurfaceBounds.readFromParcel(in);
            }

            mWindowingMode = in.readInt();
            mActivityWindowingMode = in.readInt();
@@ -377,6 +413,10 @@ public final class WindowContainerTransaction implements Parcelable {
            return mBoundsChangeTransaction;
        }

        public Rect getBoundsChangeSurfaceBounds() {
            return mBoundsChangeSurfaceBounds;
        }

        @Override
        public String toString() {
            final boolean changesBounds =
@@ -408,6 +448,9 @@ public final class WindowContainerTransaction implements Parcelable {
            if ((mChangeMask & CHANGE_FOCUSABLE) != 0) {
                sb.append("focusable:" + mFocusable + ",");
            }
            if (mBoundsChangeTransaction != null) {
                sb.append("hasBoundsTransaction,");
            }
            sb.append("}");
            return sb.toString();
        }
@@ -427,6 +470,9 @@ public final class WindowContainerTransaction implements Parcelable {
            if (mBoundsChangeTransaction != null) {
                mBoundsChangeTransaction.writeToParcel(dest, flags);
            }
            if (mBoundsChangeSurfaceBounds != null) {
                mBoundsChangeSurfaceBounds.writeToParcel(dest, flags);
            }

            dest.writeInt(mWindowingMode);
            dest.writeInt(mActivityWindowingMode);
+25 −1
Original line number Diff line number Diff line
@@ -436,7 +436,12 @@ class Task extends WindowContainer<WindowContainer> {
    static final int FLAG_FORCE_HIDDEN_FOR_TASK_ORG = 1 << 1;
    private int mForceHiddenFlags = 0;

    // When non-null, this is a transaction that will get applied on the next frame returned after
    // a relayout is requested from the client. While this is only valid on a leaf task; since the
    // transaction can effect an ancestor task, this also needs to keep track of the ancestor task
    // that this transaction manipulates because deferUntilFrame acts on individual surfaces.
    SurfaceControl.Transaction mMainWindowSizeChangeTransaction;
    Task mMainWindowSizeChangeTask;

    private final FindRootHelper mFindRootHelper = new FindRootHelper();
    private class FindRootHelper {
@@ -1745,7 +1750,7 @@ class Task extends WindowContainer<WindowContainer> {
        }

        if (isOrganized()) {
            mAtmService.mTaskOrganizerController.dispatchTaskInfoChanged(this, true /* force */);
            mAtmService.mTaskOrganizerController.dispatchTaskInfoChanged(this, false /* force */);
        }
    }

@@ -4513,13 +4518,32 @@ class Task extends WindowContainer<WindowContainer> {
     * to resize, and it will defer the transaction until that resize frame completes.
     */
    void setMainWindowSizeChangeTransaction(SurfaceControl.Transaction t) {
        setMainWindowSizeChangeTransaction(t, this);
    }

    private void setMainWindowSizeChangeTransaction(SurfaceControl.Transaction t, Task origin) {
        // This is only meaningful on an activity's task, so put it on the top one.
        ActivityRecord topActivity = getTopNonFinishingActivity();
        Task leaf = topActivity != null ? topActivity.getTask() : null;
        if (leaf == null) {
            return;
        }
        if (leaf != this) {
            leaf.setMainWindowSizeChangeTransaction(t, origin);
            return;
        }
        mMainWindowSizeChangeTransaction = t;
        mMainWindowSizeChangeTask = t == null ? null : origin;
    }

    SurfaceControl.Transaction getMainWindowSizeChangeTransaction() {
        return mMainWindowSizeChangeTransaction;
    }

    Task getMainWindowSizeChangeTask() {
        return mMainWindowSizeChangeTask;
    }

    void setActivityWindowingMode(int windowingMode) {
        PooledConsumer c = PooledLambda.obtainConsumer(ActivityRecord::setWindowingMode,
                PooledLambda.__(ActivityRecord.class), windowingMode);
+34 −0
Original line number Diff line number Diff line
@@ -163,8 +163,42 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                            Slog.e(TAG, "Attempt to operate on detached container: " + wc);
                            continue;
                        }
                        if (syncId >= 0) {
                            mBLASTSyncEngine.addToSyncSet(syncId, wc);
                        }
                        effects |= sanitizeAndApplyHierarchyOp(wc, hop);
                    }
                    // Queue-up bounds-change transactions for tasks which are now organized. Do
                    // this after hierarchy ops so we have the final organized state.
                    entries = t.getChanges().entrySet().iterator();
                    while (entries.hasNext()) {
                        final Map.Entry<IBinder, WindowContainerTransaction.Change> entry =
                                entries.next();
                        final Task task = WindowContainer.fromBinder(entry.getKey()).asTask();
                        final Rect surfaceBounds = entry.getValue().getBoundsChangeSurfaceBounds();
                        if (task == null || !task.isAttached() || surfaceBounds == null) {
                            continue;
                        }
                        if (!task.isOrganized()) {
                            final Task parent =
                                    task.getParent() != null ? task.getParent().asTask() : null;
                            // Also allow direct children of created-by-organizer tasks to be
                            // controlled. In the future, these will become organized anyways.
                            if (parent == null || !parent.mCreatedByOrganizer) {
                                throw new IllegalArgumentException(
                                        "Can't manipulate non-organized task surface " + task);
                            }
                        }
                        final SurfaceControl.Transaction sft = new SurfaceControl.Transaction();
                        final SurfaceControl sc = task.getSurfaceControl();
                        sft.setPosition(sc, surfaceBounds.left, surfaceBounds.top);
                        if (surfaceBounds.isEmpty()) {
                            sft.setWindowCrop(sc, null);
                        } else {
                            sft.setWindowCrop(sc, surfaceBounds.width(), surfaceBounds.height());
                        }
                        task.setMainWindowSizeChangeTransaction(sft);
                    }
                    if ((effects & TRANSACT_EFFECTS_LIFECYCLE) != 0) {
                        // Already calls ensureActivityConfig
                        mService.mRootWindowContainer.ensureActivitiesVisible(
+2 −2
Original line number Diff line number Diff line
@@ -904,8 +904,8 @@ class WindowStateAnimator {
        }

        if (shouldConsumeMainWindowSizeTransaction()) {
            task.getSurfaceControl().deferTransactionUntil(mWin.getClientViewRootSurface(),
                    mWin.getFrameNumber());
            task.getMainWindowSizeChangeTask().getSurfaceControl().deferTransactionUntil(
                    mWin.getClientViewRootSurface(), mWin.getFrameNumber());
            mSurfaceController.deferTransactionUntil(mWin.getClientViewRootSurface(),
                    mWin.getFrameNumber());
            SurfaceControl.mergeToGlobalTransaction(task.getMainWindowSizeChangeTransaction());