diff options
4 files changed, 60 insertions, 65 deletions
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index 5d9c42d4c3a8..7edc3a2b9786 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -691,12 +691,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { recordDisplay(wc.getDisplayContent()); if (info.mShowWallpaper) { // Collect the wallpaper token (for isWallpaper(wc)) so it is part of the sync set. - final List<WindowState> wallpapers = - wc.getDisplayContent().mWallpaperController.getAllTopWallpapers(); - for (int i = wallpapers.size() - 1; i >= 0; i--) { - WindowState wallpaper = wallpapers.get(i); - collect(wallpaper.mToken); - } + wc.mDisplayContent.mWallpaperController.collectTopWallpapers(this); } } diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java index 6949a874b533..001f46d4c36c 100644 --- a/services/core/java/com/android/server/wm/WallpaperController.java +++ b/services/core/java/com/android/server/wm/WallpaperController.java @@ -23,7 +23,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; -import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WALLPAPER; @@ -55,7 +54,6 @@ import android.view.Display; import android.view.DisplayInfo; import android.view.SurfaceControl; import android.view.WindowManager; -import android.view.animation.Animation; import android.window.ScreenCapture; import com.android.internal.R; @@ -80,6 +78,7 @@ class WallpaperController { private WallpaperCropUtils mWallpaperCropUtils = null; private DisplayContent mDisplayContent; + // Larger index has higher z-order. private final ArrayList<WallpaperWindowToken> mWallpaperTokens = new ArrayList<>(); // If non-null, this is the currently visible window that is associated @@ -126,18 +125,6 @@ class WallpaperController { */ private volatile boolean mIsWallpaperNotifiedOnDisplaySwitch; - private final Consumer<WindowState> mFindWallpapers = w -> { - if (w.mAttrs.type == TYPE_WALLPAPER) { - WallpaperWindowToken token = w.mToken.asWallpaperToken(); - if (token.canShowWhenLocked() && !mFindResults.hasTopShowWhenLockedWallpaper()) { - mFindResults.setTopShowWhenLockedWallpaper(w); - } else if (!token.canShowWhenLocked() - && !mFindResults.hasTopHideWhenLockedWallpaper()) { - mFindResults.setTopHideWhenLockedWallpaper(w); - } - } - }; - private final ToBooleanFunction<WindowState> mFindWallpaperTargetFunction = w -> { final boolean useShellTransition = w.mTransitionController.isShellTransitionsEnabled(); if (!useShellTransition) { @@ -321,16 +308,6 @@ class WallpaperController { return false; } - /** - * Starts {@param a} on all wallpaper windows. - */ - void startWallpaperAnimation(Animation a) { - for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) { - final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx); - token.startAnimation(a); - } - } - boolean isWallpaperTargetAnimating() { return mWallpaperTarget != null && mWallpaperTarget.isAnimating(TRANSITION | PARENTS) && (mWallpaperTarget.mActivityRecord == null @@ -621,7 +598,8 @@ class WallpaperController { if (Float.compare(window.mWallpaperZoomOut, zoom) != 0) { window.mWallpaperZoomOut = zoom; computeLastWallpaperZoomOut(); - for (WallpaperWindowToken token : mWallpaperTokens) { + for (int i = mWallpaperTokens.size() - 1; i >= 0; i--) { + final WallpaperWindowToken token = mWallpaperTokens.get(i); token.updateWallpaperOffset(false); } } @@ -744,7 +722,7 @@ class WallpaperController { mFindResults.setUseTopWallpaperAsTarget(true); } - mDisplayContent.forAllWindows(mFindWallpapers, true /* traverseTopToBottom */); + findWallpapers(); mDisplayContent.forAllWindows(mFindWallpaperTargetFunction, true /* traverseTopToBottom */); if (mFindResults.mNeedsShowWhenLockedWallpaper) { // Keep wallpaper visible if the show-when-locked activities doesn't fill screen. @@ -757,15 +735,29 @@ class WallpaperController { } } - List<WindowState> getAllTopWallpapers() { - ArrayList<WindowState> wallpapers = new ArrayList<>(2); + private void findWallpapers() { + for (int i = mWallpaperTokens.size() - 1; i >= 0; i--) { + final WallpaperWindowToken token = mWallpaperTokens.get(i); + final boolean canShowWhenLocked = token.canShowWhenLocked(); + for (int j = token.getChildCount() - 1; j >= 0; j--) { + final WindowState w = token.getChildAt(j); + if (!w.mIsWallpaper) continue; + if (canShowWhenLocked && !mFindResults.hasTopShowWhenLockedWallpaper()) { + mFindResults.setTopShowWhenLockedWallpaper(w); + } else if (!canShowWhenLocked && !mFindResults.hasTopHideWhenLockedWallpaper()) { + mFindResults.setTopHideWhenLockedWallpaper(w); + } + } + } + } + + void collectTopWallpapers(Transition transition) { if (mFindResults.hasTopShowWhenLockedWallpaper()) { - wallpapers.add(mFindResults.mTopWallpaper.mTopShowWhenLockedWallpaper); + transition.collect(mFindResults.mTopWallpaper.mTopShowWhenLockedWallpaper); } if (mFindResults.hasTopHideWhenLockedWallpaper()) { - wallpapers.add(mFindResults.mTopWallpaper.mTopHideWhenLockedWallpaper); + transition.collect(mFindResults.mTopWallpaper.mTopHideWhenLockedWallpaper); } - return wallpapers; } private boolean isFullscreen(WindowManager.LayoutParams attrs) { @@ -1016,6 +1008,12 @@ class WallpaperController { mWallpaperTokens.remove(token); } + void onWallpaperTokenReordered() { + if (mWallpaperTokens.size() > 1) { + mWallpaperTokens.sort(null /* by WindowContainer#compareTo */); + } + } + @VisibleForTesting boolean canScreenshotWallpaper() { return canScreenshotWallpaper(getTopVisibleWallpaper()); @@ -1160,7 +1158,8 @@ class WallpaperController { pw.print(prefix); pw.print("mPrevWallpaperTarget="); pw.println(mPrevWallpaperTarget); } - for (WallpaperWindowToken t : mWallpaperTokens) { + for (int i = mWallpaperTokens.size() - 1; i >= 0; i--) { + final WallpaperWindowToken t = mWallpaperTokens.get(i); pw.print(prefix); pw.println("token " + t + ":"); pw.print(prefix); pw.print(" canShowWhenLocked="); pw.println(t.canShowWhenLocked()); dumpValue(pw, prefix, "mWallpaperX", t.mWallpaperX); diff --git a/services/core/java/com/android/server/wm/WallpaperWindowToken.java b/services/core/java/com/android/server/wm/WallpaperWindowToken.java index 1bcd882b5d64..dc500a2748cf 100644 --- a/services/core/java/com/android/server/wm/WallpaperWindowToken.java +++ b/services/core/java/com/android/server/wm/WallpaperWindowToken.java @@ -30,7 +30,6 @@ import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.util.SparseArray; -import android.view.animation.Animation; import com.android.internal.protolog.common.ProtoLog; @@ -90,16 +89,14 @@ class WallpaperWindowToken extends WindowToken { return; } mShowWhenLocked = showWhenLocked; - // Move the window token to the front (private) or back (showWhenLocked). This is - // possible - // because the DisplayArea underneath TaskDisplayArea only contains TYPE_WALLPAPER - // windows. + // Move the window token to the front (private) or back (showWhenLocked). This is possible + // because the DisplayArea underneath TaskDisplayArea only contains TYPE_WALLPAPER windows. final int position = showWhenLocked ? POSITION_BOTTOM : POSITION_TOP; - // Note: Moving all the way to the front or back breaks ordering based on addition - // times. - // We should never have more than one non-animating token of each type. + // Note: Moving all the way to the front or back breaks ordering based on addition times. + // There should never have more than one non-animating token of each type. getParent().positionChildAt(position, this /* child */, false /*includingParents */); + mDisplayContent.mWallpaperController.onWallpaperTokenReordered(); } boolean canShowWhenLocked() { @@ -139,16 +136,6 @@ class WallpaperWindowToken extends WindowToken { } } - /** - * Starts {@param anim} on all children. - */ - void startAnimation(Animation anim) { - for (int ndx = mChildren.size() - 1; ndx >= 0; ndx--) { - final WindowState windowState = mChildren.get(ndx); - windowState.startAnimation(anim); - } - } - void updateWallpaperWindows(boolean visible) { if (mVisibleRequested != visible) { ProtoLog.d(WM_DEBUG_WALLPAPER, "Wallpaper token %s visible=%b", 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 73d386a328f5..80fb44a9b50f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java @@ -88,8 +88,6 @@ public class WallpaperControllerTests extends WindowTestsBase { @Test public void testWallpaperScreenshot() { - WindowSurfaceController windowSurfaceController = mock(WindowSurfaceController.class); - // No wallpaper final DisplayContent dc = createNewDisplay(); assertFalse(dc.mWallpaperController.canScreenshotWallpaper()); @@ -99,11 +97,9 @@ public class WallpaperControllerTests extends WindowTestsBase { assertFalse(dc.mWallpaperController.canScreenshotWallpaper()); // Wallpaper with not visible WSA surface. - wallpaperWindow.mWinAnimator.mSurfaceController = windowSurfaceController; - wallpaperWindow.mWinAnimator.mLastAlpha = 1; assertFalse(dc.mWallpaperController.canScreenshotWallpaper()); - when(windowSurfaceController.getShown()).thenReturn(true); + makeWallpaperWindowShown(wallpaperWindow); // Wallpaper with WSA alpha set to 0. wallpaperWindow.mWinAnimator.mLastAlpha = 0; @@ -306,14 +302,25 @@ public class WallpaperControllerTests extends WindowTestsBase { spyOn(mWm.mPolicy); doReturn(true).when(mWm.mPolicy).isKeyguardLocked(); doReturn(true).when(mWm.mPolicy).isKeyguardOccluded(); - mDisplayContent.mWallpaperController.adjustWallpaperWindows(); + final WallpaperController wallpaperController = mDisplayContent.mWallpaperController; + wallpaperController.adjustWallpaperWindows(); // Wallpaper is visible because the show-when-locked activity is translucent. - assertTrue(mDisplayContent.mWallpaperController.isWallpaperTarget(wallpaperWindow)); + assertTrue(wallpaperController.isWallpaperTarget(wallpaperWindow)); behind.mActivityRecord.setShowWhenLocked(true); - mDisplayContent.mWallpaperController.adjustWallpaperWindows(); + wallpaperController.adjustWallpaperWindows(); // Wallpaper is invisible because the lowest show-when-locked activity is opaque. - assertTrue(mDisplayContent.mWallpaperController.isWallpaperTarget(null)); + assertTrue(wallpaperController.isWallpaperTarget(null)); + + // A show-when-locked wallpaper is used for lockscreen. So the top wallpaper should + // be the one that is not show-when-locked. + final WindowState wallpaperWindow2 = createWallpaperWindow(mDisplayContent); + makeWallpaperWindowShown(wallpaperWindow2); + makeWallpaperWindowShown(wallpaperWindow); + assertEquals(wallpaperWindow2, wallpaperController.getTopVisibleWallpaper()); + wallpaperWindow2.mToken.asWallpaperToken().setShowWhenLocked(true); + wallpaperWindow.mToken.asWallpaperToken().setShowWhenLocked(false); + assertEquals(wallpaperWindow, wallpaperController.getTopVisibleWallpaper()); } /** @@ -527,6 +534,13 @@ public class WallpaperControllerTests extends WindowTestsBase { assertThat(wallpaperWindow.mYOffset).isEqualTo(0); } + private static void makeWallpaperWindowShown(WindowState w) { + final WindowSurfaceController windowSurfaceController = mock(WindowSurfaceController.class); + w.mWinAnimator.mSurfaceController = windowSurfaceController; + w.mWinAnimator.mLastAlpha = 1; + when(windowSurfaceController.getShown()).thenReturn(true); + } + private WindowState createWallpaperWindow(DisplayContent dc, int width, int height) { final WindowState wallpaperWindow = createWallpaperWindow(dc); // Wallpaper is cropped to match first display. |