Final fixes for growing recents transition

- Make sure to reposition windows during animations to avoid that
they lag one frame behind.
- Don't put windows that are gone for layout into resizing mode.
- Don't layout windows that are gone for layout, to avoid resizing
the surface but the client won't draw anymore.

Change-Id: I809feffef00f9a086b44504126e03f509eb7f190
Fixes: 27855229
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index aae52e8..abb1bb1 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -433,7 +433,7 @@
             WindowStateAnimator winAnimator = mAllAppWinAnimators.get(i);
             if (DEBUG_VISIBILITY) Slog.v(TAG, "performing show on: " + winAnimator);
             winAnimator.performShowLocked();
-            isAnimating |= winAnimator.isAnimating();
+            isAnimating |= winAnimator.isAnimationSet();
         }
         return isAnimating;
     }
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 545b9db..9f54b53 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -204,7 +204,7 @@
             if (DEBUG_VISIBILITY) {
                 Slog.v(TAG, "Win " + win + ": isDrawn="
                         + win.isDrawnLw()
-                        + ", isAnimating=" + win.mWinAnimator.isAnimating());
+                        + ", isAnimationSet=" + win.mWinAnimator.isAnimationSet());
                 if (!win.isDrawnLw()) {
                     Slog.v(TAG, "Not displayed: s=" +
                             win.mWinAnimator.mSurfaceController
@@ -220,11 +220,11 @@
             numInteresting++;
             if (win.isDrawnLw()) {
                 numDrawn++;
-                if (!win.mWinAnimator.isAnimating()) {
+                if (!win.mWinAnimator.isAnimationSet()) {
                     numVisible++;
                 }
                 nowGone = false;
-            } else if (win.mWinAnimator.isAnimating()) {
+            } else if (win.mWinAnimator.isAnimationSet()) {
                 nowGone = false;
             }
         }
@@ -297,7 +297,7 @@
             // Return true so that the alpha doesn't get cleared.
             if (!win.mAppFreezing
                     && (win.mViewVisibility == View.VISIBLE || mAnimatingWithSavedSurface
-                            || (win.mWinAnimator.isAnimating()
+                            || (win.mWinAnimator.isAnimationSet()
                                     && !service.mAppTransition.isTransitionSet()))
                     && !win.mDestroying
                     && win.isDrawnLw()) {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 4f49eed..6925fa5 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -601,7 +601,7 @@
                     // Anyway we don't need to synchronize position and content updates for these
                     // windows since they aren't at the base layer and could be moved around anyway.
                     if (!win.computeDragResizing() && win.mAttrs.type == TYPE_BASE_APPLICATION &&
-                            !mStack.getBoundsAnimating()) {
+                            !mStack.getBoundsAnimating() && !win.isGoneForLayoutLw()) {
                         win.mResizedWhileNotDragResizing = true;
                     }
                 }
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index a289855..467f5b6 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -41,7 +41,6 @@
 import android.util.SparseArray;
 import android.view.DisplayInfo;
 import android.view.Surface;
-import android.view.animation.PathInterpolator;
 import android.view.SurfaceControl;
 
 import com.android.internal.policy.DividerSnapAlgorithm;
@@ -503,7 +502,7 @@
                 final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
                 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
                     final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
-                    if (winAnimator.isAnimating() || winAnimator.mWin.mAnimatingExit) {
+                    if (winAnimator.isAnimationSet() || winAnimator.mWin.mAnimatingExit) {
                         return true;
                     }
                 }
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index e44b0f3..88028be 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -146,7 +146,7 @@
     }
 
     boolean isWallpaperTargetAnimating() {
-        return mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimating()
+        return mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimationSet()
                 && !mWallpaperTarget.mWinAnimator.isDummyAnimation();
     }
 
@@ -516,7 +516,7 @@
             if (hasWallpaper && w.isOnScreen() && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
                 if (DEBUG_WALLPAPER) Slog.v(TAG, "Found wallpaper target: #" + i + "=" + w);
                 result.setWallpaperTarget(w, i);
-                if (w == mWallpaperTarget && w.mWinAnimator.isAnimating()) {
+                if (w == mWallpaperTarget && w.mWinAnimator.isAnimationSet()) {
                     // The current wallpaper target is animating, so we'll look behind it for
                     // another possible target and figure out what is going on later.
                     if (DEBUG_WALLPAPER) Slog.v(TAG,
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index aee8fc9..3af03c7 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -120,7 +120,6 @@
 import android.view.WindowManagerPolicy.PointerEventListener;
 import android.view.animation.Animation;
 import android.view.inputmethod.InputMethodManagerInternal;
-import android.widget.Toast;
 
 import com.android.internal.R;
 import com.android.internal.app.IAssistScreenshotReceiver;
@@ -1525,7 +1524,7 @@
 
                 if (highestTarget != null) {
                     if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, mAppTransition + " " + highestTarget
-                            + " animating=" + highestTarget.mWinAnimator.isAnimating()
+                            + " animating=" + highestTarget.mWinAnimator.isAnimationSet()
                             + " layer=" + highestTarget.mWinAnimator.mAnimLayer
                             + " new layer=" + w.mWinAnimator.mAnimLayer);
 
@@ -1535,7 +1534,7 @@
                         mInputMethodTargetWaitingAnim = true;
                         mInputMethodTarget = highestTarget;
                         return highestPos + 1;
-                    } else if (highestTarget.mWinAnimator.isAnimating() &&
+                    } else if (highestTarget.mWinAnimator.isAnimationSet() &&
                             highestTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
                         // If the window we are currently targeting is involved
                         // with an animation, and it is on top of the next target
@@ -2275,7 +2274,7 @@
                 + " mRemoveOnExit=" + win.mRemoveOnExit
                 + " mHasSurface=" + win.mHasSurface
                 + " surfaceShowing=" + win.mWinAnimator.getShown()
-                + " isAnimating=" + win.mWinAnimator.isAnimating()
+                + " isAnimationSet=" + win.mWinAnimator.isAnimationSet()
                 + " app-animation="
                 + (win.mAppToken != null ? win.mAppToken.mAppAnimator.animation : null)
                 + " mWillReplaceWindow=" + win.mWillReplaceWindow
@@ -2339,7 +2338,7 @@
                 }
             }
             final boolean isAnimating =
-                    winAnimator.isAnimating() && !winAnimator.isDummyAnimation();
+                    winAnimator.isAnimationSet() && !winAnimator.isDummyAnimation();
             final boolean lastWindowIsStartingWindow = startingWindow && appToken != null
                     && appToken.allAppWindows.size() == 1;
             // We delay the removal of a window if it has a showing surface that can be used to run
@@ -2924,7 +2923,7 @@
             focusMayChange = isDefaultDisplay;
             win.mAnimatingExit = true;
             win.mWinAnimator.mAnimating = true;
-        } else if (win.mWinAnimator.isAnimating()) {
+        } else if (win.mWinAnimator.isAnimationSet()) {
             // Currently in a hide animation... turn this into
             // an exit.
             win.mAnimatingExit = true;
@@ -3281,7 +3280,7 @@
                         WindowState win = wtoken.windows.get(i);
                         displayContent = win.getDisplayContent();
 
-                        if (win.mWinAnimator.isAnimating()) {
+                        if (win.mWinAnimator.isAnimationSet()) {
                             delayed = true;
                         }
 
@@ -4297,7 +4296,7 @@
         }
 
         for (int i = wtoken.allAppWindows.size() - 1; i >= 0 && !delayed; i--) {
-            if (wtoken.allAppWindows.get(i).mWinAnimator.isWindowAnimating()) {
+            if (wtoken.allAppWindows.get(i).mWinAnimator.isWindowAnimationSet()) {
                 delayed = true;
             }
         }
@@ -9101,7 +9100,7 @@
 
     void updateResizingWindows(final WindowState w) {
         final WindowStateAnimator winAnimator = w.mWinAnimator;
-        if (w.mHasSurface && w.mLayoutSeq == mLayoutSeq) {
+        if (w.mHasSurface && w.mLayoutSeq == mLayoutSeq && !w.isGoneForLayoutLw()) {
             w.setInsetsChanged();
             boolean configChanged = w.isConfigChanged();
             if (DEBUG_CONFIGURATION && configChanged) {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 8c29c9b..f603995 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -291,21 +291,33 @@
         }
     }
 
-    /** Is the window or its container currently animating? */
-    boolean isAnimating() {
+    /**
+     * Is the window or its container currently set to animate or currently animating?
+     */
+    boolean isAnimationSet() {
         return mAnimation != null
                 || (mAttachedWinAnimator != null && mAttachedWinAnimator.mAnimation != null)
                 || (mAppAnimator != null && mAppAnimator.isAnimating());
     }
 
+    /**
+     * @return whether an animation is about to start, i.e. the animation is set already but we
+     *         haven't processed the first frame yet.
+     */
+    boolean isAnimationStarting() {
+        return isAnimationSet() && !mAnimating;
+    }
+
     /** Is the window animating the DummyAnimation? */
     boolean isDummyAnimation() {
         return mAppAnimator != null
                 && mAppAnimator.animation == sDummyAnimation;
     }
 
-    /** Is this window currently set to animate or currently animating? */
-    boolean isWindowAnimating() {
+    /**
+     * Is this window currently set to animate or currently animating?
+     */
+    boolean isWindowAnimationSet() {
         return mAnimation != null;
     }
 
@@ -340,7 +352,7 @@
     // there is more animation to run.
     boolean stepAnimationLocked(long currentTime) {
         // Save the animation state as it was before this step so WindowManagerService can tell if
-        // we just started or just stopped animating by comparing mWasAnimating with isAnimating().
+        // we just started or just stopped animating by comparing mWasAnimating with isAnimationSet().
         mWasAnimating = mAnimating;
         final DisplayContent displayContent = mWin.getDisplayContent();
         if (displayContent != null && mService.okToDisplay()) {
@@ -402,7 +414,7 @@
                 // Little trick to get through the path below to act like
                 // we have finished an animation.
                 mAnimating = true;
-            } else if (isAnimating()) {
+            } else if (isAnimationSet()) {
                 mAnimating = true;
             }
         } else if (mAnimation != null) {
@@ -476,7 +488,7 @@
                 TAG, "finishExit in " + this
                 + ": exiting=" + mWin.mAnimatingExit
                 + " remove=" + mWin.mRemoveOnExit
-                + " windowAnimating=" + isWindowAnimating());
+                + " windowAnimating=" + isWindowAnimationSet());
 
         if (!mWin.mChildWindows.isEmpty()) {
             // Copying to a different list as multiple children can be removed.
@@ -499,7 +511,7 @@
             }
         }
 
-        if (!isWindowAnimating()) {
+        if (!isWindowAnimationSet()) {
             //TODO (multidisplay): Accessibility is supported only for the default display.
             if (mService.mAccessibilityController != null
                     && mWin.getDisplayId() == DEFAULT_DISPLAY) {
@@ -511,7 +523,7 @@
             return;
         }
 
-        if (isWindowAnimating()) {
+        if (isWindowAnimationSet()) {
             return;
         }
 
@@ -1310,7 +1322,7 @@
         final int stackClip = resolveStackClip();
 
         // It's animating and we don't want to clip it to stack bounds during animation - abort.
-        if (isAnimating() && stackClip == STACK_CLIP_NONE) {
+        if (isAnimationSet() && stackClip == STACK_CLIP_NONE) {
             return;
         }
 
@@ -1332,7 +1344,7 @@
 
         // If we are animating, we either apply the clip before applying all the animation
         // transformation or after all the transformation.
-        final boolean useFinalClipRect = isAnimating() && stackClip == STACK_CLIP_AFTER_ANIM;
+        final boolean useFinalClipRect = isAnimationSet() && stackClip == STACK_CLIP_AFTER_ANIM;
 
         // We need to do some acrobatics with surface position, because their clip region is
         // relative to the inside of the surface, but the stack bounds aren't.
@@ -1507,7 +1519,7 @@
                 w.mToken.hasVisible = true;
             }
         } else {
-            if (DEBUG_ANIM && isAnimating()) {
+            if (DEBUG_ANIM && isAnimationSet()) {
                 Slog.v(TAG, "prepareSurface: No changes in animation for " + this);
             }
             displayed = true;
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 928fcc0..8937f09 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -10,7 +10,6 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
 import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
@@ -762,13 +761,15 @@
                             }
                         }
                     }
-                    if (!winAnimator.isAnimating()) {
+                    if (!winAnimator.isAnimationStarting()) {
                         // Updates the shown frame before we set up the surface. This is needed
                         // because the resizing could change the top-left position (in addition to
                         // size) of the window. setSurfaceBoundariesLocked uses mShownPosition to
-                        // position the surface. We only apply it to windows that aren't animating,
-                        // because we depend on the animation to calculate the correct shown frame
-                        // on the next animation step.
+                        // position the surface.
+                        //
+                        // If an animation is being started, we can't call this method because the
+                        // animation hasn't processed its initial transformation yet, but in general
+                        // we do want to update the position if the window is animating.
                         winAnimator.computeShownFrameLocked();
                     }
                     winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
@@ -792,7 +793,7 @@
                         if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
                             Slog.v(TAG, "Eval win " + w + ": isDrawn="
                                     + w.isDrawnLw()
-                                    + ", isAnimating=" + winAnimator.isAnimating());
+                                    + ", isAnimationSet=" + winAnimator.isAnimationSet());
                             if (!w.isDrawnLw()) {
                                 Slog.v(TAG, "Not displayed: s="
                                         + winAnimator.mSurfaceController
@@ -943,7 +944,8 @@
             // windows, since that means "perform layout as normal,
             // just don't display").
             if (!gone || !win.mHaveFrame || win.mLayoutNeeded
-                    || ((win.isConfigChanged() || win.setInsetsChanged()) &&
+                    || ((win.isConfigChanged() || win.setInsetsChanged())
+                            && !win.isGoneForLayoutLw() &&
                             ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
                             (win.mHasSurface && win.mAppToken != null &&
                             win.mAppToken.layoutConfigChanges)))) {