First we have the client pass up the next frameNumber from relayoutWindow
and then we simply deferTransactions at the WindowState level until
this frame number is reached. This was always a little terrifying
because deferring transaction effecftively meant we gave up
control of the surface until the frame number was reached. However now
we can still control the surface from the stack and other SurfaceControl
nodes and so the window can still be moved around and animated even if
the client is unresponsive.
Bug:
70666541
Test: Manual. go/wm-smoke
Change-Id: I2fecbeaa30fc0eb9cc8f08e1ea734dcc65da0aa0
params.backup();
mTranslator.translateWindowLayout(params);
}
+
if (params != null) {
if (DBG) Log.d(mTag, "WindowLayout in layoutWindow:" + params);
- }
- if (params != null && mOrigWindowType != params.type) {
- // For compatibility with old apps, don't crash here.
- if (mTargetSdkVersion < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
- Slog.w(mTag, "Window type can not be changed after "
- + "the window is added; ignoring change of " + mView);
- params.type = mOrigWindowType;
+ if (mOrigWindowType != params.type) {
+ // For compatibility with old apps, don't crash here.
+ if (mTargetSdkVersion < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+ Slog.w(mTag, "Window type can not be changed after "
+ + "the window is added; ignoring change of " + mView);
+ params.type = mOrigWindowType;
+ }
+ }
+
+ if (mSurface.isValid()) {
+ params.frameNumber = mSurface.getNextFrameNumber();
}
}
+
int relayoutResult = mWindowSession.relayout(
mWindow, mSeq, params,
(int) (mView.getMeasuredWidth() * appScale + 0.5f),
public long hideTimeoutMilliseconds = -1;
/**
+ * A frame number in which changes requested in this layout will be rendered.
+ *
+ * @hide
+ */
+ public long frameNumber = -1;
+
+ /**
* The color mode requested by this window. The target display may
* not be able to honor the request. When the color mode is not set
* to {@link ActivityInfo#COLOR_MODE_DEFAULT}, it might override the
TextUtils.writeToParcel(accessibilityTitle, out, parcelableFlags);
out.writeInt(mColorMode);
out.writeLong(hideTimeoutMilliseconds);
+ out.writeLong(frameNumber);
}
public static final Parcelable.Creator<LayoutParams> CREATOR
accessibilityTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
mColorMode = in.readInt();
hideTimeoutMilliseconds = in.readLong();
+ frameNumber = in.readLong();
}
@SuppressWarnings({"PointlessBitwiseExpression"})
changes |= SURFACE_INSETS_CHANGED;
}
+ // The frame number changing is only relevant in the context of other
+ // changes, and so we don't need to track it with a flag.
+ frameNumber = o.frameNumber;
+
if (hasManualSurfaceInsets != o.hasManualSurfaceInsets) {
hasManualSurfaceInsets = o.hasManualSurfaceInsets;
changes |= SURFACE_INSETS_CHANGED;
// When we change the Surface size, in scenarios which may require changing
// the surface position in sync with the resize, we use a preserved surface
// so we can freeze it while waiting for the client to report draw on the newly
- // sized surface. Don't preserve surfaces if the insets change while animating the pinned
- // stack since it can lead to issues if a new surface is created while calculating the
- // scale for the animation using the source hint rect
- // (see WindowStateAnimator#setSurfaceBoundariesLocked()).
- if (isDragResizeChanged()
- || (surfaceInsetsChanging() && !inPinnedWindowingMode())) {
- mLastSurfaceInsets.set(mAttrs.surfaceInsets);
-
+ // sized surface. At the moment this logic is only in place for switching
+ // in and out of the big surface for split screen resize.
+ if (isDragResizeChanged()) {
setDragResizing();
// We can only change top level windows to the full-screen surface when
// resizing (as we only have one full-screen surface). So there is no need
}
transformFrameToSurfacePosition(mFrame.left, mFrame.top, mSurfacePosition);
+
if (!mSurfaceAnimator.hasLeash() && !mLastSurfacePosition.equals(mSurfacePosition)) {
t.setPosition(mSurfaceControl, mSurfacePosition.x, mSurfacePosition.y);
mLastSurfacePosition.set(mSurfacePosition.x, mSurfacePosition.y);
+ if (surfaceInsetsChanging() && mWinAnimator.hasSurface()) {
+ mLastSurfaceInsets.set(mAttrs.surfaceInsets);
+ t.deferTransactionUntil(mSurfaceControl,
+ mWinAnimator.mSurfaceController.mSurfaceControl.getHandle(),
+ mAttrs.frameNumber);
+ }
}
}