Fix wallpaper transition cts test failures

Adjust wallpaper windows if an opening app has a window that can be a
wallpaper target so that the right transition animation can be played.
We previously relied on the chance that a previous layout pass might
have set the target wallpaper correctly.

Bug: 31626368
Test: run-test android.server.cts.ActivityManagerTransitionSelectionTests
Change-Id: Idf5e516f4464944b7a31a55d206f05ca3d4ef407
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 58439eb..962325f 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -18,14 +18,10 @@
 
 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
-import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
+import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -39,6 +35,7 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.util.ArraySet;
 import android.util.Slog;
 import android.view.DisplayInfo;
 import android.view.WindowManager;
@@ -384,18 +381,6 @@
         return mWallpaperAnimLayerAdjustment;
     }
 
-    void setAnimLayerAdjustment(WindowState win, int adj) {
-        if (win != mWallpaperTarget || mLowerWallpaperTarget != null) {
-            return;
-        }
-
-        if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Setting wallpaper layer adj to " + adj);
-        mWallpaperAnimLayerAdjustment = adj;
-        for (int i = mWallpaperTokens.size() - 1; i >= 0; i--) {
-            mWallpaperTokens.get(i).adjustAnimLayer(adj);
-        }
-    }
-
     private void findWallpaperTarget(WindowList windows, FindWallpaperTargetResult result) {
         final WindowAnimator winAnimator = mService.mAnimator;
         result.reset();
@@ -477,101 +462,111 @@
         }
     }
 
+    /** Updates the target wallpaper if needed and returns true if an update happened. */
     private boolean updateWallpaperWindowsTarget(
             WindowList windows, FindWallpaperTargetResult result) {
 
-        boolean targetChanged = false;
         WindowState wallpaperTarget = result.wallpaperTarget;
         int wallpaperTargetIndex = result.wallpaperTargetIndex;
 
-        if (mWallpaperTarget != wallpaperTarget
-                && (mLowerWallpaperTarget == null || mLowerWallpaperTarget != wallpaperTarget)) {
-            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
-                    "New wallpaper target: " + wallpaperTarget + " oldTarget: " + mWallpaperTarget);
+        if (mWallpaperTarget == wallpaperTarget
+                || (mLowerWallpaperTarget != null && mLowerWallpaperTarget == wallpaperTarget)) {
 
-            mLowerWallpaperTarget = null;
-            mUpperWallpaperTarget = null;
-
-            WindowState oldW = mWallpaperTarget;
-            mWallpaperTarget = wallpaperTarget;
-            targetChanged = true;
-
-            // Now what is happening...  if the current and new targets are animating,
-            // then we are in our super special mode!
-            if (wallpaperTarget != null && oldW != null) {
-                boolean oldAnim = oldW.isAnimatingLw();
-                boolean foundAnim = wallpaperTarget.isAnimatingLw();
-                if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
-                        "New animation: " + foundAnim + " old animation: " + oldAnim);
-                if (foundAnim && oldAnim) {
-                    int oldI = windows.indexOf(oldW);
+            if (mLowerWallpaperTarget != null) {
+                // Is it time to stop animating?
+                if (!mLowerWallpaperTarget.isAnimatingLw()
+                        || !mUpperWallpaperTarget.isAnimatingLw()) {
                     if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
-                            "New i: " + wallpaperTargetIndex + " old i: " + oldI);
-                    if (oldI >= 0) {
-                        final boolean newTargetHidden =
-                                wallpaperTarget.mAppToken != null && wallpaperTarget.mAppToken.hiddenRequested;
-                        final boolean oldTargetHidden =
-                                oldW.mAppToken != null && oldW.mAppToken.hiddenRequested;
-                        if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Animating wallpapers:"
-                                + " old#" + oldI + "=" + oldW + " hidden=" + oldTargetHidden
-                                + " new#" + wallpaperTargetIndex + "=" + wallpaperTarget
-                                + " hidden=" + newTargetHidden);
-
-                        // Set the upper and lower wallpaper targets correctly,
-                        // and make sure that we are positioning the wallpaper below the lower.
-                        if (wallpaperTargetIndex > oldI) {
-                            // The new target is on top of the old one.
-                            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
-                                    "Found target above old target.");
-                            mUpperWallpaperTarget = wallpaperTarget;
-                            mLowerWallpaperTarget = oldW;
-
-                            wallpaperTarget = oldW;
-                            wallpaperTargetIndex = oldI;
-                        } else {
-                            // The new target is below the old one.
-                            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
-                                    "Found target below old target.");
-                            mUpperWallpaperTarget = oldW;
-                            mLowerWallpaperTarget = wallpaperTarget;
-                        }
-                        if (newTargetHidden && !oldTargetHidden) {
-                            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
-                                    "Old wallpaper still the target.");
-                            // Use the old target if new target is hidden but old target
-                            // is not. If they're both hidden, still use the new target.
-                            mWallpaperTarget = oldW;
-                        } else if (newTargetHidden == oldTargetHidden
-                                && !mService.mOpeningApps.contains(wallpaperTarget.mAppToken)
-                                    && (mService.mOpeningApps.contains(oldW.mAppToken)
-                                    || mService.mClosingApps.contains(oldW.mAppToken))) {
-                            // If they're both hidden (or both not hidden), prefer the one that's
-                            // currently in opening or closing app list, this allows transition
-                            // selection logic to better determine the wallpaper status of
-                            // opening/closing apps.
-                            mWallpaperTarget = oldW;
-                        }
-                    }
+                            "No longer animating wallpaper targets!");
+                    mLowerWallpaperTarget = null;
+                    mUpperWallpaperTarget = null;
+                    mWallpaperTarget = wallpaperTarget;
+                    return true;
                 }
             }
 
-        } else if (mLowerWallpaperTarget != null) {
-            // Is it time to stop animating?
-            if (!mLowerWallpaperTarget.isAnimatingLw() || !mUpperWallpaperTarget.isAnimatingLw()) {
-                if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "No longer animating wallpaper targets!");
-                mLowerWallpaperTarget = null;
-                mUpperWallpaperTarget = null;
-                mWallpaperTarget = wallpaperTarget;
-                targetChanged = true;
-            }
+            return false;
+        }
+
+        if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+                "New wallpaper target: " + wallpaperTarget + " oldTarget: " + mWallpaperTarget);
+
+        mLowerWallpaperTarget = null;
+        mUpperWallpaperTarget = null;
+
+        WindowState oldW = mWallpaperTarget;
+        mWallpaperTarget = wallpaperTarget;
+
+        if (wallpaperTarget == null || oldW == null) {
+            return true;
+        }
+
+        // Now what is happening...  if the current and new targets are animating,
+        // then we are in our super special mode!
+        boolean oldAnim = oldW.isAnimatingLw();
+        boolean foundAnim = wallpaperTarget.isAnimatingLw();
+        if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+                "New animation: " + foundAnim + " old animation: " + oldAnim);
+
+        if (!foundAnim || !oldAnim) {
+            return true;
+        }
+
+        int oldI = windows.indexOf(oldW);
+        if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+                "New i: " + wallpaperTargetIndex + " old i: " + oldI);
+
+        if (oldI < 0) {
+            return true;
+        }
+
+        final boolean newTargetHidden = wallpaperTarget.mAppToken != null
+                && wallpaperTarget.mAppToken.hiddenRequested;
+        final boolean oldTargetHidden = oldW.mAppToken != null
+                && oldW.mAppToken.hiddenRequested;
+
+        if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Animating wallpapers:" + " old#" + oldI + "="
+                + oldW + " hidden=" + oldTargetHidden + " new#" + wallpaperTargetIndex + "="
+                + wallpaperTarget + " hidden=" + newTargetHidden);
+
+        // Set the upper and lower wallpaper targets correctly,
+        // and make sure that we are positioning the wallpaper below the lower.
+        if (wallpaperTargetIndex > oldI) {
+            // The new target is on top of the old one.
+            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Found target above old target.");
+            mUpperWallpaperTarget = wallpaperTarget;
+            mLowerWallpaperTarget = oldW;
+
+            wallpaperTarget = oldW;
+            wallpaperTargetIndex = oldI;
+        } else {
+            // The new target is below the old one.
+            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Found target below old target.");
+            mUpperWallpaperTarget = oldW;
+            mLowerWallpaperTarget = wallpaperTarget;
+        }
+
+        if (newTargetHidden && !oldTargetHidden) {
+            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Old wallpaper still the target.");
+            // Use the old target if new target is hidden but old target
+            // is not. If they're both hidden, still use the new target.
+            mWallpaperTarget = oldW;
+        } else if (newTargetHidden == oldTargetHidden
+                && !mService.mOpeningApps.contains(wallpaperTarget.mAppToken)
+                && (mService.mOpeningApps.contains(oldW.mAppToken)
+                || mService.mClosingApps.contains(oldW.mAppToken))) {
+            // If they're both hidden (or both not hidden), prefer the one that's currently in
+            // opening or closing app list, this allows transition selection logic to better
+            // determine the wallpaper status of opening/closing apps.
+            mWallpaperTarget = oldW;
         }
 
         result.setWallpaperTarget(wallpaperTarget, wallpaperTargetIndex);
-        return targetChanged;
+        return true;
     }
 
-    boolean updateWallpaperWindowsTargetByLayer(
-            WindowList windows, FindWallpaperTargetResult result) {
+    private boolean updateWallpaperWindowsTargetByLayer(WindowList windows,
+            FindWallpaperTargetResult result) {
 
         WindowState wallpaperTarget = result.wallpaperTarget;
         int wallpaperTargetIndex = result.wallpaperTargetIndex;
@@ -621,7 +616,7 @@
         return visible;
     }
 
-    boolean updateWallpaperWindowsPlacement(WindowList windows,
+    private boolean updateWallpaperWindowsPlacement(WindowList windows,
             WindowState wallpaperTarget, int wallpaperTargetIndex, boolean visible) {
 
         // TODO(multidisplay): Wallpapers on main screen only.
@@ -734,6 +729,31 @@
         return transitionReady;
     }
 
+    /**
+     * Adjusts the wallpaper windows if the input display has a pending wallpaper layout or one of
+     * the opening apps should be a wallpaper target.
+     */
+    void adjustWallpaperWindowsForAppTransitionIfNeeded(
+            DisplayContent dc, ArraySet<AppWindowToken> openingApps, WindowList windows) {
+        boolean adjust = false;
+        if ((dc.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
+            adjust = true;
+        } else {
+            for (int i = openingApps.size() - 1; i >= 0; --i) {
+                final AppWindowToken token = openingApps.valueAt(i);
+                if (token.windowsCanBeWallpaperTarget()) {
+                    adjust = true;
+                    break;
+                }
+            }
+        }
+
+        if (adjust && adjustWallpaperWindows()) {
+            mService.mLayersController.assignLayersLocked(windows);
+            dc.setLayoutNeeded();
+        }
+    }
+
     void addWallpaperToken(WindowToken token) {
         mWallpaperTokens.add(token);
     }