Put PIP windows above transition animations.

PIP activities are already on top of everything else, but during
animation we increase the layer of the animated window for the duration
of the animation and it may cover the PIP. By forcing the same
adjustment on PIP windows we will keep them above animating windows.

Bug: 26015827
Change-Id: I8f7a87f41fed24b3e520fb599a94cf24cc2eeb50
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 4bbf586..898a9a4 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -237,8 +237,8 @@
     }
 
     void moveStack(TaskStack stack, boolean toTop) {
-        if (stack.mStackId == PINNED_STACK_ID && !toTop) {
-            // Pinned stack is always-on-top silly...
+        if (StackId.isAlwaysOnTop(stack.mStackId) && !toTop) {
+            // This stack is always-on-top silly...
             Slog.w(TAG, "Ignoring move of always-on-top stack=" + stack + " to bottom");
             return;
         }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index f25f1e3..8259fa7 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -58,6 +58,8 @@
 import android.animation.ValueAnimator;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.ActivityManager.StackId;
 import android.app.ActivityManagerNative;
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
@@ -8652,14 +8654,7 @@
             } else if (wtoken != null) {
                 winAnimator.mAnimLayer =
                         w.mLayer + wtoken.mAppAnimator.animLayerAdjustment;
-                if (wtoken.mWillReplaceWindow && wtoken.mReplacingWindow != w
-                        && wtoken.mAnimateReplacingWindow) {
-                    // We know that we will be animating a relaunching window in the near future,
-                    // which will receive a z-order increase. We want the replaced window to
-                    // immediately receive the same treatment, e.g. to be above the dock divider.
-                    w.mLayer += TYPE_LAYER_OFFSET;
-                    winAnimator.mAnimLayer += TYPE_LAYER_OFFSET;
-                }
+                forceHigherLayerIfNeeded(w, winAnimator, wtoken);
             } else {
                 winAnimator.mAnimLayer = w.mLayer;
             }
@@ -8696,6 +8691,30 @@
         }
     }
 
+    private void forceHigherLayerIfNeeded(WindowState w, WindowStateAnimator winAnimator,
+            AppWindowToken wtoken) {
+        boolean force = false;
+        if (wtoken.mWillReplaceWindow && wtoken.mReplacingWindow != w
+                && wtoken.mAnimateReplacingWindow) {
+            // We know that we will be animating a relaunching window in the near future,
+            // which will receive a z-order increase. We want the replaced window to
+            // immediately receive the same treatment, e.g. to be above the dock divider.
+            force = true;
+        }
+        if (!force) {
+            final TaskStack stack = w.getStack();
+            if (stack != null && StackId.isAlwaysOnTop(stack.mStackId)) {
+                // If the window's stack is always on top, we want to make it above other windows
+                // also when these windows are animating.
+                force = true;
+            }
+        }
+        if (force) {
+            w.mLayer += TYPE_LAYER_OFFSET;
+            winAnimator.mAnimLayer += TYPE_LAYER_OFFSET;
+        }
+    }
+
     void makeWindowFreezingScreenIfNeededLocked(WindowState w) {
         // If the screen is currently frozen or off, then keep
         // it frozen/off until this window draws at its new