Loading core/java/android/window/WindowContainerTransaction.java +46 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading @@ -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; Loading @@ -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(); Loading Loading @@ -377,6 +413,10 @@ public final class WindowContainerTransaction implements Parcelable { return mBoundsChangeTransaction; } public Rect getBoundsChangeSurfaceBounds() { return mBoundsChangeSurfaceBounds; } @Override public String toString() { final boolean changesBounds = Loading Loading @@ -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(); } Loading @@ -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); Loading services/core/java/com/android/server/wm/Task.java +25 −1 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -1745,7 +1750,7 @@ class Task extends WindowContainer<WindowContainer> { } if (isOrganized()) { mAtmService.mTaskOrganizerController.dispatchTaskInfoChanged(this, true /* force */); mAtmService.mTaskOrganizerController.dispatchTaskInfoChanged(this, false /* force */); } } Loading Loading @@ -4510,13 +4515,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); Loading services/core/java/com/android/server/wm/WindowOrganizerController.java +34 −0 Original line number Diff line number Diff line Loading @@ -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( Loading services/core/java/com/android/server/wm/WindowStateAnimator.java +2 −2 Original line number Diff line number Diff line Loading @@ -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()); Loading Loading
core/java/android/window/WindowContainerTransaction.java +46 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading @@ -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; Loading @@ -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(); Loading Loading @@ -377,6 +413,10 @@ public final class WindowContainerTransaction implements Parcelable { return mBoundsChangeTransaction; } public Rect getBoundsChangeSurfaceBounds() { return mBoundsChangeSurfaceBounds; } @Override public String toString() { final boolean changesBounds = Loading Loading @@ -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(); } Loading @@ -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); Loading
services/core/java/com/android/server/wm/Task.java +25 −1 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -1745,7 +1750,7 @@ class Task extends WindowContainer<WindowContainer> { } if (isOrganized()) { mAtmService.mTaskOrganizerController.dispatchTaskInfoChanged(this, true /* force */); mAtmService.mTaskOrganizerController.dispatchTaskInfoChanged(this, false /* force */); } } Loading Loading @@ -4510,13 +4515,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); Loading
services/core/java/com/android/server/wm/WindowOrganizerController.java +34 −0 Original line number Diff line number Diff line Loading @@ -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( Loading
services/core/java/com/android/server/wm/WindowStateAnimator.java +2 −2 Original line number Diff line number Diff line Loading @@ -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()); Loading