Skip to content

Commit 0c86ced

Browse files
author
Evan Rosky
committed
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
1 parent c83fbde commit 0c86ced

4 files changed

Lines changed: 107 additions & 3 deletions

File tree

core/java/android/window/WindowContainerTransaction.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,36 @@ public WindowContainerTransaction setBoundsChangeTransaction(
140140
return this;
141141
}
142142

143+
/**
144+
* Like {@link #setBoundsChangeTransaction} but instead queues up a setPosition/WindowCrop
145+
* on a container's surface control. This is useful when a boundsChangeTransaction needs to be
146+
* queued up on a Task that won't be organized until the end of this window-container
147+
* transaction.
148+
*
149+
* This requires that, at the end of this transaction, `task` will be organized; otherwise
150+
* the server will throw an IllegalArgumentException.
151+
*
152+
* WARNING: Use this carefully. Whatever is set here should match the expected bounds after
153+
* the transaction completes since it will likely be replaced by it. This call is
154+
* intended to pre-emptively set bounds on a surface in sync with a buffer when
155+
* otherwise the new bounds and the new buffer would update on different frames.
156+
*
157+
* TODO(b/134365562): remove once TaskOrg drives full-screen or BLAST is enabled.
158+
*
159+
* @hide
160+
*/
161+
@NonNull
162+
public WindowContainerTransaction setBoundsChangeTransaction(
163+
@NonNull WindowContainerToken task, @NonNull Rect surfaceBounds) {
164+
Change chg = getOrCreateChange(task.asBinder());
165+
if (chg.mBoundsChangeSurfaceBounds == null) {
166+
chg.mBoundsChangeSurfaceBounds = new Rect();
167+
}
168+
chg.mBoundsChangeSurfaceBounds.set(surfaceBounds);
169+
chg.mChangeMask |= Change.CHANGE_BOUNDS_TRANSACTION_RECT;
170+
return this;
171+
}
172+
143173
/**
144174
* Set the windowing mode of children of a given root task, without changing
145175
* the windowing mode of the Task itself. This can be used during transitions
@@ -287,6 +317,7 @@ public static class Change implements Parcelable {
287317
public static final int CHANGE_BOUNDS_TRANSACTION = 1 << 1;
288318
public static final int CHANGE_PIP_CALLBACK = 1 << 2;
289319
public static final int CHANGE_HIDDEN = 1 << 3;
320+
public static final int CHANGE_BOUNDS_TRANSACTION_RECT = 1 << 4;
290321

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

298329
private Rect mPinnedBounds = null;
299330
private SurfaceControl.Transaction mBoundsChangeTransaction = null;
331+
private Rect mBoundsChangeSurfaceBounds = null;
300332

301333
private int mActivityWindowingMode = -1;
302334
private int mWindowingMode = -1;
@@ -318,6 +350,10 @@ protected Change(Parcel in) {
318350
mBoundsChangeTransaction =
319351
SurfaceControl.Transaction.CREATOR.createFromParcel(in);
320352
}
353+
if ((mChangeMask & Change.CHANGE_BOUNDS_TRANSACTION_RECT) != 0) {
354+
mBoundsChangeSurfaceBounds = new Rect();
355+
mBoundsChangeSurfaceBounds.readFromParcel(in);
356+
}
321357

322358
mWindowingMode = in.readInt();
323359
mActivityWindowingMode = in.readInt();
@@ -377,6 +413,10 @@ public SurfaceControl.Transaction getBoundsChangeTransaction() {
377413
return mBoundsChangeTransaction;
378414
}
379415

416+
public Rect getBoundsChangeSurfaceBounds() {
417+
return mBoundsChangeSurfaceBounds;
418+
}
419+
380420
@Override
381421
public String toString() {
382422
final boolean changesBounds =
@@ -408,6 +448,9 @@ public String toString() {
408448
if ((mChangeMask & CHANGE_FOCUSABLE) != 0) {
409449
sb.append("focusable:" + mFocusable + ",");
410450
}
451+
if (mBoundsChangeTransaction != null) {
452+
sb.append("hasBoundsTransaction,");
453+
}
411454
sb.append("}");
412455
return sb.toString();
413456
}
@@ -427,6 +470,9 @@ public void writeToParcel(Parcel dest, int flags) {
427470
if (mBoundsChangeTransaction != null) {
428471
mBoundsChangeTransaction.writeToParcel(dest, flags);
429472
}
473+
if (mBoundsChangeSurfaceBounds != null) {
474+
mBoundsChangeSurfaceBounds.writeToParcel(dest, flags);
475+
}
430476

431477
dest.writeInt(mWindowingMode);
432478
dest.writeInt(mActivityWindowingMode);

services/core/java/com/android/server/wm/Task.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,12 @@ class Task extends WindowContainer<WindowContainer> {
436436
static final int FLAG_FORCE_HIDDEN_FOR_TASK_ORG = 1 << 1;
437437
private int mForceHiddenFlags = 0;
438438

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

441446
private final FindRootHelper mFindRootHelper = new FindRootHelper();
442447
private class FindRootHelper {
@@ -1745,7 +1750,7 @@ void updateTaskDescription() {
17451750
}
17461751

17471752
if (isOrganized()) {
1748-
mAtmService.mTaskOrganizerController.dispatchTaskInfoChanged(this, true /* force */);
1753+
mAtmService.mTaskOrganizerController.dispatchTaskInfoChanged(this, false /* force */);
17491754
}
17501755
}
17511756

@@ -4513,13 +4518,32 @@ void onPictureInPictureParamsChanged() {
45134518
* to resize, and it will defer the transaction until that resize frame completes.
45144519
*/
45154520
void setMainWindowSizeChangeTransaction(SurfaceControl.Transaction t) {
4521+
setMainWindowSizeChangeTransaction(t, this);
4522+
}
4523+
4524+
private void setMainWindowSizeChangeTransaction(SurfaceControl.Transaction t, Task origin) {
4525+
// This is only meaningful on an activity's task, so put it on the top one.
4526+
ActivityRecord topActivity = getTopNonFinishingActivity();
4527+
Task leaf = topActivity != null ? topActivity.getTask() : null;
4528+
if (leaf == null) {
4529+
return;
4530+
}
4531+
if (leaf != this) {
4532+
leaf.setMainWindowSizeChangeTransaction(t, origin);
4533+
return;
4534+
}
45164535
mMainWindowSizeChangeTransaction = t;
4536+
mMainWindowSizeChangeTask = t == null ? null : origin;
45174537
}
45184538

45194539
SurfaceControl.Transaction getMainWindowSizeChangeTransaction() {
45204540
return mMainWindowSizeChangeTransaction;
45214541
}
45224542

4543+
Task getMainWindowSizeChangeTask() {
4544+
return mMainWindowSizeChangeTask;
4545+
}
4546+
45234547
void setActivityWindowingMode(int windowingMode) {
45244548
PooledConsumer c = PooledLambda.obtainConsumer(ActivityRecord::setWindowingMode,
45254549
PooledLambda.__(ActivityRecord.class), windowingMode);

services/core/java/com/android/server/wm/WindowOrganizerController.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,42 @@ public int applySyncTransaction(WindowContainerTransaction t,
163163
Slog.e(TAG, "Attempt to operate on detached container: " + wc);
164164
continue;
165165
}
166+
if (syncId >= 0) {
167+
mBLASTSyncEngine.addToSyncSet(syncId, wc);
168+
}
166169
effects |= sanitizeAndApplyHierarchyOp(wc, hop);
167170
}
171+
// Queue-up bounds-change transactions for tasks which are now organized. Do
172+
// this after hierarchy ops so we have the final organized state.
173+
entries = t.getChanges().entrySet().iterator();
174+
while (entries.hasNext()) {
175+
final Map.Entry<IBinder, WindowContainerTransaction.Change> entry =
176+
entries.next();
177+
final Task task = WindowContainer.fromBinder(entry.getKey()).asTask();
178+
final Rect surfaceBounds = entry.getValue().getBoundsChangeSurfaceBounds();
179+
if (task == null || !task.isAttached() || surfaceBounds == null) {
180+
continue;
181+
}
182+
if (!task.isOrganized()) {
183+
final Task parent =
184+
task.getParent() != null ? task.getParent().asTask() : null;
185+
// Also allow direct children of created-by-organizer tasks to be
186+
// controlled. In the future, these will become organized anyways.
187+
if (parent == null || !parent.mCreatedByOrganizer) {
188+
throw new IllegalArgumentException(
189+
"Can't manipulate non-organized task surface " + task);
190+
}
191+
}
192+
final SurfaceControl.Transaction sft = new SurfaceControl.Transaction();
193+
final SurfaceControl sc = task.getSurfaceControl();
194+
sft.setPosition(sc, surfaceBounds.left, surfaceBounds.top);
195+
if (surfaceBounds.isEmpty()) {
196+
sft.setWindowCrop(sc, null);
197+
} else {
198+
sft.setWindowCrop(sc, surfaceBounds.width(), surfaceBounds.height());
199+
}
200+
task.setMainWindowSizeChangeTransaction(sft);
201+
}
168202
if ((effects & TRANSACT_EFFECTS_LIFECYCLE) != 0) {
169203
// Already calls ensureActivityConfig
170204
mService.mRootWindowContainer.ensureActivitiesVisible(

services/core/java/com/android/server/wm/WindowStateAnimator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -904,8 +904,8 @@ void setSurfaceBoundariesLocked(final boolean recoveringMemory) {
904904
}
905905

906906
if (shouldConsumeMainWindowSizeTransaction()) {
907-
task.getSurfaceControl().deferTransactionUntil(mWin.getClientViewRootSurface(),
908-
mWin.getFrameNumber());
907+
task.getMainWindowSizeChangeTask().getSurfaceControl().deferTransactionUntil(
908+
mWin.getClientViewRootSurface(), mWin.getFrameNumber());
909909
mSurfaceController.deferTransactionUntil(mWin.getClientViewRootSurface(),
910910
mWin.getFrameNumber());
911911
SurfaceControl.mergeToGlobalTransaction(task.getMainWindowSizeChangeTransaction());

0 commit comments

Comments
 (0)