Defer detach until animations are complete.

Allowing the detach of ActivityStack from DisplayContent to happen
immediately was causing all sorts of problems associated with not
having a Display to complete the animations.

Waiting for animations to complete before either the detach or the
display removal fixes those problems.

Change-Id: I8a5663bfac5c3c1084ff4fcc451e0e38e8080265
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index ce493d4..0941c76 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -137,6 +137,21 @@
         return mBounds.isEmpty();
     }
 
+    boolean isAnimating() {
+        for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
+            final ArrayList<AppWindowToken> activities = mTasks.get(taskNdx).mAppTokens;
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
+                for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+                    if (windows.get(winNdx).mWinAnimator.isAnimating()) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
     void resizeBounds(float oldWidth, float oldHeight, float newWidth, float newHeight) {
         if (oldWidth == newWidth && oldHeight == newHeight) {
             return;
@@ -351,6 +366,19 @@
         mAnimationBackgroundSurface.mDimSurface.destroy();
     }
 
+    void checkForDeferredDetach() {
+        if (mDisplayContent != null &&
+                (mDisplayContent.mDeferredActions & DisplayContent.DEFER_DETACH) != 0 &&
+                !isAnimating()) {
+            mDisplayContent.mDeferredActions &= ~DisplayContent.DEFER_DETACH;
+            mService.detachStack(mStackId);
+            if ((mDisplayContent.mDeferredActions & DisplayContent.DEFER_REMOVAL) != 0) {
+                mDisplayContent.mDeferredActions &= ~DisplayContent.DEFER_REMOVAL;
+                mService.onDisplayRemoved(mDisplayContent.getDisplayId());
+            }
+        }
+    }
+
     public void dump(String prefix, PrintWriter pw) {
         pw.print(prefix); pw.print("mStackId="); pw.println(mStackId);
         for (int taskNdx = 0; taskNdx < mTasks.size(); ++taskNdx) {