WindowContainerTransaction: Provide non-BLAST bounds change sync
This is to enable landing the SysUI driven PiP animation without BLAST. Without BLAST we can't support multi container sync, multi buffer sync, etc, but we can support the same sort of synchronization we've supported before. Let's recall how the old PIP animation works: At the end of the enter animation, or the beginning of the leave animation, the Surface changes size (When the Windowing mode changes). We detect this size change deep in the guts of WindowStateAnimator, and when we detect that we are called from "relayoutWindow" defer a transaction changing the PIP scaling factors. This approach is we simply allow SysUI to set a pending Transaction on a task via the WindowContainerTransaction API. The next BASE_APPLICATION window to resize in this task will consume this transaciton, and defer the transaction until the frame in which it resizes. Bug: 139371701 Bug: 139371701 Test: Manual test with pending SysUI branch Change-Id: I1e757d87e2f276db626de00685b0432508ac6d62
This commit is contained in:
@@ -26,6 +26,7 @@ import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.ArrayMap;
|
||||
import android.view.SurfaceControl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -77,8 +78,28 @@ public class WindowContainerTransaction implements Parcelable {
|
||||
public WindowContainerTransaction scheduleFinishEnterPip(IWindowContainer container,
|
||||
Rect bounds) {
|
||||
Change chg = getOrCreateChange(container.asBinder());
|
||||
chg.mSchedulePipCallback = true;
|
||||
chg.mPinnedBounds = new Rect(bounds);
|
||||
chg.mChangeMask |= Change.CHANGE_PIP_CALLBACK;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a SurfaceControl transaction to the server, which the server will apply in sync with
|
||||
* the next bounds change. As this uses deferred transaction and not BLAST it is only
|
||||
* able to sync with a single window, and the first visible window in this hierarchy of type
|
||||
* BASE_APPLICATION to resize will be used. If there are bound changes included in this
|
||||
* WindowContainer transaction (from setBounds or scheduleFinishEnterPip), the SurfaceControl
|
||||
* transaction will be synced with those bounds. If there are no changes, then
|
||||
* the SurfaceControl transaction will be synced with the next bounds change. This means
|
||||
* that you can call this, apply the WindowContainer transaction, and then later call
|
||||
* dismissPip() to achieve synchronization.
|
||||
*/
|
||||
public WindowContainerTransaction setBoundsChangeTransaction(IWindowContainer container,
|
||||
SurfaceControl.Transaction t) {
|
||||
Change chg = getOrCreateChange(container.asBinder());
|
||||
chg.mBoundsChangeTransaction = t;
|
||||
chg.mChangeMask |= Change.CHANGE_BOUNDS_TRANSACTION;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -174,6 +195,8 @@ public class WindowContainerTransaction implements Parcelable {
|
||||
*/
|
||||
public static class Change implements Parcelable {
|
||||
public static final int CHANGE_FOCUSABLE = 1;
|
||||
public static final int CHANGE_BOUNDS_TRANSACTION = 1 << 1;
|
||||
public static final int CHANGE_PIP_CALLBACK = 1 << 2;
|
||||
|
||||
private final Configuration mConfiguration = new Configuration();
|
||||
private boolean mFocusable = true;
|
||||
@@ -181,8 +204,8 @@ public class WindowContainerTransaction implements Parcelable {
|
||||
private @ActivityInfo.Config int mConfigSetMask = 0;
|
||||
private @WindowConfiguration.WindowConfig int mWindowSetMask = 0;
|
||||
|
||||
private boolean mSchedulePipCallback = false;
|
||||
private Rect mPinnedBounds = null;
|
||||
private SurfaceControl.Transaction mBoundsChangeTransaction = null;
|
||||
|
||||
public Change() {}
|
||||
|
||||
@@ -192,11 +215,14 @@ public class WindowContainerTransaction implements Parcelable {
|
||||
mChangeMask = in.readInt();
|
||||
mConfigSetMask = in.readInt();
|
||||
mWindowSetMask = in.readInt();
|
||||
mSchedulePipCallback = (in.readInt() != 0);
|
||||
if (mSchedulePipCallback ) {
|
||||
if ((mChangeMask & Change.CHANGE_PIP_CALLBACK) != 0) {
|
||||
mPinnedBounds = new Rect();
|
||||
mPinnedBounds.readFromParcel(in);
|
||||
}
|
||||
if ((mChangeMask & Change.CHANGE_BOUNDS_TRANSACTION) != 0) {
|
||||
mBoundsChangeTransaction =
|
||||
SurfaceControl.Transaction.CREATOR.createFromParcel(in);
|
||||
}
|
||||
}
|
||||
|
||||
public Configuration getConfiguration() {
|
||||
@@ -233,6 +259,10 @@ public class WindowContainerTransaction implements Parcelable {
|
||||
return mPinnedBounds;
|
||||
}
|
||||
|
||||
public SurfaceControl.Transaction getBoundsChangeTransaction() {
|
||||
return mBoundsChangeTransaction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final boolean changesBounds =
|
||||
@@ -264,10 +294,12 @@ public class WindowContainerTransaction implements Parcelable {
|
||||
dest.writeInt(mConfigSetMask);
|
||||
dest.writeInt(mWindowSetMask);
|
||||
|
||||
dest.writeInt(mSchedulePipCallback ? 1 : 0);
|
||||
if (mSchedulePipCallback ) {
|
||||
if (mPinnedBounds != null) {
|
||||
mPinnedBounds.writeToParcel(dest, flags);
|
||||
}
|
||||
if (mBoundsChangeTransaction != null) {
|
||||
mBoundsChangeTransaction.writeToParcel(dest, flags);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -422,6 +422,8 @@ class Task extends WindowContainer<WindowContainer> {
|
||||
/** When set, will force the task to report as invisible. */
|
||||
boolean mForceHidden = false;
|
||||
|
||||
SurfaceControl.Transaction mMainWindowSizeChangeTransaction;
|
||||
|
||||
private final FindRootHelper mFindRootHelper = new FindRootHelper();
|
||||
private class FindRootHelper {
|
||||
private ActivityRecord mRoot;
|
||||
@@ -3981,4 +3983,17 @@ class Task extends WindowContainer<WindowContainer> {
|
||||
mAtmService.mTaskOrganizerController.dispatchTaskInfoChanged(
|
||||
this, true /* force */);
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link WindowContainerTransaction#setBoundsChangeTransaction}. In short this
|
||||
* transaction will be consumed by the next BASE_APPLICATION window within our hierarchy
|
||||
* to resize, and it will defer the transaction until that resize frame completes.
|
||||
*/
|
||||
void setMainWindowSizeChangeTransaction(SurfaceControl.Transaction t) {
|
||||
mMainWindowSizeChangeTransaction = t;
|
||||
}
|
||||
|
||||
SurfaceControl.Transaction getMainWindowSizeChangeTransaction() {
|
||||
return mMainWindowSizeChangeTransaction;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -553,6 +553,12 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub
|
||||
WindowContainerTransaction.Change c) {
|
||||
int effects = sanitizeAndApplyChange(wc, c);
|
||||
|
||||
final SurfaceControl.Transaction t = c.getBoundsChangeTransaction();
|
||||
if (t != null) {
|
||||
Task tr = (Task) wc;
|
||||
tr.setMainWindowSizeChangeTransaction(t);
|
||||
}
|
||||
|
||||
Rect enterPipBounds = c.getEnterPipBounds();
|
||||
if (enterPipBounds != null) {
|
||||
Task tr = (Task) wc;
|
||||
|
||||
@@ -873,6 +873,14 @@ class WindowStateAnimator {
|
||||
clipRect = mTmpClipRect;
|
||||
}
|
||||
|
||||
if (mSurfaceResized && (mAttrType == TYPE_BASE_APPLICATION) &&
|
||||
(task != null) && (task.getMainWindowSizeChangeTransaction() != null)) {
|
||||
mSurfaceController.deferTransactionUntil(mWin.getDeferTransactionBarrier(),
|
||||
mWin.getFrameNumber());
|
||||
SurfaceControl.mergeToGlobalTransaction(task.getMainWindowSizeChangeTransaction());
|
||||
task.setMainWindowSizeChangeTransaction(null);
|
||||
}
|
||||
|
||||
float surfaceWidth = mSurfaceController.getWidth();
|
||||
float surfaceHeight = mSurfaceController.getHeight();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user