From 4fb6cb28969f40b4d81769fd9d486f7fdcc783f9 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Thu, 9 Mar 2023 09:30:23 +0000 Subject: [PATCH] Report pending change to wallpaper when being visible Configuration change will make mLastConfigReportedToClient true. But if the window is invisible, updateResizingWindowIfNeeded may be skipped by isGoneForLayout. So if it becomes visible later, request a traversal to dispatch the change and then the client window (wallpaper) can redraw with the latest state. Fix: 261988495 Test: WallpaperControllerTests#testWallpaperReportConfigChange Change-Id: I7f43811ac6d0582e9b904ad3cad7d98e1605877a --- .../com/android/server/wm/WindowState.java | 2 +- .../server/wm/WallpaperControllerTests.java | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 52f2b6351265b..41e0fd7158897 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -4577,7 +4577,7 @@ class WindowState extends WindowContainer implements WindowManagerP void requestUpdateWallpaperIfNeeded() { final DisplayContent dc = getDisplayContent(); - if (dc != null && hasWallpaper()) { + if (dc != null && ((mIsWallpaper && !mLastConfigReportedToClient) || hasWallpaper())) { dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; dc.setLayoutNeeded(); mWmService.mWindowPlacerLocked.requestTraversal(); diff --git a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java index 1407cdd8600ca..65f31a0e15bbd 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java @@ -52,6 +52,7 @@ import android.graphics.Rect; import android.os.IBinder; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; +import android.util.MergedConfiguration; import android.view.DisplayCutout; import android.view.DisplayInfo; import android.view.Gravity; @@ -61,6 +62,7 @@ import android.view.RoundedCorners; import android.view.Surface; import android.view.SurfaceControl; import android.view.WindowManager; +import android.window.ClientWindowFrames; import androidx.test.filters.SmallTest; @@ -337,6 +339,29 @@ public class WallpaperControllerTests extends WindowTestsBase { assertEquals(appWin, mDisplayContent.mWallpaperController.getWallpaperTarget()); } + @Test + public void testWallpaperReportConfigChange() { + final WindowState wallpaperWindow = createWallpaperWindow(mDisplayContent); + createWallpaperTargetWindow(mDisplayContent); + final WallpaperWindowToken wallpaperToken = wallpaperWindow.mToken.asWallpaperToken(); + makeWindowVisible(wallpaperWindow); + wallpaperWindow.mLayoutSeq = mDisplayContent.mLayoutSeq; + // Assume the token was invisible and the latest config was reported. + wallpaperToken.commitVisibility(false); + wallpaperWindow.fillClientWindowFramesAndConfiguration(new ClientWindowFrames(), + new MergedConfiguration(), true /* useLatestConfig */, false /* relayoutVisible */); + assertTrue(wallpaperWindow.isLastConfigReportedToClient()); + + final Rect bounds = wallpaperToken.getBounds(); + wallpaperToken.setBounds(new Rect(0, 0, bounds.width() / 2, bounds.height() / 2)); + assertFalse(wallpaperWindow.isLastConfigReportedToClient()); + // If there is a pending config change when changing to visible, it should tell the client + // to redraw by WindowState#reportResized. + wallpaperToken.commitVisibility(true); + waitUntilHandlersIdle(); + assertTrue(wallpaperWindow.isLastConfigReportedToClient()); + } + @Test public void testWallpaperTokenVisibility() { final DisplayContent dc = mWm.mRoot.getDefaultDisplay();