Do not clear AppWindowToken.allDrawn while animating.

Creating new surfaces for applications clears the allDrawn flag in the
AppWindowToken. If the app windows were animating when this happened
the animation would complete immediately resulting in jank. This fix
defers clearing allDrawn until the animation completes.

Bug 7326635 fixed.

Change-Id: I5abe3b9ecfbefb476de6a6c8acc394373cc11751
diff --git a/services/java/com/android/server/wm/AppWindowAnimator.java b/services/java/com/android/server/wm/AppWindowAnimator.java
index ca94d04..e044c6d 100644
--- a/services/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/java/com/android/server/wm/AppWindowAnimator.java
@@ -100,6 +100,10 @@
             animInitialized = false;
         }
         clearThumbnail();
+        if (mAppToken.deferClearAllDrawn) {
+            mAppToken.allDrawn = false;
+            mAppToken.deferClearAllDrawn = false;
+        }
     }
 
     public void clearThumbnail() {
diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java
index 7efffe5..3ec6d26 100644
--- a/services/java/com/android/server/wm/AppWindowToken.java
+++ b/services/java/com/android/server/wm/AppWindowToken.java
@@ -64,6 +64,9 @@
     int numDrawnWindows;
     boolean inPendingTransaction;
     boolean allDrawn;
+    // Set to true when this app creates a surface while in the middle of an animation. In that
+    // case do not clear allDrawn until the animation completes.
+    boolean deferClearAllDrawn;
 
     // Is this token going to be hidden in a little while?  If so, it
     // won't be taken into account for setting the screen orientation.
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 5adc082..921147d 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -4295,6 +4295,7 @@
                         // the new one.
                         if (ttoken.allDrawn) {
                             wtoken.allDrawn = true;
+                            wtoken.deferClearAllDrawn = ttoken.deferClearAllDrawn;
                         }
                         if (ttoken.firstWindowDrawn) {
                             wtoken.firstWindowDrawn = true;
@@ -4602,6 +4603,7 @@
                     // its windows to be ready.
                     if (wtoken.hidden) {
                         wtoken.allDrawn = false;
+                        wtoken.deferClearAllDrawn = false;
                         wtoken.waitingToShow = true;
 
                         if (wtoken.clientHidden) {
@@ -8708,6 +8710,7 @@
                 // this guy's animations regardless of whether it's
                 // gotten drawn.
                 wtoken.allDrawn = true;
+                wtoken.deferClearAllDrawn = false;
             }
 
             if (mNextAppTransitionThumbnail != null && topOpeningApp != null
@@ -8878,6 +8881,7 @@
                     winAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
                     if (w.mAppToken != null) {
                         w.mAppToken.allDrawn = false;
+                        w.mAppToken.deferClearAllDrawn = false;
                     }
                 }
                 if (!mResizingWindows.contains(w)) {
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index 7b30c89..4ecc191 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -626,7 +626,14 @@
                     "createSurface " + this + ": mDrawState=DRAW_PENDING");
             mDrawState = DRAW_PENDING;
             if (mWin.mAppToken != null) {
-                mWin.mAppToken.allDrawn = false;
+                if (mWin.mAppToken.mAppAnimator.animation == null) {
+                    mWin.mAppToken.allDrawn = false;
+                    mWin.mAppToken.deferClearAllDrawn = false;
+                } else {
+                    // Currently animating, persist current state of allDrawn until animation
+                    // is complete.
+                    mWin.mAppToken.deferClearAllDrawn = true;
+                }
             }
 
             mService.makeWindowFreezingScreenIfNeededLocked(mWin);