From 296f8a1e0971bbd56fcfa56a6e1a95cfc56a2c2b Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Wed, 31 May 2023 23:13:45 -0600 Subject: [PATCH] Avoid applying weird wallpaper offset The case may almost only happen with image wallpaper that will set requested size larger than screen to support scroll. Usually it is hard to observe because it may be updated to correct state in a short time. Sometimes the window hierarchy may have updated to new orientation, then the parent frame will be assigned based on configuration bounds. But the specified requested size has higher priority to affect window frame. So if the wallpaper client has not updated the new size according to the new orientation, the offset may put wallpaper at a weird position. Bug: 281973565 Test: Rapidly switch between apps and home with different orientation. Change-Id: I53a44f389e7e8a9ae193e1e4dfac6e0f344e5200 --- .../server/wm/WallpaperController.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java index 20ce98ca2faee..4616e6b2a6800 100644 --- a/services/core/java/com/android/server/wm/WallpaperController.java +++ b/services/core/java/com/android/server/wm/WallpaperController.java @@ -401,6 +401,19 @@ class WallpaperController { // swiping through Launcher pages). final Rect wallpaperFrame = wallpaperWin.getFrame(); + final int diffWidth = wallpaperFrame.width() - lastWallpaperBounds.width(); + final int diffHeight = wallpaperFrame.height() - lastWallpaperBounds.height(); + if ((wallpaperWin.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0 + && Math.abs(diffWidth) > 1 && Math.abs(diffHeight) > 1) { + Slog.d(TAG, "Skip wallpaper offset with inconsistent orientation, bounds=" + + lastWallpaperBounds + " frame=" + wallpaperFrame); + // With FLAG_SCALED, the requested size should at least make the frame match one of + // side. If both sides contain differences, the client side may not have updated the + // latest size according to the current orientation. So skip calculating the offset to + // avoid the wallpaper not filling the screen. + return false; + } + int newXOffset = 0; int newYOffset = 0; boolean rawChanged = false; @@ -417,7 +430,7 @@ class WallpaperController { float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f; // Difference between width of wallpaper image, and the last size of the wallpaper. // This is the horizontal surplus from the prior configuration. - int availw = wallpaperFrame.width() - lastWallpaperBounds.width(); + int availw = diffWidth; int displayOffset = getDisplayWidthOffset(availw, lastWallpaperBounds, wallpaperWin.isRtl()); @@ -442,9 +455,7 @@ class WallpaperController { float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f; float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f; - int availh = wallpaperWin.getFrame().bottom - wallpaperWin.getFrame().top - - lastWallpaperBounds.height(); - offset = availh > 0 ? -(int)(availh * wpy + .5f) : 0; + offset = diffHeight > 0 ? -(int) (diffHeight * wpy + .5f) : 0; if (mLastWallpaperDisplayOffsetY != Integer.MIN_VALUE) { offset += mLastWallpaperDisplayOffsetY; }