Unset window destroying state only if its surface is destroyed

Otherwise if mDestroying is unset unexpectedly, the pending
destroing surface of the window will show on screen again.
E.g. from ActivityRecord#notifyAppResumed
  -> ActivityRecord#destroySurfaces
   -> WindowStatedestroySurface(
       cleanupOnResume=true, appStopped=false)

Fix: 377179807
Flag: EXEMPT bugfix
Test: atest WindowStateTests#testDestroySurface
Test: Set the root view of a dialog in an activity to GONE.
      Switch to another activity and switch back before the
      previous activity stopped. The dialog should not appear
      on screen.
Change-Id: I380e87e0df40d5d5dda8ea71d1164cf9259da555
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 079170a..f18f6e9 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -3380,8 +3380,10 @@
             if (cleanupOnResume) {
                 requestUpdateWallpaperIfNeeded();
             }
-            mDestroying = false;
-            destroyedSomething = true;
+            if (!mHasSurface) {
+                mDestroying = false;
+                destroyedSomething = true;
+            }
 
             // Since mDestroying will affect ActivityRecord#allDrawn, we need to perform another
             // traversal in case we are waiting on this window to start the transition.
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 1750a14..b737d35 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -353,6 +353,29 @@
     }
 
     @Test
+    public void testDestroySurface() {
+        final WindowState win = createWindow(null, TYPE_APPLICATION, "win");
+        win.mHasSurface = win.mAnimatingExit = true;
+        win.mWinAnimator.mSurfaceControl = mock(SurfaceControl.class);
+        win.onExitAnimationDone();
+
+        assertFalse("Case 1 destroySurface no-op",
+                win.destroySurface(false /* cleanupOnResume */, false /* appStopped */));
+        assertTrue(win.mHasSurface);
+        assertTrue(win.mDestroying);
+
+        assertFalse("Case 2 destroySurface no-op",
+                win.destroySurface(true /* cleanupOnResume */, false /* appStopped */));
+        assertTrue(win.mHasSurface);
+        assertTrue(win.mDestroying);
+
+        assertTrue("Case 3 destroySurface destroys surface",
+                win.destroySurface(false /* cleanupOnResume */, true /* appStopped */));
+        assertFalse(win.mDestroying);
+        assertFalse(win.mHasSurface);
+    }
+
+    @Test
     public void testPrepareWindowToDisplayDuringRelayout() {
         // Call prepareWindowToDisplayDuringRelayout for a window without FLAG_TURN_SCREEN_ON before
         // calling setCurrentLaunchCanTurnScreenOn for windows with flag in the same activity.