summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/window/WindowContainerTransaction.java46
-rw-r--r--services/core/java/com/android/server/wm/Task.java26
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java34
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java4
4 files changed, 107 insertions, 3 deletions
diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java
index 231e024e835f..9a732455113c 100644
--- a/core/java/android/window/WindowContainerTransaction.java
+++ b/core/java/android/window/WindowContainerTransaction.java
@@ -141,6 +141,36 @@ public final class WindowContainerTransaction implements Parcelable {
}
/**
+ * 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
* for example to make the activity render it's fullscreen configuration
@@ -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);
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index cc72dcfb0be2..61d08e16407b 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -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);
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 707a7898f8b6..a3faa86758cd 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -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(
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index b30d40824a05..42c21930bdf7 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -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());