diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java index 35e54912b33e1..45c4233b40aaa 100644 --- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java @@ -30,6 +30,7 @@ import static com.android.server.wm.InsetsSourceProviderProto.CONTROLLABLE; import static com.android.server.wm.InsetsSourceProviderProto.CONTROL_TARGET; import static com.android.server.wm.InsetsSourceProviderProto.FAKE_CONTROL; import static com.android.server.wm.InsetsSourceProviderProto.FAKE_CONTROL_TARGET; +import static com.android.server.wm.InsetsSourceProviderProto.FINISH_SEAMLESS_ROTATE_FRAME_NUMBER; import static com.android.server.wm.InsetsSourceProviderProto.FRAME; import static com.android.server.wm.InsetsSourceProviderProto.IME_OVERRIDDEN_FRAME; import static com.android.server.wm.InsetsSourceProviderProto.IS_LEASH_READY_FOR_DISPATCHING; @@ -58,7 +59,6 @@ import com.android.server.wm.SurfaceAnimator.AnimationType; import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback; import java.io.PrintWriter; -import java.util.function.Consumer; /** * Controller for a specific inset source on the server. It's called provider as it provides the @@ -84,16 +84,6 @@ class InsetsSourceProvider { private final Rect mImeOverrideFrame = new Rect(); private boolean mIsLeashReadyForDispatching; - private final Consumer mSetLeashPositionConsumer = t -> { - if (mControl != null) { - final SurfaceControl leash = mControl.getLeash(); - if (leash != null) { - final Point position = mControl.getSurfacePosition(); - t.setPosition(leash, position.x, position.y); - } - } - }; - /** The visibility override from the current controlling window. */ private boolean mClientVisible; @@ -159,6 +149,7 @@ class InsetsSourceProvider { // TODO: Ideally, we should wait for the animation to finish so previous window can // animate-out as new one animates-in. mWin.cancelAnimation(); + mWin.mPendingPositionChanged = null; mWin.mProvidedInsetsSources.remove(mSource.getType()); } ProtoLog.d(WM_DEBUG_IME, "InsetsSource setWin %s", win); @@ -257,16 +248,31 @@ class InsetsSourceProvider { if (mControl != null) { final Point position = getWindowFrameSurfacePosition(); if (mControl.setSurfacePosition(position.x, position.y) && mControlTarget != null) { - if (mWin.getWindowFrames().didFrameSizeChange()) { - mWin.applyWithNextDraw(mSetLeashPositionConsumer); + if (!mWin.getWindowFrames().didFrameSizeChange()) { + updateLeashPosition(-1 /* frameNumber */); + } else if (mWin.mInRelayout) { + updateLeashPosition(mWin.getFrameNumber()); } else { - mSetLeashPositionConsumer.accept(mWin.getPendingTransaction()); + mWin.mPendingPositionChanged = this; } mStateController.notifyControlChanged(mControlTarget); } } } + void updateLeashPosition(long frameNumber) { + if (mControl == null) { + return; + } + final SurfaceControl leash = mControl.getLeash(); + if (leash != null) { + final Transaction t = mDisplayContent.getPendingTransaction(); + final Point position = mControl.getSurfacePosition(); + t.setPosition(leash, position.x, position.y); + deferTransactionUntil(t, leash, frameNumber); + } + } + private Point getWindowFrameSurfacePosition() { final Rect frame = mWin.getFrame(); final Point position = new Point(); @@ -274,6 +280,14 @@ class InsetsSourceProvider { return position; } + private void deferTransactionUntil(Transaction t, SurfaceControl leash, long frameNumber) { + if (frameNumber >= 0) { + final SurfaceControl barrier = mWin.getClientViewRootSurface(); + t.deferTransactionUntil(mWin.getSurfaceControl(), barrier, frameNumber); + t.deferTransactionUntil(leash, barrier, frameNumber); + } + } + /** * @see InsetsStateController#onControlFakeTargetChanged(int, InsetsControlTarget) */ diff --git a/services/core/java/com/android/server/wm/WindowFrames.java b/services/core/java/com/android/server/wm/WindowFrames.java index ffd6d21c1026b..9245f8c3efe5e 100644 --- a/services/core/java/com/android/server/wm/WindowFrames.java +++ b/services/core/java/com/android/server/wm/WindowFrames.java @@ -113,7 +113,7 @@ public class WindowFrames { } /** - * @return true if the width or height has changed since last updating resizing window. + * @return true if the width or height has changed since last reported to the client. */ boolean didFrameSizeChange() { return (mLastFrame.width() != mFrame.width()) || (mLastFrame.height() != mFrame.height()); @@ -134,13 +134,6 @@ public class WindowFrames { return mLastForceReportingResized || mFrameSizeChanged; } - /** - * @return true if the width or height has changed since last reported to the client. - */ - boolean isFrameSizeChangeReported() { - return mFrameSizeChanged || didFrameSizeChange(); - } - /** * Resets the size changed flags so they're all set to false again. This should be called * after the frames are reported to client. diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index f0dc7fe08c665..ec012fc36c896 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2232,6 +2232,11 @@ public class WindowManagerService extends IWindowManager.Stub final DisplayContent dc = win.getDisplayContent(); + if (win.mPendingPositionChanged != null) { + win.mPendingPositionChanged.updateLeashPosition(frameNumber); + win.mPendingPositionChanged = null; + } + if (mUseBLASTSync && win.useBLASTSync() && viewVisibility != View.GONE) { win.prepareDrawHandlers(); result |= RELAYOUT_RES_BLAST_SYNC; diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 7ebc1cc6d5c1f..2eadcd5814175 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -726,6 +726,8 @@ class WindowState extends WindowContainer implements WindowManagerP */ private InsetsState mFrozenInsetsState; + @Nullable InsetsSourceProvider mPendingPositionChanged; + private static final float DEFAULT_DIM_AMOUNT_DEAD_WINDOW = 0.5f; private KeyInterceptionInfo mKeyInterceptionInfo; @@ -772,12 +774,6 @@ class WindowState extends WindowContainer implements WindowManagerP updateSurfacePosition(t); }; - private final Consumer mSetSurfacePositionConsumer = t -> { - if (mSurfaceControl != null && mSurfaceControl.isValid()) { - t.setPosition(mSurfaceControl, mSurfacePosition.x, mSurfacePosition.y); - } - }; - /** * @see #setSurfaceTranslationY(int) */ @@ -2133,8 +2129,6 @@ class WindowState extends WindowContainer implements WindowManagerP : getTask().getWindowConfiguration().hasMovementAnimations(); if (mToken.okToAnimate() && (mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0 - && !mWindowFrames.didFrameSizeChange() - && !surfaceInsetsChanging() && !isDragResizing() && hasMovementAnimation && !mWinAnimator.mLastHidden @@ -5324,17 +5318,13 @@ class WindowState extends WindowContainer implements WindowManagerP // prior to the rotation. if (!mSurfaceAnimator.hasLeash() && mPendingSeamlessRotate == null && !mLastSurfacePosition.equals(mSurfacePosition)) { - final boolean frameSizeChanged = mWindowFrames.isFrameSizeChangeReported(); - final boolean surfaceInsetsChanged = surfaceInsetsChanging(); - final boolean surfaceSizeChanged = frameSizeChanged || surfaceInsetsChanged; + t.setPosition(mSurfaceControl, mSurfacePosition.x, mSurfacePosition.y); mLastSurfacePosition.set(mSurfacePosition.x, mSurfacePosition.y); - if (surfaceInsetsChanged) { + if (surfaceInsetsChanging() && mWinAnimator.hasSurface()) { mLastSurfaceInsets.set(mAttrs.surfaceInsets); - } - if (surfaceSizeChanged) { - applyWithNextDraw(mSetSurfacePositionConsumer); - } else { - mSetSurfacePositionConsumer.accept(t); + t.deferTransactionUntil(mSurfaceControl, + mWinAnimator.mSurfaceController.mSurfaceControl, + getFrameNumber()); } } }