Scale, crop, and translate window when swiping back to home.

This makes the animation consistent with what happens
when swiping up to home.

Bug: 208292857
Test: open app, swipe back to close, test on portrait and landscape
Change-Id: I096b20fe3d3398001e442d41981350e7b0321a46
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index 0123c4f..a8a085b 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -660,10 +660,10 @@
         AnimOpenProperties prop = new AnimOpenProperties(mLauncher.getResources(), mDeviceProfile,
                 windowTargetBounds, launcherIconBounds, v, dragLayerBounds[0], dragLayerBounds[1],
                 hasSplashScreen, floatingView.isDifferentFromAppIcon());
-        int left = (int) (prop.cropCenterXStart - prop.cropWidthStart / 2);
-        int top = (int) (prop.cropCenterYStart - prop.cropHeightStart / 2);
-        int right = (int) (left + prop.cropWidthStart);
-        int bottom = (int) (top + prop.cropHeightStart);
+        int left = prop.cropCenterXStart - prop.cropWidthStart / 2;
+        int top = prop.cropCenterYStart - prop.cropHeightStart / 2;
+        int right = left + prop.cropWidthStart;
+        int bottom = top + prop.cropHeightStart;
         // Set the crop here so we can calculate the corner radius below.
         crop.set(left, top, right, bottom);
 
@@ -1329,6 +1329,8 @@
                 mDeviceProfile);
 
         // Hook up floating views to the closing window animators.
+        final int rotationChange = getRotationChange(targets);
+        Rect windowTargetBounds = getWindowTargetBounds(targets, rotationChange);
         if (floatingIconView != null) {
             anim.addAnimatorListener(floatingIconView);
             floatingIconView.setOnTargetChangeListener(anim::onTargetPositionChanged);
@@ -1339,7 +1341,8 @@
             // FolderIconView can be seen morphing into the icon shape.
             final float windowAlphaThreshold = 1f - SHAPE_PROGRESS_DURATION;
 
-            RectFSpringAnim.OnUpdateListener runner = new SpringAnimRunner(targets, targetRect) {
+            RectFSpringAnim.OnUpdateListener runner = new SpringAnimRunner(targets, targetRect,
+                    windowTargetBounds) {
                 @Override
                 public void onUpdate(RectF currentRectF, float progress) {
                     finalFloatingIconView.update(1f, 255 /* fgAlpha */, currentRectF, progress,
@@ -1356,7 +1359,8 @@
 
             final float floatingWidgetAlpha = isTransluscent ? 0 : 1;
             FloatingWidgetView finalFloatingWidget = floatingWidget;
-            RectFSpringAnim.OnUpdateListener  runner = new SpringAnimRunner(targets, targetRect) {
+            RectFSpringAnim.OnUpdateListener  runner = new SpringAnimRunner(targets, targetRect,
+                    windowTargetBounds) {
                 @Override
                 public void onUpdate(RectF currentRectF, float progress) {
                     final float fallbackBackgroundAlpha =
@@ -1767,12 +1771,17 @@
         private final float mStartRadius;
         private final float mEndRadius;
         private final SurfaceTransactionApplier mSurfaceApplier;
+        private final Rect mWindowTargetBounds = new Rect();
 
-        SpringAnimRunner(RemoteAnimationTargetCompat[] appTargets, RectF targetRect) {
+        private final Rect mTmpRect = new Rect();
+
+        SpringAnimRunner(RemoteAnimationTargetCompat[] appTargets, RectF targetRect,
+                Rect windowTargetBounds) {
             mAppTargets = appTargets;
             mStartRadius = QuickStepContract.getWindowCornerRadius(mLauncher);
             mEndRadius = Math.max(1, targetRect.width()) / 2f;
             mSurfaceApplier = new SurfaceTransactionApplier(mDragLayer);
+            mWindowTargetBounds.set(windowTargetBounds);
         }
 
         public float getCornerRadius(float progress) {
@@ -1793,13 +1802,36 @@
                 }
 
                 if (target.mode == MODE_CLOSING) {
-                    float alpha = getWindowAlpha(progress);
                     currentRectF.round(mCurrentRect);
 
+                    // Scale the target window to match the currentRectF.
+                    final float scale;
+
+                    // We need to infer the crop (we crop the window to match the currentRectF).
+                    if (mWindowTargetBounds.height() > mWindowTargetBounds.width()) {
+                        scale = Math.min(1f, currentRectF.width() / mWindowTargetBounds.width());
+
+                        int unscaledHeight = (int) (mCurrentRect.height() * (1f / scale));
+                        int croppedHeight = mWindowTargetBounds.height() - unscaledHeight;
+                        mTmpRect.set(0, 0, mWindowTargetBounds.width(),
+                                mWindowTargetBounds.height() - croppedHeight);
+                    } else {
+                        scale = Math.min(1f, currentRectF.height() / mWindowTargetBounds.height());
+
+                        int unscaledWidth = (int) (mCurrentRect.width() * (1f / scale));
+                        int croppedWidth = mWindowTargetBounds.width() - unscaledWidth;
+                        mTmpRect.set(0, 0, mWindowTargetBounds.width() - croppedWidth,
+                                mWindowTargetBounds.height());
+                    }
+
+                    // Match size and position of currentRect.
+                    mMatrix.setScale(scale, scale);
+                    mMatrix.postTranslate(mCurrentRect.left, mCurrentRect.top);
+
                     builder.withMatrix(mMatrix)
-                            .withWindowCrop(mCurrentRect)
-                            .withAlpha(alpha)
-                            .withCornerRadius(getCornerRadius(progress));
+                            .withWindowCrop(mTmpRect)
+                            .withAlpha(getWindowAlpha(progress))
+                            .withCornerRadius(getCornerRadius(progress) / scale);
                 } else if (target.mode == MODE_OPENING) {
                     mMatrix.setTranslate(mTmpPos.x, mTmpPos.y);
                     builder.withMatrix(mMatrix)