From 5eeb4070c1a432b5a599554adf30c76afe30c002 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Tue, 21 Dec 2021 00:18:48 +0800 Subject: [PATCH] Fix wallpaper zoom effect with shell transition Currently WallpaperController#adjustWallpaperWindows is called for shell transition at DisplayContent#ensureActivitiesVisible and Transition#onTransactionReady for collecting visibility change of wallpaper. But if wallpaper target is cleared and wallpaper is requested to be invisible, its offset and scale won't be updated. So this change allows visible window to update wallpaper during transition. And make sure the offsets are calculated based on the configuration that reported to client, to avoid mixing coordinates with different orientation. Bug: 211447882 Test: adb shell setprop persist.debug.shell_transit 1; reboot Set static image as wallpaper (don't use live wallpaper). Launch portrait and landscape app from portrait home. Observe the wallpaper should show the same zoom effect. Change-Id: I1db9207c79bc45dedd90e7b13af5517f09abe4a7 --- .../server/wm/WallpaperController.java | 13 ++++++++++--- .../com/android/server/wm/WindowState.java | 19 +++++++++++++++---- .../server/wm/DisplayContentTests.java | 8 +++----- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java index e24be378d29a1..24493e2541e19 100644 --- a/services/core/java/com/android/server/wm/WallpaperController.java +++ b/services/core/java/com/android/server/wm/WallpaperController.java @@ -298,9 +298,9 @@ class WallpaperController { } boolean updateWallpaperOffset(WindowState wallpaperWin, boolean sync) { - final Rect parentFrame = wallpaperWin.getParentFrame(); - final int dw = parentFrame.width(); - final int dh = parentFrame.height(); + final Rect bounds = wallpaperWin.getLastReportedBounds(); + final int dw = bounds.width(); + final int dh = bounds.height(); int xOffset = 0; int yOffset = 0; @@ -448,6 +448,13 @@ class WallpaperController { private void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) { WindowState target = mWallpaperTarget; + if (target == null && changingTarget.mToken.isVisible() + && changingTarget.mTransitionController.inTransition()) { + // If the wallpaper target was cleared during transition, still allows the visible + // window which may have been requested to be invisible to update the offset, e.g. + // zoom effect from home. + target = changingTarget; + } if (target != null) { if (target.mWallpaperX >= 0) { mLastWallpaperX = target.mWallpaperX; diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 0b9174210a19e..8b026bfee15fa 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2882,6 +2882,12 @@ class WindowState extends WindowContainer implements WindowManagerP return mLastReportedConfiguration.getMergedConfiguration(); } + /** Returns the last window configuration bounds reported to the client. */ + Rect getLastReportedBounds() { + final Rect bounds = getLastReportedConfiguration().windowConfiguration.getBounds(); + return !bounds.isEmpty() ? bounds : getBounds(); + } + void adjustStartingWindowFlags() { if (mAttrs.type == TYPE_BASE_APPLICATION && mActivityRecord != null && mActivityRecord.mStartingWindow != null) { @@ -5230,6 +5236,11 @@ class WindowState extends WindowContainer implements WindowManagerP // Child window follows parent's scale. return; } + if (!isVisibleRequested() && !(mIsWallpaper && mToken.isVisible())) { + // Skip if it is requested to be invisible, but if it is wallpaper, it may be in + // transition that still needs to update the scale for zoom effect. + return; + } float newHScale = mHScale * mGlobalScale * mWallpaperScale; float newVScale = mVScale * mGlobalScale * mWallpaperScale; if (mLastHScale != newHScale || @@ -5249,7 +5260,7 @@ class WindowState extends WindowContainer implements WindowManagerP updateSurfacePositionNonOrganized(); // Send information to SurfaceFlinger about the priority of the current window. updateFrameRateSelectionPriorityIfNeeded(); - if (isVisibleRequested()) updateScaleIfNeeded(); + updateScaleIfNeeded(); mWinAnimator.prepareSurfaceLocked(getSyncTransaction()); super.prepareSurfaces(); @@ -5275,11 +5286,11 @@ class WindowState extends WindowContainer implements WindowManagerP mSurfacePosition); if (mWallpaperScale != 1f) { - DisplayInfo displayInfo = getDisplayInfo(); + final Rect bounds = getLastReportedBounds(); Matrix matrix = mTmpMatrix; matrix.setTranslate(mXOffset, mYOffset); - matrix.postScale(mWallpaperScale, mWallpaperScale, displayInfo.logicalWidth / 2f, - displayInfo.logicalHeight / 2f); + matrix.postScale(mWallpaperScale, mWallpaperScale, bounds.exactCenterX(), + bounds.exactCenterY()); matrix.getValues(mTmpMatrixArray); mSurfacePosition.offset(Math.round(mTmpMatrixArray[Matrix.MTRANS_X]), Math.round(mTmpMatrixArray[Matrix.MTRANS_Y])); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index dc0e02800bb29..2ef59f6ac5c97 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -1422,18 +1422,16 @@ public class DisplayContentTests extends WindowTestsBase { assertEquals(config90.orientation, app.getConfiguration().orientation); assertEquals(config90.windowConfiguration.getBounds(), app.getBounds()); - // Make wallaper laid out with the fixed rotation transform. + // Associate wallpaper with the fixed rotation transform. final WindowToken wallpaperToken = mWallpaperWindow.mToken; wallpaperToken.linkFixedRotationTransform(app); - mWallpaperWindow.mLayoutNeeded = true; - performLayout(mDisplayContent); // Force the negative offset to verify it can be updated. mWallpaperWindow.mXOffset = mWallpaperWindow.mYOffset = -1; assertTrue(mDisplayContent.mWallpaperController.updateWallpaperOffset(mWallpaperWindow, false /* sync */)); - assertThat(mWallpaperWindow.mXOffset).isGreaterThan(-1); - assertThat(mWallpaperWindow.mYOffset).isGreaterThan(-1); + assertThat(mWallpaperWindow.mXOffset).isNotEqualTo(-1); + assertThat(mWallpaperWindow.mYOffset).isNotEqualTo(-1); // The wallpaper need to animate with transformed position, so its surface position should // not be reset.