diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index eea0ca0666f7d..8a9ace780ad51 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -595,6 +595,12 @@ class Task implements DimLayer.DimLayerUser { if (win.mHasSurface && !resizingWindows.contains(win)) { if (DEBUG_RESIZE) Slog.d(TAG, "resizeWindows: Resizing " + win); resizingWindows.add(win); + + // If we are not drag resizing, force recreating of a new surface so updating + // the content and positioning that surface will be in sync. + if (!win.computeDragResizing()) { + win.mResizedWhileNotDragResizing = true; + } } if (win.isGoneForLayoutLw()) { win.mResizedWhileGone = true; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index a632bdb7beefd..e07dbff432b99 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2935,8 +2935,9 @@ public class WindowManagerService extends IWindowManager.Stub // If we're starting a drag-resize, we'll be changing the surface size as well as // notifying the client to render to with an offset from the surface's top-left. - if (win.isDragResizeChanged()) { + if (win.isDragResizeChanged() || win.mResizedWhileNotDragResizing) { win.setDragResizing(); + win.mResizedWhileNotDragResizing = false; // 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 // to preserve and destroy windows which are attached to another, they @@ -9021,7 +9022,8 @@ public class WindowManagerService extends IWindowManager.Stub || winAnimator.mSurfaceResized || w.mOutsetsChanged || configChanged - || dragResizingChanged) { + || dragResizingChanged + || w.mResizedWhileNotDragResizing) { if (DEBUG_RESIZE || DEBUG_ORIENTATION) { Slog.v(TAG_WM, "Resize reasons for w=" + w + ": " + " contentInsetsChanged=" + w.mContentInsetsChanged @@ -9055,7 +9057,8 @@ public class WindowManagerService extends IWindowManager.Stub // the display until this window has been redrawn; to do that, // we need to go through the process of getting informed by the // application when it has finished drawing. - if (w.mOrientationChanging || dragResizingChanged) { + if (w.mOrientationChanging || dragResizingChanged + || w.mResizedWhileNotDragResizing) { if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION || DEBUG_RESIZE) { Slog.v(TAG_WM, "Orientation or resize start waiting for draw" + ", mDrawState=DRAW_PENDING in " + w diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 1eca4d444db99..ddfc022aeb3f3 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -468,6 +468,13 @@ final class WindowState implements WindowManagerPolicy.WindowState { */ boolean mResizedWhileGone = false; + /** + * Indicates whether we got resized but drag resizing flag was false. In this case, we also + * need to recreate the surface and defer surface bound updates in order to make sure the + * buffer contents and the positioning/size stay in sync. + */ + boolean mResizedWhileNotDragResizing; + WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token, WindowState attachedWindow, int appOp, int seq, WindowManager.LayoutParams a, int viewVisibility, final DisplayContent displayContent) { diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 8fd8bc06a90ab..34452ee1eefa4 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -1318,6 +1318,11 @@ class WindowStateAnimator { final WindowState w = mWin; final Task task = w.getTask(); + // We got resized, so block all updates until we got the new surface. + if (w.mResizedWhileNotDragResizing) { + return; + } + mTmpSize.set(w.mShownPosition.x, w.mShownPosition.y, 0, 0); calculateSurfaceBounds(w, w.getAttrs());