Introduce IWindowSession#relayoutAsync

IWindowSession#relayoutAsync is similar to IWindowSession#relayout, but
the former is an oneway method which just sends the layout attributes to
the server. Since the client can compute its own window frame, it just
needs to send attributes to the server without getting blocked for
receving the window frame.

In somes cases, the client still needs to obtain things from the server.
Such as:

- When view visibility is changed. The client maybe not be able to
  receive the latest insets state while it is INVISIBLE or GONE. In this
  case, the client needs to obtain the frame and the insets state. Also,
  the client need to obtain the surface control when it becomes VISIBLE.

- When the insets state is stale but the config is up-to-date. This can
  happen when WindowProcessController sends the new config to the client
  before WindowState does. In this case, the client needs to obtain the
  window frame from the server.

- When the position and the size of the frame are both changed. This
  will trigger a BLAST sync, and the client needs to obtain the sync seq
  ID.

For cases above, the client needs to call the original relayout method.

Bug: 161810301
Bug: 175861051
Test: Seamless rotation, fixed rotation, and regular rotation.
Merged-In: Ifb365789fa08103773fd3180e486ba1d92042fc5
Change-Id: Ifb365789fa08103773fd3180e486ba1d92042fc5
This commit is contained in:
Tiger Huang 2022-07-07 20:00:25 +08:00
parent 490acded90
commit 3712433349
11 changed files with 235 additions and 181 deletions

View File

@ -153,9 +153,9 @@ public class RelayoutPerfTest extends WindowManagerPerfTestBase
final IWindowSession session = WindowManagerGlobal.getWindowSession();
while (state.keepRunning()) {
session.relayout(mWindow, mParams, mWidth, mHeight,
mViewVisibility.getAsInt(), mFlags, mOutFrames,
mOutMergedConfiguration, mOutSurfaceControl, mOutInsetsState, mOutControls,
new Bundle());
mViewVisibility.getAsInt(), mFlags, 0 /* seq */, 0 /* lastSyncSeqId */,
mOutFrames, mOutMergedConfiguration, mOutSurfaceControl, mOutInsetsState,
mOutControls, new Bundle());
}
}
}

View File

@ -1154,8 +1154,8 @@ public abstract class WallpaperService extends Service {
mLayout.surfaceInsets.set(0, 0, 0, 0);
}
final int relayoutResult = mSession.relayout(mWindow, mLayout, mWidth, mHeight,
View.VISIBLE, 0, mWinFrames, mMergedConfiguration, mSurfaceControl,
mInsetsState, mTempControls, mSyncSeqIdBundle);
View.VISIBLE, 0, 0, 0, mWinFrames, mMergedConfiguration,
mSurfaceControl, mInsetsState, mTempControls, mSyncSeqIdBundle);
final int transformHint = SurfaceControl.rotationToBufferTransform(
(mDisplayInstallOrientation + mDisplay.getRotation()) % 4);

View File

@ -75,41 +75,42 @@ interface IWindowSession {
* @param requestedWidth The width the window wants to be.
* @param requestedHeight The height the window wants to be.
* @param viewVisibility Window root view's visibility.
* @param flags Request flags: {@link WindowManagerGlobal#RELAYOUT_INSETS_PENDING},
* {@link WindowManagerGlobal#RELAYOUT_DEFER_SURFACE_DESTROY}.
* @param outFrame Rect in which is placed the new position/size on
* screen.
* @param outContentInsets Rect in which is placed the offsets from
* <var>outFrame</var> in which the content of the window should be
* placed. This can be used to modify the window layout to ensure its
* contents are visible to the user, taking into account system windows
* like the status bar or a soft keyboard.
* @param outVisibleInsets Rect in which is placed the offsets from
* <var>outFrame</var> in which the window is actually completely visible
* to the user. This can be used to temporarily scroll the window's
* contents to make sure the user can see it. This is different than
* <var>outContentInsets</var> in that these insets change transiently,
* so complex relayout of the window should not happen based on them.
* @param outOutsets Rect in which is placed the dead area of the screen that we would like to
* treat as real display. Example of such area is a chin in some models of wearable devices.
* @param outBackdropFrame Rect which is used draw the resizing background during a resize
* operation.
* @param flags Request flags: {@link WindowManagerGlobal#RELAYOUT_INSETS_PENDING}.
* @param seq The calling sequence of {@link #relayout} and {@link #relayoutAsync}.
* @param lastSyncSeqId The last SyncSeqId that the client applied.
* @param outFrames The window frames used by the client side for layout.
* @param outMergedConfiguration New config container that holds global, override and merged
* config for window, if it is now becoming visible and the merged configuration has changed
* since it was last displayed.
* @param outSurface Object in which is placed the new display surface.
* config for window, if it is now becoming visible and the merged
* config has changed since it was last displayed.
* @param outSurfaceControl Object in which is placed the new display surface.
* @param insetsState The current insets state in the system.
*
* @return int Result flags: {@link WindowManagerGlobal#RELAYOUT_SHOW_FOCUS},
* {@link WindowManagerGlobal#RELAYOUT_FIRST_TIME}.
* @param activeControls Objects which allow controlling {@link InsetsSource}s.
* @param bundle A temporary object to obtain the latest SyncSeqId.
* @return int Result flags, defined in {@link WindowManagerGlobal}.
*/
int relayout(IWindow window, in WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewVisibility,
int flags, out ClientWindowFrames outFrames,
int flags, int seq, int lastSyncSeqId, out ClientWindowFrames outFrames,
out MergedConfiguration outMergedConfiguration, out SurfaceControl outSurfaceControl,
out InsetsState insetsState, out InsetsSourceControl[] activeControls,
out Bundle bundle);
/**
* Similar to {@link #relayout} but this is an oneway method which doesn't return anything.
*
* @param window The window being modified.
* @param attrs If non-null, new attributes to apply to the window.
* @param requestedWidth The width the window wants to be.
* @param requestedHeight The height the window wants to be.
* @param viewVisibility Window root view's visibility.
* @param flags Request flags: {@link WindowManagerGlobal#RELAYOUT_INSETS_PENDING}.
* @param seq The calling sequence of {@link #relayout} and {@link #relayoutAsync}.
* @param lastSyncSeqId The last SyncSeqId that the client applied.
*/
oneway void relayoutAsync(IWindow window, in WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewVisibility, int flags, int seq,
int lastSyncSeqId);
/*
* Notify the window manager that an application is relaunching and
* windows should be prepared for replacement.

View File

@ -75,6 +75,7 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INSET_PARENT_
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
@ -706,6 +707,8 @@ public final class ViewRootImpl implements ViewParent,
final Rect mPendingBackDropFrame = new Rect();
boolean mPendingAlwaysConsumeSystemBars;
private int mRelayoutSeq;
private final Rect mWinFrameInScreen = new Rect();
private final InsetsState mTempInsets = new InsetsState();
private final InsetsSourceControl[] mTempControls = new InsetsSourceControl[SIZE];
private final WindowConfiguration mTempWinConfig = new WindowConfiguration();
@ -3333,20 +3336,6 @@ public final class ViewRootImpl implements ViewParent,
}
}
} else {
// If a relayout isn't going to happen, we still need to check if this window can draw
// when mCheckIfCanDraw is set. This is because it means we had a sync in the past, but
// have not been told by WMS that the sync is complete and that we can continue to draw
if (mCheckIfCanDraw) {
try {
cancelDraw = mWindowSession.cancelDraw(mWindow);
cancelReason = "wm_sync";
if (DEBUG_BLAST) {
Log.d(mTag, "cancelDraw returned " + cancelDraw);
}
} catch (RemoteException e) {
}
}
// Not the first pass and no window/insets/visibility change but the window
// may have moved and we need check that and if so to update the left and right
// in the attach info. We translate only the window frame since on window move
@ -3355,6 +3344,20 @@ public final class ViewRootImpl implements ViewParent,
maybeHandleWindowMove(frame);
}
if (!mRelayoutRequested && mCheckIfCanDraw) {
// We had a sync previously, but we didn't call IWindowSession#relayout in this
// traversal. So we don't know if the sync is complete that we can continue to draw.
// Here invokes cancelDraw to obtain the information.
try {
cancelDraw = mWindowSession.cancelDraw(mWindow);
cancelReason = "wm_sync";
if (DEBUG_BLAST) {
Log.d(mTag, "cancelDraw returned " + cancelDraw);
}
} catch (RemoteException e) {
}
}
if (surfaceSizeChanged || surfaceReplaced || surfaceCreated || windowAttributesChanged) {
// If the surface has been replaced, there's a chance the bounds layer is not parented
// to the new layer. When updating bounds layer, also reparent to the main VRI
@ -8082,7 +8085,43 @@ public final class ViewRootImpl implements ViewParent,
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
boolean insetsPending) throws RemoteException {
mRelayoutRequested = true;
final WindowConfiguration winConfigFromAm = getConfiguration().windowConfiguration;
final WindowConfiguration winConfigFromWm =
mLastReportedMergedConfiguration.getGlobalConfiguration().windowConfiguration;
final WindowConfiguration winConfig = getCompatWindowConfiguration();
final int measuredWidth = mView.getMeasuredWidth();
final int measuredHeight = mView.getMeasuredHeight();
final boolean relayoutAsync;
if (LOCAL_LAYOUT && !mFirst && viewVisibility == mViewVisibility
&& mWindowAttributes.type != TYPE_APPLICATION_STARTING
&& mSyncSeqId <= mLastSyncSeqId
&& winConfigFromAm.diff(winConfigFromWm, false /* compareUndefined */) == 0) {
final InsetsState state = mInsetsController.getState();
final Rect displayCutoutSafe = mTempRect;
state.getDisplayCutoutSafe(displayCutoutSafe);
mWindowLayout.computeFrames(mWindowAttributes.forRotation(winConfig.getRotation()),
state, displayCutoutSafe, winConfig.getBounds(), winConfig.getWindowingMode(),
measuredWidth, measuredHeight, mInsetsController.getRequestedVisibilities(),
1f /* compatScale */, mTmpFrames);
mWinFrameInScreen.set(mTmpFrames.frame);
if (mTranslator != null) {
mTranslator.translateRectInAppWindowToScreen(mWinFrameInScreen);
}
// If the position and the size of the frame are both changed, it will trigger a BLAST
// sync, and we still need to call relayout to obtain the syncSeqId. Otherwise, we just
// need to send attributes via relayoutAsync.
final Rect oldFrame = mWinFrame;
final Rect newFrame = mTmpFrames.frame;
final boolean positionChanged =
newFrame.top != oldFrame.top || newFrame.left != oldFrame.left;
final boolean sizeChanged =
newFrame.width() != oldFrame.width() || newFrame.height() != oldFrame.height();
relayoutAsync = !positionChanged || !sizeChanged;
} else {
relayoutAsync = false;
}
float appScale = mAttachInfo.mApplicationScale;
boolean restore = false;
if (params != null && mTranslator != null) {
@ -8104,26 +8143,47 @@ public final class ViewRootImpl implements ViewParent,
}
}
final int requestedWidth = (int) (mView.getMeasuredWidth() * appScale + 0.5f);
final int requestedHeight = (int) (mView.getMeasuredHeight() * appScale + 0.5f);
final int requestedWidth = (int) (measuredWidth * appScale + 0.5f);
final int requestedHeight = (int) (measuredHeight * appScale + 0.5f);
int relayoutResult = 0;
mRelayoutSeq++;
if (relayoutAsync) {
mWindowSession.relayoutAsync(mWindow, params,
requestedWidth, requestedHeight, viewVisibility,
insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, mRelayoutSeq,
mLastSyncSeqId);
} else {
relayoutResult = mWindowSession.relayout(mWindow, params,
requestedWidth, requestedHeight, viewVisibility,
insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, mRelayoutSeq,
mLastSyncSeqId, mTmpFrames, mPendingMergedConfiguration, mSurfaceControl,
mTempInsets, mTempControls, mRelayoutBundle);
mRelayoutRequested = true;
final int maybeSyncSeqId = mRelayoutBundle.getInt("seqid");
if (maybeSyncSeqId > 0) {
mSyncSeqId = maybeSyncSeqId;
}
mWinFrameInScreen.set(mTmpFrames.frame);
if (mTranslator != null) {
mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame);
mTranslator.translateRectInScreenToAppWindow(mTmpFrames.displayFrame);
mTranslator.translateRectInScreenToAppWindow(mTmpFrames.attachedFrame);
mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets);
mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls);
}
mInvSizeCompatScale = 1f / mTmpFrames.sizeCompatScale;
mInsetsController.onStateChanged(mTempInsets);
mInsetsController.onControlsChanged(mTempControls);
int relayoutResult = mWindowSession.relayout(mWindow, params,
requestedWidth, requestedHeight, viewVisibility,
insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
mTempControls, mRelayoutBundle);
final int maybeSyncSeqId = mRelayoutBundle.getInt("seqid");
if (maybeSyncSeqId > 0) {
mSyncSeqId = maybeSyncSeqId;
mPendingAlwaysConsumeSystemBars =
(relayoutResult & RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS) != 0;
}
mInvSizeCompatScale = 1f / mTmpFrames.sizeCompatScale;
final int transformHint = SurfaceControl.rotationToBufferTransform(
(mDisplayInstallOrientation + mDisplay.getRotation()) % 4);
final WindowConfiguration winConfig = getCompatWindowConfiguration();
WindowLayout.computeSurfaceSize(mWindowAttributes, winConfig.getMaxBounds(), requestedWidth,
requestedHeight, mTmpFrames.frame, mPendingDragResizing, mSurfaceSize);
requestedHeight, mWinFrameInScreen, mPendingDragResizing, mSurfaceSize);
final boolean transformHintChanged = transformHint != mLastTransformHint;
final boolean sizeChanged = !mLastSurfaceSize.equals(mSurfaceSize);
@ -8170,23 +8230,11 @@ public final class ViewRootImpl implements ViewParent,
destroySurface();
}
mPendingAlwaysConsumeSystemBars =
(relayoutResult & RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS) != 0;
if (restore) {
params.restore();
}
if (mTranslator != null) {
mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame);
mTranslator.translateRectInScreenToAppWindow(mTmpFrames.displayFrame);
mTranslator.translateRectInScreenToAppWindow(mTmpFrames.attachedFrame);
mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets);
mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls);
}
setFrame(mTmpFrames.frame);
mInsetsController.onStateChanged(mTempInsets);
mInsetsController.onControlsChanged(mTempControls);
return relayoutResult;
}

View File

@ -286,10 +286,11 @@ public class WindowlessWindowManager implements IWindowSession {
@Override
public int relayout(IWindow window, WindowManager.LayoutParams inAttrs,
int requestedWidth, int requestedHeight, int viewFlags, int flags,
ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
SurfaceControl outSurfaceControl, InsetsState outInsetsState,
InsetsSourceControl[] outActiveControls, Bundle outSyncSeqIdBundle) {
int requestedWidth, int requestedHeight, int viewFlags, int flags, int seq,
int lastSyncSeqId, ClientWindowFrames outFrames,
MergedConfiguration outMergedConfiguration, SurfaceControl outSurfaceControl,
InsetsState outInsetsState, InsetsSourceControl[] outActiveControls,
Bundle outSyncSeqIdBundle) {
final State state;
synchronized (this) {
state = mStateForWindow.get(window.asBinder());
@ -309,15 +310,23 @@ public class WindowlessWindowManager implements IWindowSession {
if (viewFlags == View.VISIBLE) {
t.setOpaque(sc, isOpaque(attrs)).show(sc).apply();
outSurfaceControl.copyFrom(sc, "WindowlessWindowManager.relayout");
if (outSurfaceControl != null) {
outSurfaceControl.copyFrom(sc, "WindowlessWindowManager.relayout");
}
} else {
t.hide(sc).apply();
outSurfaceControl.release();
if (outSurfaceControl != null) {
outSurfaceControl.release();
}
}
if (outFrames != null) {
outFrames.frame.set(0, 0, attrs.width, attrs.height);
outFrames.displayFrame.set(outFrames.frame);
}
outFrames.frame.set(0, 0, attrs.width, attrs.height);
outFrames.displayFrame.set(outFrames.frame);
mergedConfiguration.setConfiguration(mConfiguration, mConfiguration);
if (outMergedConfiguration != null) {
outMergedConfiguration.setConfiguration(mConfiguration, mConfiguration);
}
if ((attrChanges & WindowManager.LayoutParams.FLAGS_CHANGED) != 0
&& state.mInputChannelToken != null) {
@ -335,13 +344,23 @@ public class WindowlessWindowManager implements IWindowSession {
}
}
if (mInsetsState != null) {
if (outInsetsState != null && mInsetsState != null) {
outInsetsState.set(mInsetsState);
}
return 0;
}
@Override
public void relayoutAsync(IWindow window, WindowManager.LayoutParams inAttrs,
int requestedWidth, int requestedHeight, int viewFlags, int flags, int seq,
int lastSyncSeqId) {
relayout(window, inAttrs, requestedWidth, requestedHeight, viewFlags, flags, seq,
lastSyncSeqId, null /* outFrames */, null /* outMergedConfiguration */,
null /* outSurfaceControl */, null /* outInsetsState */,
null /* outActiveControls */, null /* outSyncSeqIdBundle */);
}
@Override
public void prepareToReplaceWindows(android.os.IBinder appToken, boolean childrenOnly) {
}

View File

@ -246,7 +246,7 @@ public class TaskSnapshotWindow {
window.setOuter(snapshotSurface);
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "TaskSnapshot#relayout");
session.relayout(window, layoutParams, -1, -1, View.VISIBLE, 0,
session.relayout(window, layoutParams, -1, -1, View.VISIBLE, 0, 0, 0,
tmpFrames, tmpMergedConfiguration, surfaceControl, tmpInsetsState,
tmpControls, new Bundle());
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);

View File

@ -53,7 +53,6 @@ import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
import static android.view.View.GONE;
import static android.view.ViewRootImpl.LOCAL_LAYOUT;
import static android.view.WindowInsets.Type.displayCutout;
import static android.view.WindowInsets.Type.ime;
import static android.view.WindowInsets.Type.systemBars;
@ -2707,25 +2706,22 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mCurrentPrivacyIndicatorBounds =
mCurrentPrivacyIndicatorBounds.updateStaticBounds(staticBounds);
if (!Objects.equals(oldBounds, mCurrentPrivacyIndicatorBounds)) {
updateDisplayFrames(false /* insetsSourceMayChange */, true /* notifyInsetsChange */);
updateDisplayFrames(true /* notifyInsetsChange */);
}
}
void onDisplayInfoChanged() {
updateDisplayFrames(LOCAL_LAYOUT, LOCAL_LAYOUT);
updateDisplayFrames(false /* notifyInsetsChange */);
mMinSizeOfResizeableTaskDp = getMinimalTaskSizeDp();
mInputMonitor.layoutInputConsumers(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
mDisplayPolicy.onDisplayInfoChanged(mDisplayInfo);
}
private void updateDisplayFrames(boolean insetsSourceMayChange, boolean notifyInsetsChange) {
private void updateDisplayFrames(boolean notifyInsetsChange) {
if (mDisplayFrames.update(mDisplayInfo,
calculateDisplayCutoutForRotation(mDisplayInfo.rotation),
calculateRoundedCornersForRotation(mDisplayInfo.rotation),
calculatePrivacyIndicatorBoundsForRotation(mDisplayInfo.rotation))) {
if (insetsSourceMayChange) {
mDisplayPolicy.updateInsetsSourceFramesExceptIme(mDisplayFrames);
}
mInsetsStateController.onDisplayFramesUpdated(notifyInsetsChange);
}
}

View File

@ -1576,19 +1576,6 @@ public class DisplayPolicy {
}
}
void updateInsetsSourceFramesExceptIme(DisplayFrames displayFrames) {
sTmpClientFrames.attachedFrame = null;
for (int i = mInsetsSourceWindowsExceptIme.size() - 1; i >= 0; i--) {
final WindowState win = mInsetsSourceWindowsExceptIme.valueAt(i);
mWindowLayout.computeFrames(win.mAttrs.forRotation(displayFrames.mRotation),
displayFrames.mInsetsState, displayFrames.mDisplayCutoutSafe,
displayFrames.mUnrestricted, win.getWindowingMode(), UNSPECIFIED_LENGTH,
UNSPECIFIED_LENGTH, win.getRequestedVisibilities(), win.mGlobalScale,
sTmpClientFrames);
win.updateSourceFrame(sTmpClientFrames.frame);
}
}
void onDisplayInfoChanged(DisplayInfo info) {
mSystemGestures.onDisplayInfoChanged(info);
}

View File

@ -242,16 +242,17 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
@Override
public int relayout(IWindow window, WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewFlags, int flags,
ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
SurfaceControl outSurfaceControl, InsetsState outInsetsState,
InsetsSourceControl[] outActiveControls, Bundle outSyncSeqIdBundle) {
int requestedWidth, int requestedHeight, int viewFlags, int flags, int seq,
int lastSyncSeqId, ClientWindowFrames outFrames,
MergedConfiguration mergedConfiguration, SurfaceControl outSurfaceControl,
InsetsState outInsetsState, InsetsSourceControl[] outActiveControls,
Bundle outSyncSeqIdBundle) {
if (false) Slog.d(TAG_WM, ">>>>>> ENTERED relayout from "
+ Binder.getCallingPid());
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mRelayoutTag);
int res = mService.relayoutWindow(this, window, attrs,
requestedWidth, requestedHeight, viewFlags, flags,
outFrames, mergedConfiguration, outSurfaceControl, outInsetsState,
requestedWidth, requestedHeight, viewFlags, flags, seq,
lastSyncSeqId, outFrames, mergedConfiguration, outSurfaceControl, outInsetsState,
outActiveControls, outSyncSeqIdBundle);
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
if (false) Slog.d(TAG_WM, "<<<<<< EXITING relayout to "
@ -259,6 +260,16 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
return res;
}
@Override
public void relayoutAsync(IWindow window, WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewFlags, int flags, int seq,
int lastSyncSeqId) {
relayout(window, attrs, requestedWidth, requestedHeight, viewFlags, flags, seq,
lastSyncSeqId, null /* outFrames */, null /* mergedConfiguration */,
null /* outSurfaceControl */, null /* outInsetsState */,
null /* outActiveControls */, null /* outSyncIdBundle */);
}
@Override
public boolean outOfMemory(IWindow window) {
return mService.outOfMemoryWindow(this, window);

View File

@ -2246,11 +2246,14 @@ public class WindowManagerService extends IWindowManager.Stub
}
public int relayoutWindow(Session session, IWindow client, LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewVisibility, int flags,
ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
SurfaceControl outSurfaceControl, InsetsState outInsetsState,
InsetsSourceControl[] outActiveControls, Bundle outSyncIdBundle) {
Arrays.fill(outActiveControls, null);
int requestedWidth, int requestedHeight, int viewVisibility, int flags, int seq,
int lastSyncSeqId, ClientWindowFrames outFrames,
MergedConfiguration outMergedConfiguration, SurfaceControl outSurfaceControl,
InsetsState outInsetsState, InsetsSourceControl[] outActiveControls,
Bundle outSyncIdBundle) {
if (outActiveControls != null) {
Arrays.fill(outActiveControls, null);
}
int result = 0;
boolean configChanged;
final int pid = Binder.getCallingPid();
@ -2261,8 +2264,15 @@ public class WindowManagerService extends IWindowManager.Stub
if (win == null) {
return 0;
}
if (win.mRelayoutSeq < seq) {
win.mRelayoutSeq = seq;
} else if (win.mRelayoutSeq > seq) {
return 0;
}
if (win.cancelAndRedraw() && win.mPrepareSyncSeqId <= win.mLastSeqIdSentToRelayout) {
if (win.cancelAndRedraw() && win.mPrepareSyncSeqId <= lastSyncSeqId) {
// The client has reported the sync draw, but we haven't finished it yet.
// Don't let the client perform a non-sync draw at this time.
result |= RELAYOUT_RES_CANCEL_AND_REDRAW;
}
@ -2431,7 +2441,7 @@ public class WindowManagerService extends IWindowManager.Stub
// Create surfaceControl before surface placement otherwise layout will be skipped
// (because WS.isGoneForLayout() is true when there is no surface.
if (shouldRelayout) {
if (shouldRelayout && outSurfaceControl != null) {
try {
result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
} catch (Exception e) {
@ -2470,22 +2480,25 @@ public class WindowManagerService extends IWindowManager.Stub
winAnimator.mEnterAnimationPending = false;
winAnimator.mEnteringAnimation = false;
if (viewVisibility == View.VISIBLE && winAnimator.hasSurface()) {
// We already told the client to go invisible, but the message may not be
// handled yet, or it might want to draw a last frame. If we already have a
// surface, let the client use that, but don't create new surface at this point.
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: getSurface");
winAnimator.mSurfaceController.getSurfaceControl(outSurfaceControl);
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
} else {
if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Releasing surface in: " + win);
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wmReleaseOutSurface_"
+ win.mAttrs.getTitle());
outSurfaceControl.release();
} finally {
if (outSurfaceControl != null) {
if (viewVisibility == View.VISIBLE && winAnimator.hasSurface()) {
// We already told the client to go invisible, but the message may not be
// handled yet, or it might want to draw a last frame. If we already have a
// surface, let the client use that, but don't create new surface at this
// point.
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: getSurface");
winAnimator.mSurfaceController.getSurfaceControl(outSurfaceControl);
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
} else {
if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Releasing surface in: " + win);
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wmReleaseOutSurface_"
+ win.mAttrs.getTitle());
outSurfaceControl.release();
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
}
@ -2538,20 +2551,16 @@ public class WindowManagerService extends IWindowManager.Stub
win.mResizedWhileGone = false;
}
win.fillClientWindowFramesAndConfiguration(outFrames, mergedConfiguration,
false /* useLatestConfig */, shouldRelayout);
if (outFrames != null && outMergedConfiguration != null) {
win.fillClientWindowFramesAndConfiguration(outFrames, outMergedConfiguration,
false /* useLatestConfig */, shouldRelayout);
// Set resize-handled here because the values are sent back to the client.
win.onResizeHandled();
// Set resize-handled here because the values are sent back to the client.
win.onResizeHandled();
}
outInsetsState.set(win.getCompatInsetsState(), win.isClientLocal());
if (DEBUG) {
Slog.v(TAG_WM, "Relayout given client " + client.asBinder()
+ ", requestedWidth=" + requestedWidth
+ ", requestedHeight=" + requestedHeight
+ ", viewVisibility=" + viewVisibility
+ "\nRelayout returning frame=" + outFrames.frame
+ ", surface=" + outSurfaceControl);
if (outInsetsState != null) {
outInsetsState.set(win.getCompatInsetsState(), win.isClientLocal());
}
ProtoLog.v(WM_DEBUG_FOCUS, "Relayout of %s: focusMayChange=%b",
@ -2562,14 +2571,16 @@ public class WindowManagerService extends IWindowManager.Stub
}
win.mInRelayout = false;
if (mUseBLASTSync && win.useBLASTSync() && viewVisibility != View.GONE
&& (win.mSyncSeqId > win.mLastSeqIdSentToRelayout)) {
win.markRedrawForSyncReported();
win.mLastSeqIdSentToRelayout = win.mSyncSeqId;
outSyncIdBundle.putInt("seqid", win.mSyncSeqId);
} else {
outSyncIdBundle.putInt("seqid", -1);
if (outSyncIdBundle != null) {
final int maybeSyncSeqId;
if (mUseBLASTSync && win.useBLASTSync() && viewVisibility != View.GONE
&& win.mSyncSeqId > lastSyncSeqId) {
maybeSyncSeqId = win.mSyncSeqId;
win.markRedrawForSyncReported();
} else {
maybeSyncSeqId = -1;
}
outSyncIdBundle.putInt("seqid", maybeSyncSeqId);
}
if (configChanged) {
@ -2578,7 +2589,9 @@ public class WindowManagerService extends IWindowManager.Stub
displayContent.sendNewConfiguration();
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
getInsetsSourceControls(win, outActiveControls);
if (outActiveControls != null) {
getInsetsSourceControls(win, outActiveControls);
}
}
Binder.restoreCallingIdentity(origId);

View File

@ -390,7 +390,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
* examine the git commit message introducing this comment and variable.2
*/
int mSyncSeqId = 0;
int mLastSeqIdSentToRelayout = 0;
/** The last syncId associated with a prepareSync or 0 when no sync is active. */
int mPrepareSyncSeqId = 0;
@ -426,6 +425,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
boolean mHaveFrame;
boolean mObscured;
int mRelayoutSeq = -1;
int mLayoutSeq = -1;
/**
@ -1350,29 +1350,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
final WindowFrames windowFrames = mWindowFrames;
mTmpRect.set(windowFrames.mParentFrame);
if (LOCAL_LAYOUT) {
windowFrames.mCompatFrame.set(clientWindowFrames.frame);
windowFrames.mDisplayFrame.set(clientWindowFrames.displayFrame);
windowFrames.mParentFrame.set(clientWindowFrames.parentFrame);
windowFrames.mFrame.set(clientWindowFrames.frame);
windowFrames.mFrame.set(clientWindowFrames.frame);
windowFrames.mDisplayFrame.set(clientWindowFrames.displayFrame);
windowFrames.mParentFrame.set(clientWindowFrames.parentFrame);
if (mGlobalScale != 1f) {
// The frames sent from the client need to be adjusted to the real coordinate space.
windowFrames.mFrame.scale(mGlobalScale);
windowFrames.mDisplayFrame.scale(mGlobalScale);
windowFrames.mParentFrame.scale(mGlobalScale);
}
} else {
windowFrames.mDisplayFrame.set(clientWindowFrames.displayFrame);
windowFrames.mParentFrame.set(clientWindowFrames.parentFrame);
windowFrames.mFrame.set(clientWindowFrames.frame);
windowFrames.mCompatFrame.set(windowFrames.mFrame);
if (mInvGlobalScale != 1f) {
// Also, the scaled frame that we report to the app needs to be adjusted to be in
// its coordinate space.
windowFrames.mCompatFrame.scale(mInvGlobalScale);
}
windowFrames.mCompatFrame.set(windowFrames.mFrame);
if (mInvGlobalScale != 1f) {
// Also, the scaled frame that we report to the app needs to be adjusted to be in
// its coordinate space.
windowFrames.mCompatFrame.scale(mInvGlobalScale);
}
windowFrames.setParentFrameWasClippedByDisplayCutout(
clientWindowFrames.isParentFrameClippedByDisplayCutout);
@ -1416,13 +1402,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
updateSourceFrame(windowFrames.mFrame);
if (LOCAL_LAYOUT) {
if (!mHaveFrame) {
// The first frame should not be considered as moved.
updateLastFrames();
}
}
if (mActivityRecord != null && !mIsChildWindow) {
mActivityRecord.layoutLetterbox(this);
}