Merge "Fixes for ending PiP animation." into nyc-dev
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index e3035da..31fe390 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -702,6 +702,14 @@
         public static boolean windowsAreScaleable(int stackId) {
             return stackId == PINNED_STACK_ID;
         }
+
+        /**
+         * Returns true if windows in this stack should be given move animations
+         * by default.
+         */
+        public static boolean hasMovementAnimations(int stackId) {
+            return stackId != PINNED_STACK_ID;
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java
index 51c4045..5bfece4 100644
--- a/services/core/java/com/android/server/wm/BoundsAnimationController.java
+++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java
@@ -156,12 +156,10 @@
                     + mTmpRect + " from=" + mFrom + " mTo=" + mTo + " value=" + value
                     + " remains=" + remains);
 
-            if (remains != 0) {
-                mTmpTaskBounds.set(mTmpRect.left, mTmpRect.top,
-                        mTmpRect.left + mFrozenTaskWidth, mTmpRect.top + mFrozenTaskHeight);
-            }
+            mTmpTaskBounds.set(mTmpRect.left, mTmpRect.top,
+                    mTmpRect.left + mFrozenTaskWidth, mTmpRect.top + mFrozenTaskHeight);
 
-            if (!mTarget.setPinnedStackSize(mTmpRect, remains != 0 ? mTmpTaskBounds : null)) {
+            if (!mTarget.setPinnedStackSize(mTmpRect, mTmpTaskBounds)) {
                 // Whoops, the target doesn't feel like animating anymore. Let's immediately finish
                 // any further animation.
                 animation.cancel();
@@ -205,11 +203,12 @@
                 return;
             }
 
+            finishAnimation();
+
+            mTarget.setPinnedStackSize(mTo, null);
             if (mMoveToFullScreen && !mWillReplace) {
                 mTarget.moveToFullscreen();
             }
-
-            finishAnimation();
         }
 
         @Override
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index eb8c1dc..f51fd8a 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -130,12 +130,6 @@
     // certain logic we would otherwise apply while resizing,
     // while resizing in the bounds animating mode.
     private boolean mBoundsAnimating = false;
-    // By default, movement animations are applied to all
-    // window movement. If this is true, animations will not
-    // be applied within this stack. This is useful for example
-    // if the windows are moving as the result of a stack animation,
-    // in which case a second window animation would cause jitter.
-    private boolean mFreezeMovementAnimations = false;
 
     // Temporary storage for the new bounds that should be used after the configuration change.
     // Will be cleared once the client retrieves the new bounds via getBoundsForNewConfiguration().
@@ -1361,7 +1355,6 @@
     @Override  // AnimatesBounds
     public void onAnimationStart() {
         synchronized (mService.mWindowMap) {
-            mFreezeMovementAnimations = true;
             mBoundsAnimating = true;
         }
     }
@@ -1369,7 +1362,6 @@
     @Override  // AnimatesBounds
     public void onAnimationEnd() {
         synchronized (mService.mWindowMap) {
-            mFreezeMovementAnimations = false;
             mBoundsAnimating = false;
             mService.requestTraversal();
         }
@@ -1396,8 +1388,8 @@
         getDisplayContent().getContentRect(bounds);
     }
 
-    public boolean getFreezeMovementAnimations() {
-        return mFreezeMovementAnimations;
+    public boolean hasMovementAnimations() {
+        return StackId.hasMovementAnimations(mStackId);
     }
 
     public boolean getForceScaleToCrop() {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index d936722..54c4214 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -229,6 +229,8 @@
     long mDeferTransactionUntilFrame = -1;
     long mDeferTransactionTime = -1;
 
+    boolean mForceScaleUntilResize;
+
     private final Rect mTmpSize = new Rect();
 
     WindowStateAnimator(final WindowState win) {
@@ -1416,8 +1418,13 @@
         float extraHScale = (float) 1.0;
         float extraVScale = (float) 1.0;
 
+        mSurfaceResized = mSurfaceController.setSizeInTransaction(
+                mTmpSize.width(), mTmpSize.height(), recoveringMemory);
+        mForceScaleUntilResize = mForceScaleUntilResize && !mSurfaceResized;
+
+
         calculateSurfaceWindowCrop(mTmpClipRect, mTmpFinalClipRect);
-        if (task != null && task.mStack.getForceScaleToCrop()) {
+        if ((task != null && task.mStack.getForceScaleToCrop()) || mForceScaleUntilResize) {
             int hInsets = w.getAttrs().surfaceInsets.left + w.getAttrs().surfaceInsets.right;
             int vInsets = w.getAttrs().surfaceInsets.top + w.getAttrs().surfaceInsets.bottom;
             // We want to calculate the scaling based on the content area, not based on
@@ -1447,6 +1454,14 @@
             // past where the system would have cropped us
             mTmpClipRect.set(0, 0, mTmpSize.width(), mTmpSize.height());
             mTmpFinalClipRect.setEmpty();
+
+            // Various surfaces in the scaled stack may resize at different times.
+            // We need to ensure for each surface, that we disable transformation matrix
+            // scaling in the same transaction which we resize the surface in.
+            // As we are in SCALING_MODE_SCALE_TO_WINDOW, SurfaceFlinger will
+            // then take over the scaling until the new buffer arrives, and things 
+            // will be seamless.
+            mForceScaleUntilResize = true;
         } else {
             mSurfaceController.setPositionInTransaction(mTmpSize.left, mTmpSize.top,
                     recoveringMemory);
@@ -1458,8 +1473,6 @@
                 mDtDx * w.mVScale * extraVScale,
                 mDsDy * w.mHScale * extraHScale,
                 mDtDy * w.mVScale * extraVScale, recoveringMemory);
-        mSurfaceResized = mSurfaceController.setSizeInTransaction(
-                mTmpSize.width(), mTmpSize.height(), recoveringMemory);
 
         if (mSurfaceResized) {
             mReportSurfaceResized = true;
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 7e9993d..308b24d 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -719,7 +719,7 @@
                                     || task.mStack.isAdjustedForIme());
                     if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
                             && !w.isDragResizing() && !adjustedForMinimizedDockOrIme
-                            && (task == null || !w.getTask().mStack.getFreezeMovementAnimations())
+                            && (task == null || w.getTask().mStack.hasMovementAnimations())
                             && !w.mWinAnimator.mLastHidden) {
                         winAnimator.setMoveAnimation(left, top);
                     }
@@ -731,7 +731,9 @@
                     }
 
                     try {
-                        w.mClient.moved(left, top);
+                        if (task == null || task.mStack.getBoundsAnimating()) {
+                            w.mClient.moved(left, top);
+                        }
                     } catch (RemoteException e) {
                     }
                     w.mMovedByResize = false;