Merge "Don't leak starting window when app crashes before adding windows" into mnc-dev
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index cebb909..5d8979f 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2672,7 +2672,8 @@
     }
 
     void removeWindowLocked(WindowState win) {
-        if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
+        final boolean startingWindow = win.mAttrs.type == TYPE_APPLICATION_STARTING;
+        if (startingWindow) {
             if (DEBUG_STARTING_WINDOW) Slog.d(TAG, "Starting window removed " + win);
         }
 
@@ -2721,7 +2722,13 @@
                     mAccessibilityController.onWindowTransitionLocked(win, transit);
                 }
             }
-            if (win.mExiting || win.mWinAnimator.isAnimating()) {
+            final AppWindowToken appToken = win.mAppToken;
+            // The starting window is the last window in this app token and it isn't animating.
+            // Allow it to be removed now as there is no additional window or animation that will
+            // trigger its removal.
+            final boolean lastWinStartingNotAnimating = startingWindow && appToken!= null
+                    && appToken.allAppWindows.size() == 1 && !win.mWinAnimator.isWindowAnimating();
+            if (!lastWinStartingNotAnimating && (win.mExiting || win.mWinAnimator.isAnimating())) {
                 // The exit animation is running... wait for it!
                 //Slog.i(TAG, "*** Running exit animation...");
                 win.mExiting = true;
@@ -2733,8 +2740,8 @@
                 final boolean focusChanged = updateFocusedWindowLocked(
                         UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
                 performLayoutAndPlaceSurfacesLocked();
-                if (win.mAppToken != null) {
-                    win.mAppToken.updateReportedVisibilityLocked();
+                if (appToken != null) {
+                    appToken.updateReportedVisibilityLocked();
                 }
                 if (focusChanged) {
                     mInputMonitor.updateInputWindowsLw(false /*force*/);
@@ -4648,12 +4655,7 @@
 
             mOpeningApps.remove(wtoken);
             mClosingApps.remove(wtoken);
-            wtoken.waitingToShow = wtoken.waitingToHide = false;
-            wtoken.hiddenRequested = !visible;
-
-            mOpeningApps.remove(wtoken);
-            mClosingApps.remove(wtoken);
-            wtoken.waitingToShow = wtoken.waitingToHide = false;
+            wtoken.waitingToShow = false;
             wtoken.hiddenRequested = !visible;
 
             // If we are preparing an app transition, then delay changing
@@ -4692,12 +4694,6 @@
                 } else {
                     mClosingApps.add(wtoken);
                     wtoken.mEnteringAnimation = false;
-
-                    // If the token is currently visible (should be the
-                    // common case), then set up to wait for it to be hidden.
-                    if (!wtoken.hidden) {
-                        wtoken.waitingToHide = true;
-                    }
                 }
                 if (mAppTransition.getAppTransition() == AppTransition.TRANSIT_TASK_OPEN_BEHIND) {
                     // We're launchingBehind, add the launching activity to mOpeningApps.
@@ -4867,7 +4863,6 @@
                     delayed = true;
                 } else if (mAppTransition.isTransitionSet()) {
                     mClosingApps.add(wtoken);
-                    wtoken.waitingToHide = true;
                     delayed = true;
                 }
                 if (DEBUG_APP_TRANSITIONS) Slog.v(
@@ -9416,7 +9411,6 @@
                 wtoken.inPendingTransaction = false;
                 setTokenVisibilityLocked(wtoken, animLp, false, transit, false, voiceInteraction);
                 wtoken.updateReportedVisibilityLocked();
-                wtoken.waitingToHide = false;
                 // Force the allDrawn flag, because we want to start
                 // this guy's animations regardless of whether it's
                 // gotten drawn.
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index b303505..4ac9135 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -63,10 +63,6 @@
     // will be shown.
     boolean waitingToShow;
 
-    // Set to true when this token is in a pending transaction where it
-    // will be hidden.
-    boolean waitingToHide;
-
     // Set to true when this token is in a pending transaction where its
     // windows will be put to the bottom of the list.
     boolean sendingToBottom;
@@ -93,9 +89,8 @@
         pw.print(prefix); pw.print("windowType="); pw.print(windowType);
                 pw.print(" hidden="); pw.print(hidden);
                 pw.print(" hasVisible="); pw.println(hasVisible);
-        if (waitingToShow || waitingToHide || sendingToBottom) {
+        if (waitingToShow || sendingToBottom) {
             pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
-                    pw.print(" waitingToHide="); pw.print(waitingToHide);
                     pw.print(" sendingToBottom="); pw.print(sendingToBottom);
         }
     }