Merge "Force windows to be scalable during pinned animation." into nyc-dev
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index ef50fdc..7da849a 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -102,13 +102,13 @@
     public @interface ScalingMode {}
     // From system/window.h
     /** @hide */
-    static final int SCALING_MODE_FREEZE = 0;
+    public static final int SCALING_MODE_FREEZE = 0;
     /** @hide */
-    static final int SCALING_MODE_SCALE_TO_WINDOW = 1;
+    public static final int SCALING_MODE_SCALE_TO_WINDOW = 1;
     /** @hide */
-    static final int SCALING_MODE_SCALE_CROP = 2;
+    public static final int SCALING_MODE_SCALE_CROP = 2;
     /** @hide */
-    static final int SCALING_MODE_NO_SCALE_CROP = 3;
+    public static final int SCALING_MODE_NO_SCALE_CROP = 3;
 
     /** @hide */
     @IntDef({ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270})
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index c30ede3..dc9014b 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -85,6 +85,8 @@
             IBinder displayToken, int mode);
     private static native void nativeDeferTransactionUntil(long nativeObject,
             IBinder handle, long frame);
+    private static native void nativeSetOverrideScalingMode(long nativeObject,
+            int scalingMode);
     private static native IBinder nativeGetHandle(long nativeObject);
 
 
@@ -376,6 +378,11 @@
         nativeDeferTransactionUntil(mNativeObject, handle, frame);
     }
 
+    public void setOverrideScalingMode(int scalingMode) {
+        checkNotReleased();
+        nativeSetOverrideScalingMode(mNativeObject, scalingMode);
+    }
+
     public IBinder getHandle() {
         return nativeGetHandle(mNativeObject);
     }
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index d8233a0..0590134 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -597,6 +597,13 @@
     ctrl->deferTransactionUntil(handle, frameNumber);
 }
 
+static void nativeSetOverrideScalingMode(JNIEnv* env, jclass clazz, jlong nativeObject,
+        jint scalingMode) {
+    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+
+    ctrl->setOverrideScalingMode(scalingMode);
+}
+
 static jobject nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) {
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
 
@@ -676,6 +683,8 @@
             (void*)nativeSetDisplayPowerMode },
     {"nativeDeferTransactionUntil", "(JLandroid/os/IBinder;J)V",
             (void*)nativeDeferTransactionUntil },
+    {"nativeSetOverrideScalingMode", "(JI)V",
+            (void*)nativeSetOverrideScalingMode },
     {"nativeGetHandle", "(J)Landroid/os/IBinder;",
             (void*)nativeGetHandle }
 };
diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java
index b7d6062..eacdd81 100644
--- a/services/core/java/com/android/server/wm/BoundsAnimationController.java
+++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java
@@ -129,13 +129,16 @@
         public void onAnimationStart(Animator animation) {
             if (DEBUG) Slog.d(TAG, "onAnimationStart: mTarget=" + mTarget
                     + " mReplacement=" + mReplacement);
-            if (animatingToLargerSize()) {
-                mTarget.setPinnedStackSize(mFrom, mTo);
-            }
-
             if (!mReplacement) {
                 mTarget.onAnimationStart();
             }
+
+            // Ensure that we have prepared the target for animation before
+            // we trigger any size changes, so it can swap surfaces
+            // in to appropriate modes, or do as it wishes otherwise.
+            if (animatingToLargerSize()) {
+                mTarget.setPinnedStackSize(mFrom, mTo);
+            }
         }
 
         @Override
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 46a8dff..4f49eed 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -600,7 +600,8 @@
                     //
                     // 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) {
+                    if (!win.computeDragResizing() && win.mAttrs.type == TYPE_BASE_APPLICATION &&
+                            !mStack.getBoundsAnimating()) {
                         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 872bc6d..1fd2b1f 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -42,6 +42,7 @@
 import android.view.DisplayInfo;
 import android.view.Surface;
 import android.view.animation.PathInterpolator;
+import android.view.SurfaceControl;
 
 import com.android.internal.policy.DividerSnapAlgorithm;
 import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
@@ -127,10 +128,12 @@
     private float mAdjustImeAmount;
     private final int mDockedStackMinimizeThickness;
 
-    // If this is true, the task will be down or upscaled
-    // to perfectly fit the region it would have been cropped
-    // to.
-    private boolean mForceScaleToCrop = false;
+    // If this is true, we are in the bounds animating mode.
+    // The task will be down or upscaled to perfectly fit the
+    // region it would have been cropped to. We may also avoid
+    // 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
@@ -1269,11 +1272,36 @@
         return true;
     }
 
+    void forceWindowsScaleable(boolean force) {
+        SurfaceControl.openTransaction();
+        try {
+            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) {
+                        final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
+                        if (winAnimator == null || !winAnimator.hasSurface()) {
+                            continue;
+                        }
+                        winAnimator.mSurfaceController.forceScaleableInTransaction(force);
+                    }
+                }
+            }
+        } finally {
+            SurfaceControl.closeTransaction();
+        }
+    }
+
     @Override  // AnimatesBounds
     public void onAnimationStart() {
         synchronized (mService.mWindowMap) {
+            // We force windows out of SCALING_MODE_FREEZE
+            // so that we can continue to animate them
+            // while a resize is pending.
+            forceWindowsScaleable(true);
             mFreezeMovementAnimations = true;
-            mForceScaleToCrop = true;
+            mBoundsAnimating = true;
         }
     }
 
@@ -1281,7 +1309,8 @@
     public void onAnimationEnd() {
         synchronized (mService.mWindowMap) {
             mFreezeMovementAnimations = false;
-            mForceScaleToCrop = false;
+            mBoundsAnimating = false;
+            forceWindowsScaleable(false);
             mService.requestTraversal();
         }
         if (mStackId == PINNED_STACK_ID) {
@@ -1312,6 +1341,10 @@
     }
 
     public boolean getForceScaleToCrop() {
-        return mForceScaleToCrop;
+        return mBoundsAnimating;
+    }
+
+    public boolean getBoundsAnimating() {
+        return mBoundsAnimating;
     }
 }
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 08982f4..f6ef69d 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -562,6 +562,7 @@
             Slog.v(TAG, "Finishing drawing window " + mWin + ": mDrawState="
                     + drawStateToString());
         }
+
         if (mWin.mAppToken != null && mWin.mAppToken.mAnimatingWithSavedSurface) {
             // App has drawn something to its windows, we're no longer animating with
             // the saved surfaces. If the user exits now, we only want to save again
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 8799c61..6eed5e7 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -23,6 +23,8 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static android.view.Surface.SCALING_MODE_FREEZE;
+import static android.view.Surface.SCALING_MODE_SCALE_TO_WINDOW;
 
 import android.graphics.Point;
 import android.graphics.PointF;
@@ -392,6 +394,13 @@
         mSurfaceControl.deferTransactionUntil(handle, frame);
     }
 
+    void forceScaleableInTransaction(boolean force) {
+        // -1 means we don't override the default or client specified
+        // scaling mode.
+        int scalingMode = force ? SCALING_MODE_SCALE_TO_WINDOW : -1;
+        mSurfaceControl.setOverrideScalingMode(scalingMode);
+    }
+
     boolean clearWindowContentFrameStats() {
         if (mSurfaceControl == null) {
             return false;