Rip out WindowContainer#isScreenOverlay

Messes up ordering of the windows that should be above
the navigation bar and status bar. It seems better to
achieve the IME layering we need directly.

Bug: 69591927
Test: Manual
Change-Id: I69202bca0b84cec5d9f5176645e31c5bd0af767e
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 409e04b..56e5922 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -181,8 +181,8 @@
     private final TaskStackContainers mTaskStackContainers = new TaskStackContainers();
     // Contains all non-app window containers that should be displayed above the app containers
     // (e.g. Status bar)
-    private final NonAppWindowContainers mAboveAppWindowsContainers =
-            new NonAppWindowContainers("mAboveAppWindowsContainers");
+    private final AboveAppWindowContainers mAboveAppWindowsContainers =
+            new AboveAppWindowContainers("mAboveAppWindowsContainers");
     // Contains all non-app window containers that should be displayed below the app containers
     // (e.g. Wallpaper).
     private final NonAppWindowContainers mBelowAppWindowsContainers =
@@ -356,7 +356,8 @@
     /**
      * We organize all top-level Surfaces in to the following layers.
      * mOverlayLayer contains a few Surfaces which are always on top of others
-     * and omitted from Screen-Magnification ({@link WindowState#isScreenOverlay})
+     * and omitted from Screen-Magnification, for example the strict mode flash or
+     * the magnification overlay itself.
      * {@link #mWindowingLayer} contains everything else.
      */
     private SurfaceControl mOverlayLayer;
@@ -3746,11 +3747,39 @@
         }
     }
 
+    private final class AboveAppWindowContainers extends NonAppWindowContainers {
+        AboveAppWindowContainers(String name) {
+            super(name);
+        }
+
+        void assignChildLayers(SurfaceControl.Transaction t, WindowContainer imeContainer) {
+            boolean needAssignIme = imeContainer != null
+                    && imeContainer.getSurfaceControl() != null;
+            for (int j = 0; j < mChildren.size(); ++j) {
+                final WindowToken wt = mChildren.get(j);
+                wt.assignLayer(t, j);
+                wt.assignChildLayers(t);
+
+                int layer = mService.mPolicy.getWindowLayerFromTypeLw(
+                        wt.windowType, wt.mOwnerCanManageAppTokens);
+                if (needAssignIme && layer >= TYPE_INPUT_METHOD_DIALOG) {
+                    t.setRelativeLayer(imeContainer.getSurfaceControl(),
+                            wt.getSurfaceControl(), -1);
+                    needAssignIme = false;
+                }
+            }
+            if (needAssignIme) {
+                t.setRelativeLayer(imeContainer.getSurfaceControl(),
+                        getSurfaceControl(), Integer.MIN_VALUE);
+            }
+        }
+    }
+
     /**
      * Window container class that contains all containers on this display that are not related to
      * Apps. E.g. status bar.
      */
-    private final class NonAppWindowContainers extends DisplayChildWindowContainer<WindowToken> {
+    private class NonAppWindowContainers extends DisplayChildWindowContainer<WindowToken> {
         /**
          * Compares two child window tokens returns -1 if the first is lesser than the second in
          * terms of z-order and 1 otherwise.
@@ -3848,12 +3877,8 @@
             return b;
         }
 
-        b.setName(child.getName());
-        if (child.isScreenOverlay()) {
-            return b.setParent(mOverlayLayer);
-        } else {
-            return b.setParent(mWindowingLayer);
-        }
+        return b.setName(child.getName())
+                .setParent(mWindowingLayer);
     }
 
     /**
@@ -3891,39 +3916,36 @@
         mAboveAppWindowsContainers.assignLayer(t, 2);
 
         WindowState imeTarget = mService.mInputMethodTarget;
+        boolean needAssignIme = true;
 
-        // A brief summary of IME layer assignment:
+        // In the case where we have an IME target that is not in split-screen
+        // mode IME assignment is easy. We just need the IME to go directly above
+        // the target. This way children of the target will naturally go above the IME
+        // and everyone is happy.
         //
-        // In case we have no IME target but we have an IME we are typically in
-        // a transition state and keeping the IME on top of everything except overlays
-        // seems to work best.
+        // In the case of split-screen windowing mode, we need to elevate the IME above the
+        // docked divider while keeping the app itself below the docked divider, so instead
+        // we use relative layering of the IME targets child windows, and place the
+        // IME in the non-app layer (see {@link AboveAppWindowContainers#assignChildLayers}).
         //
-        // In split-screen windowing mode we can't layer the
-        // IME relative to the IME target because it needs to
-        // go over the docked divider, so instead we place it on top
-        // of everything and use relative layering of windows which need
-        // to go above it (see special logic in WindowState#assignLayer)
-        //
-        // There is a third case, where the IME target has no SurfaceControl, for
-        // example if Layer assignment were triggered due to removal of the
-        // IME target while it was still the IME target.
-        if (imeTarget == null ||
-                imeTarget.inSplitScreenWindowingMode() ||
-                imeTarget.getSurfaceControl() == null) {
-            mImeWindowsContainers.assignLayer(t, 3);
-        } else {
+        // In the case where we have no IME target we assign it where it's base layer would
+        // place it in the AboveAppWindowContainers.
+        if (imeTarget != null && !imeTarget.inSplitScreenWindowingMode()
+                && (imeTarget.getSurfaceControl() != null)) {
             t.setRelativeLayer(mImeWindowsContainers.getSurfaceControl(),
                     imeTarget.getSurfaceControl(),
                     // TODO: We need to use an extra level on the app surface to ensure
                     // this is always above SurfaceView but always below attached window.
                     1);
+            needAssignIme = false;
         }
 
         // Above we have assigned layers to our children, now we ask them to assign
         // layers to their children.
         mBelowAppWindowsContainers.assignChildLayers(t);
         mTaskStackContainers.assignChildLayers(t);
-        mAboveAppWindowsContainers.assignChildLayers(t);
+        mAboveAppWindowsContainers.assignChildLayers(t,
+                needAssignIme == true ? mImeWindowsContainers : null);
         mImeWindowsContainers.assignChildLayers(t);
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 610453e..6467582 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -731,29 +731,8 @@
         final WindowContainer p = getParent();
         // Give the parent a chance to set properties. In hierarchy v1 we rely
         // on this to set full-screen dimensions on all our Surface-less Layers.
-        final SurfaceControl.Builder b = p.makeChildSurface(child);
-        if (child != null && child.isScreenOverlay()) {
-            // If it's a screen overlay it's been promoted in the hierarchy (wrt to the
-            // WindowContainer hierarchy vs the SurfaceControl hierarchy)
-            // and we shouldn't set ourselves as the parent.
-            return b;
-        } else {
-            return b.setParent(mSurfaceControl);
-        }
-    }
-
-    /**
-     * There are various layers which require promotion from the WindowContainer
-     * hierarchy to the Overlay layer described in {@link DisplayContent}. See {@link WindowState}
-     * for the particular usage.
-     *
-     * TODO: Perhaps this should be eliminated, either through modifying
-     * the window container hierarchy or through modifying the way we express these overlay
-     * Surfaces (for example, the Magnification Overlay could be implemented like the Strict-mode
-     * Flash and not actually use a WindowState).
-     */
-    boolean isScreenOverlay() {
-        return false;
+        return p.makeChildSurface(child)
+                .setParent(mSurfaceControl);
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 90e9c23..502fc127 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -58,6 +58,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
@@ -4346,27 +4347,19 @@
     @Override
     boolean shouldMagnify() {
         if (mAttrs.type == TYPE_INPUT_METHOD ||
-                mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
-            return false;
-        } else if (isScreenOverlay()) {
+                mAttrs.type == TYPE_INPUT_METHOD_DIALOG ||
+                mAttrs.type == TYPE_MAGNIFICATION_OVERLAY ||
+                mAttrs.type == TYPE_NAVIGATION_BAR ||
+                // It's tempting to wonder: Have we forgotten the rounded corners overlay?
+                // worry not: it's a fake TYPE_NAVIGATION_BAR_PANEL
+                mAttrs.type == TYPE_NAVIGATION_BAR_PANEL ||
+                mAttrs.type == TYPE_STATUS_BAR) {
             return false;
         }
         return true;
     }
 
     @Override
-    boolean isScreenOverlay() {
-        // It's tempting to wonder: Have we forgotten the rounded corners overlay?
-        // worry not: it's a fake TYPE_NAVIGATION_BAR.
-        if (mAttrs.type == TYPE_MAGNIFICATION_OVERLAY ||
-                mAttrs.type == TYPE_NAVIGATION_BAR ||
-                mAttrs.type == TYPE_STATUS_BAR) {
-            return true;
-        }
-        return false;
-    }
-
-    @Override
     SurfaceSession getSession() {
         if (mSession.mSurfaceSession != null) {
             return mSession.mSurfaceSession;