From 52385c332a36b5e0f5bd8157a3afcf8a3d1f4e13 Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Tue, 23 Jun 2020 15:56:28 -0700 Subject: [PATCH] Force app to redraw when using bounds change transaction It can be difficult for the shell to determine whether a given WindowContainerTransaction will actually trigger the app to redraw. If the app doesn't redraw their bounds change transaction will be silently dropped. We follow the same pattern used in applySyncTransaction, and force app windows to redraw when a Task receives a bounds change transaction. Bug: 158600827 Test: Existing tests pass. Change-Id: Id537fd865e9d5c7230acd7ae576990dc74d1ecfd --- .../core/java/com/android/server/wm/Task.java | 1 + .../com/android/server/wm/WindowState.java | 30 ++++++++++++++----- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index a7b1209421636..748244e1a5c24 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -4515,6 +4515,7 @@ class Task extends WindowContainer { */ void setMainWindowSizeChangeTransaction(SurfaceControl.Transaction t) { setMainWindowSizeChangeTransaction(t, this); + forAllWindows(WindowState::requestRedrawForSync, true); } private void setMainWindowSizeChangeTransaction(SurfaceControl.Transaction t, Task origin) { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 49ef4e46bfeb5..be32c95e707fa 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -339,7 +339,7 @@ class WindowState extends WindowContainer implements WindowManagerP private boolean mDragResizing; private boolean mDragResizingChangeReported = true; private int mResizeMode; - private boolean mResizeForBlastSyncReported; + private boolean mRedrawForSyncReported; /** * Special mode that is intended only for the rounded corner overlay: during rotation @@ -1402,7 +1402,7 @@ class WindowState extends WindowContainer implements WindowManagerP || configChanged || dragResizingChanged || mReportOrientationChanged - || requestResizeForBlastSync()) { + || shouldSendRedrawForSync()) { ProtoLog.v(WM_DEBUG_RESIZE, "Resize reasons for w=%s: %s surfaceResized=%b configChanged=%b " + "dragResizingChanged=%b reportOrientationChanged=%b", @@ -3562,7 +3562,6 @@ class WindowState extends WindowContainer implements WindowManagerP mReportOrientationChanged = false; mDragResizingChangeReported = true; mWinAnimator.mSurfaceResized = false; - mResizeForBlastSyncReported = true; mWindowFrames.resetInsetsChanged(); final Rect frame = mWindowFrames.mCompatFrame; @@ -3570,11 +3569,13 @@ class WindowState extends WindowContainer implements WindowManagerP final Rect visibleInsets = mWindowFrames.mLastVisibleInsets; final Rect stableInsets = mWindowFrames.mLastStableInsets; final MergedConfiguration mergedConfiguration = mLastReportedConfiguration; - final boolean reportDraw = mWinAnimator.mDrawState == DRAW_PENDING || useBLASTSync(); - final boolean forceRelayout = reportOrientation || isDragResizeChanged(); + final boolean reportDraw = mWinAnimator.mDrawState == DRAW_PENDING || useBLASTSync() || !mRedrawForSyncReported; + final boolean forceRelayout = reportOrientation || isDragResizeChanged() || !mRedrawForSyncReported; final int displayId = getDisplayId(); final DisplayCutout displayCutout = getWmDisplayCutout().getDisplayCutout(); + mRedrawForSyncReported = true; + try { mClient.resized(frame, contentInsets, visibleInsets, stableInsets, reportDraw, mergedConfiguration, getBackdropFrame(frame), forceRelayout, @@ -5821,7 +5822,7 @@ class WindowState extends WindowContainer implements WindowManagerP if (!willSync) { return false; } - mResizeForBlastSyncReported = false; + requestRedrawForSync(); mLocalSyncId = mBLASTSyncEngine.startSyncSet(this); addChildrenToSyncSet(mLocalSyncId); @@ -5882,7 +5883,20 @@ class WindowState extends WindowContainer implements WindowManagerP notifyBlastSyncTransaction(); } - private boolean requestResizeForBlastSync() { - return useBLASTSync() && !mResizeForBlastSyncReported; + /** + * When using the two WindowOrganizer sync-primitives (BoundsChangeTransaction, BLASTSync) + * it can be a little difficult to predict whether your change will actually trigger redrawing + * on the client side. To ease the burden on shell developers, we force send MSG_RESIZED + * for Windows involved in these Syncs + */ + private boolean shouldSendRedrawForSync() { + final Task task = getTask(); + if (task != null && task.getMainWindowSizeChangeTransaction() != null) + return !mRedrawForSyncReported; + return useBLASTSync() && !mRedrawForSyncReported; + } + + void requestRedrawForSync() { + mRedrawForSyncReported = false; } }