Remove starting window whenever the acitvity is stopped

The main app window will never finish drawing at this point so there
is nothing to trigger the removal of the starting window.

Also, set ActivityRecord.mStartingWindowShown to true for some cases
where we were telling WM to show starting window but not setting the
flag that would later be used for clean-up.

Bug: 26659857
Change-Id: I7a8582521853f1f95b77d8b08f4dd0cf778f8cbf
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 90a7da9..32ca5bf 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -321,6 +321,7 @@
                 pw.print(" visible="); pw.print(visible);
                 pw.print(" sleeping="); pw.print(sleeping);
                 pw.print(" idle="); pw.println(idle);
+                pw.print(" mStartingWindowShown="); pw.println(mStartingWindowShown);
         pw.print(prefix); pw.print("fullscreen="); pw.print(fullscreen);
                 pw.print(" noDisplay="); pw.print(noDisplay);
                 pw.print(" immersive="); pw.print(immersive);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index acde10f..ec37667 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -2263,6 +2263,7 @@
                             mService.compatibilityInfoForPackageLocked(next.info.applicationInfo),
                             next.nonLocalizedLabel, next.labelRes, next.icon, next.logo,
                             next.windowFlags, null, true);
+                    next.mStartingWindowShown = true;
                 }
                 mStackSupervisor.startSpecificActivityLocked(next, true, false);
                 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
@@ -2295,6 +2296,7 @@
                             next.nonLocalizedLabel,
                             next.labelRes, next.icon, next.logo, next.windowFlags,
                             null, true);
+                    next.mStartingWindowShown = true;
                 }
                 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
             }
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 12c62bd..f9e258d 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -21,6 +21,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -159,6 +160,25 @@
         }
     }
 
+    void onFirstWindowDrawn(WindowState win, WindowStateAnimator winAnimator) {
+        firstWindowDrawn = true;
+
+        // We now have a good window to show, remove dead placeholders
+        removeAllDeadWindows();
+
+        if (startingData != null) {
+            if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG, "Finish starting "
+                    + win.mToken + ": first real window is shown, no animation");
+            // If this initial window is animating, stop it -- we will do an animation to reveal
+            // it from behind the starting window, so there is no need for it to also be doing its
+            // own stuff.
+            winAnimator.clearAnimation();
+            winAnimator.mService.mFinishedStarting.add(this);
+            winAnimator.mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
+        }
+        updateReportedVisibilityLocked();
+    }
+
     void updateReportedVisibilityLocked() {
         if (appToken == null) {
             return;
@@ -357,6 +377,9 @@
     void notifyAppStopped() {
         mAppStopped = true;
         destroySurfaces();
+
+        // Remove any starting window that was added for this app if they are still around.
+        mTask.mService.scheduleRemoveStartingWindowLocked(this);
     }
 
     /**
@@ -594,6 +617,9 @@
         if (paused) {
             pw.print(prefix); pw.print("paused="); pw.println(paused);
         }
+        if (mAppStopped) {
+            pw.print(prefix); pw.print("mAppStopped="); pw.println(mAppStopped);
+        }
         if (numInterestingWindows != 0 || numDrawnWindows != 0
                 || allDrawn || mAppAnimator.allDrawn) {
             pw.print(prefix); pw.print("numInterestingWindows=");
@@ -619,7 +645,7 @@
             pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
                     pw.print(" startingView="); pw.print(startingView);
                     pw.print(" startingDisplayed="); pw.print(startingDisplayed);
-                    pw.print(" startingMoved"); pw.println(startingMoved);
+                    pw.print(" startingMoved="); pw.println(startingMoved);
         }
         if (!mFrozenBounds.isEmpty()) {
             pw.print(prefix); pw.print("mFrozenBounds="); pw.print(mFrozenBounds);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 44ed7e2..40b6b50 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2347,7 +2347,8 @@
         pw.print(prefix); pw.print("mHasSurface="); pw.print(mHasSurface);
                 pw.print(" mShownPosition="); mShownPosition.printShortString(pw);
                 pw.print(" isReadyForDisplay()="); pw.print(isReadyForDisplay());
-                pw.print(" hasSavedSurface()="); pw.println(hasSavedSurface());
+                pw.print(" hasSavedSurface()="); pw.print(hasSavedSurface());
+                pw.print(" mWindowRemovalAllowed="); pw.println(mWindowRemovalAllowed);
         if (dumpAll) {
             pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
                     pw.print(" last="); mLastFrame.printShortString(pw);
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 2d8a4c9..c623047 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1522,23 +1522,7 @@
             }
 
             if (mWin.mAttrs.type != TYPE_APPLICATION_STARTING && mWin.mAppToken != null) {
-                mWin.mAppToken.firstWindowDrawn = true;
-
-                // We now have a good window to show, remove dead placeholders
-                mWin.mAppToken.removeAllDeadWindows();
-
-                if (mWin.mAppToken.startingData != null) {
-                    if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG, "Finish starting "
-                            + mWin.mToken + ": first real window is shown, no animation");
-                    // If this initial window is animating, stop it -- we
-                    // will do an animation to reveal it from behind the
-                    // starting window, so there is no need for it to also
-                    // be doing its own stuff.
-                    clearAnimation();
-                    mService.mFinishedStarting.add(mWin.mAppToken);
-                    mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
-                }
-                mWin.mAppToken.updateReportedVisibilityLocked();
+                mWin.mAppToken.onFirstWindowDrawn(mWin, this);
             }
 
             return true;