Detach children when stopping app.

Prior to the implementation of detachChildren we handled this
case via the "mWindowStopped" codepath in SurfaceView.java which this
CL deletes. That codepath however causes confusion due to it's failure
to set null the SurfaceControl, meaning we may not necessarily
recreate it when resuming if we didn't hit any other code-path
to do such as happens in linked bug 78588930. Anyway it seems clearest
to handle all these preserve-child-surfaces-on-tear-down cases via
one mechanism (detachChildren).

Bug: 78588930
Test: Manual.
Change-Id: Iac7c0bc0c6b4da0d405bdc2b57d13d5c881611b0
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 16c5969..e73f42f 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -1626,6 +1626,10 @@
         if (parent != null) {
             parent.onActivityStateChanged(this, state, reason);
         }
+
+        if (state == STOPPING) {
+            mWindowContainerController.notifyAppStopping();
+        }
     }
 
     ActivityState getState() {
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index 165a409..644e3c3 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -671,6 +671,17 @@
         }
     }
 
+    public void notifyAppStopping() {
+        synchronized(mWindowMap) {
+            if (mContainer == null) {
+                Slog.w(TAG_WM, "Attempted to notify stopping on non-existing app token: "
+                        + mToken);
+                return;
+            }
+            mContainer.detachChildren();
+        }
+    }
+
     public void notifyAppStopped() {
         synchronized(mWindowMap) {
             if (mContainer == null) {
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index a701d42..1d581d4 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -913,12 +913,16 @@
         // try and clean up it's child surfaces. We need to prevent this from
         // happening, so we sever the children, transfering their ownership
         // from the client it-self to the parent surface (owned by us).
+        detachChildren();
+
+        mPendingRelaunchCount++;
+    }
+
+    void detachChildren() {
         for (int i = mChildren.size() - 1; i >= 0; i--) {
             final WindowState w = mChildren.get(i);
             w.mWinAnimator.detachChildren();
         }
-
-        mPendingRelaunchCount++;
     }
 
     void finishRelaunching() {