Allow DisplayContent children to be removed on display removal

DisplayContent has direct children that we treat as permanent and as
such we don't allow them to be removed. However, this causes an issue
when removing the display as all children of the display are expected
to be removed at that point.
We now allow the removal of the chilren when the display is being removed
and still disallow it in all other cases.

Bug: 32193212
Test: cts-tradefed run commandAndExit cts-dev -m CtsDisplayTestCases
Change-Id: I9a2eeb2418311a9c5931797ab7a831deead3781e
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index fa3112d..65f2906 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -165,6 +165,10 @@
     private final GetWindowOnDisplaySearchResult mTmpGetWindowOnDisplaySearchResult =
             new GetWindowOnDisplaySearchResult();
 
+    // True if this display is in the process of being removed. Used to determine if the removal of
+    // the display's direct children should be allowed.
+    private boolean mRemovingDisplay = false;
+
     /**
      * @param display May not be null.
      * @param service You know.
@@ -433,6 +437,12 @@
 
     @Override
     protected void removeChild(DisplayChildWindowContainer child) {
+        // Only allow removal of direct children from this display if the display is in the process
+        // of been removed.
+        if (mRemovingDisplay) {
+            super.removeChild(child);
+            return;
+        }
         throw new UnsupportedOperationException("See DisplayChildWindowContainer");
     }
 
@@ -565,12 +575,17 @@
 
     @Override
     void removeImmediately() {
-        super.removeImmediately();
-        if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Removing display=" + this);
-        mDimLayerController.close();
-        if (mDisplayId == DEFAULT_DISPLAY) {
-            mService.unregisterPointerEventListener(mTapDetector);
-            mService.unregisterPointerEventListener(mService.mMousePositionTracker);
+        mRemovingDisplay = true;
+        try {
+            super.removeImmediately();
+            if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Removing display=" + this);
+            mDimLayerController.close();
+            if (mDisplayId == DEFAULT_DISPLAY) {
+                mService.unregisterPointerEventListener(mTapDetector);
+                mService.unregisterPointerEventListener(mService.mMousePositionTracker);
+            }
+        } finally {
+            mRemovingDisplay = false;
         }
     }