Use sourceRectHint to calculate scale when enter PiP

This is to patch the entering PiP transition with YT tablet UI, which is
used in unfolded state and/or tablets landscape mode.

Changed also to use SurfaceControl.Transaction#setCrop instead of
deprecated setWindowCrop.

Bug: 198309223
Video: http://recall/-/aaaaaabFQoRHlzixHdtY/eODHpvqAQPfbwjFamtRYC1
Test: manual, see video
Change-Id: I6fbfea110f9a73faf05ebeb90773dcee58b41328
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
index 3379000..95bb65c5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
@@ -250,7 +250,6 @@
         protected T mCurrentValue;
         protected T mStartValue;
         private T mEndValue;
-        private float mStartingAngle;
         private PipAnimationCallback mPipAnimationCallback;
         private PipTransactionHandler mPipTransactionHandler;
         private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory
@@ -260,8 +259,8 @@
         protected SurfaceControl mContentOverlay;
 
         private PipTransitionAnimator(TaskInfo taskInfo, SurfaceControl leash,
-                @AnimationType int animationType, Rect destinationBounds, T baseValue, T startValue,
-                T endValue, float startingAngle) {
+                @AnimationType int animationType,
+                Rect destinationBounds, T baseValue, T startValue, T endValue) {
             mTaskInfo = taskInfo;
             mLeash = leash;
             mAnimationType = animationType;
@@ -269,7 +268,6 @@
             mBaseValue = baseValue;
             mStartValue = startValue;
             mEndValue = endValue;
-            mStartingAngle = startingAngle;
             addListener(this);
             addUpdateListener(this);
             mSurfaceControlTransactionFactory =
@@ -480,7 +478,7 @@
         static PipTransitionAnimator<Float> ofAlpha(TaskInfo taskInfo, SurfaceControl leash,
                 Rect destinationBounds, float startValue, float endValue) {
             return new PipTransitionAnimator<Float>(taskInfo, leash, ANIM_TYPE_ALPHA,
-                    destinationBounds, startValue, startValue, endValue, 0) {
+                    destinationBounds, startValue, startValue, endValue) {
                 @Override
                 void applySurfaceControlTransaction(SurfaceControl leash,
                         SurfaceControl.Transaction tx, float fraction) {
@@ -520,7 +518,7 @@
                 @PipAnimationController.TransitionDirection int direction, float startingAngle,
                 @Surface.Rotation int rotationDelta) {
             final boolean isOutPipDirection = isOutPipDirection(direction);
-
+            final boolean isInPipDirection = isInPipDirection(direction);
             // Just for simplicity we'll interpolate between the source rect hint insets and empty
             // insets to calculate the window crop
             final Rect initialSourceValue;
@@ -559,8 +557,7 @@
 
             // construct new Rect instances in case they are recycled
             return new PipTransitionAnimator<Rect>(taskInfo, leash, ANIM_TYPE_BOUNDS,
-                    endValue, new Rect(baseValue), new Rect(startValue), new Rect(endValue),
-                    startingAngle) {
+                    endValue, new Rect(baseValue), new Rect(startValue), new Rect(endValue)) {
                 private final RectEvaluator mRectEvaluator = new RectEvaluator(new Rect());
                 private final RectEvaluator mInsetsEvaluator = new RectEvaluator(new Rect());
 
@@ -595,7 +592,8 @@
                     } else {
                         final Rect insets = computeInsets(fraction);
                         getSurfaceTransactionHelper().scaleAndCrop(tx, leash,
-                                initialSourceValue, bounds, insets);
+                                sourceHintRect, initialSourceValue, bounds, insets,
+                                isInPipDirection);
                         if (shouldApplyCornerRadius()) {
                             final Rect sourceBounds = new Rect(initialContainerRect);
                             sourceBounds.inset(insets);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
index 00f62d4..b349010 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
@@ -103,21 +103,31 @@
      * @return same {@link PipSurfaceTransactionHelper} instance for method chaining
      */
     public PipSurfaceTransactionHelper scaleAndCrop(SurfaceControl.Transaction tx,
-            SurfaceControl leash,
-            Rect sourceBounds, Rect destinationBounds, Rect insets) {
+            SurfaceControl leash, Rect sourceRectHint,
+            Rect sourceBounds, Rect destinationBounds, Rect insets,
+            boolean isInPipDirection) {
         mTmpSourceRectF.set(sourceBounds);
         mTmpDestinationRect.set(sourceBounds);
         mTmpDestinationRect.inset(insets);
         // Scale by the shortest edge and offset such that the top/left of the scaled inset source
         // rect aligns with the top/left of the destination bounds
-        final float scale = sourceBounds.width() <= sourceBounds.height()
-                ? (float) destinationBounds.width() / sourceBounds.width()
-                : (float) destinationBounds.height() / sourceBounds.height();
+        final float scale;
+        if (isInPipDirection
+                && sourceRectHint != null && sourceRectHint.width() < sourceBounds.width()) {
+            // scale by sourceRectHint if it's not edge-to-edge, for entering PiP transition only.
+            scale = sourceBounds.width() <= sourceBounds.height()
+                    ? (float) destinationBounds.width() / sourceRectHint.width()
+                    : (float) destinationBounds.height() / sourceRectHint.height();
+        } else {
+            scale = sourceBounds.width() <= sourceBounds.height()
+                    ? (float) destinationBounds.width() / sourceBounds.width()
+                    : (float) destinationBounds.height() / sourceBounds.height();
+        }
         final float left = destinationBounds.left - insets.left * scale;
         final float top = destinationBounds.top - insets.top * scale;
         mTmpTransform.setScale(scale, scale);
         tx.setMatrix(leash, mTmpTransform, mTmpFloat9)
-                .setWindowCrop(leash, mTmpDestinationRect)
+                .setCrop(leash, mTmpDestinationRect)
                 .setPosition(leash, left, top);
         return this;
     }
@@ -163,7 +173,7 @@
         mTmpTransform.setScale(scale, scale);
         mTmpTransform.postRotate(degrees);
         mTmpTransform.postTranslate(positionX, positionY);
-        tx.setMatrix(leash, mTmpTransform, mTmpFloat9).setWindowCrop(leash, crop);
+        tx.setMatrix(leash, mTmpTransform, mTmpFloat9).setCrop(leash, crop);
         return this;
     }
 
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java
index 238690c..938b1ca 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java
@@ -80,21 +80,29 @@
 
     public PictureInPictureSurfaceTransaction scaleAndCrop(
             SurfaceControl.Transaction tx, SurfaceControl leash,
-            Rect sourceBounds, Rect destinationBounds, Rect insets) {
+            Rect sourceRectHint, Rect sourceBounds, Rect destinationBounds, Rect insets) {
         mTmpSourceRectF.set(sourceBounds);
         mTmpDestinationRect.set(sourceBounds);
         mTmpDestinationRect.inset(insets);
         // Scale by the shortest edge and offset such that the top/left of the scaled inset
         // source rect aligns with the top/left of the destination bounds
-        final float scale = sourceBounds.width() <= sourceBounds.height()
-                ? (float) destinationBounds.width() / sourceBounds.width()
-                : (float) destinationBounds.height() / sourceBounds.height();
+        final float scale;
+        if (sourceRectHint.isEmpty() || sourceRectHint.width() == sourceBounds.width()) {
+            scale = sourceBounds.width() <= sourceBounds.height()
+                    ? (float) destinationBounds.width() / sourceBounds.width()
+                    : (float) destinationBounds.height() / sourceBounds.height();
+        } else {
+            // scale by sourceRectHint if it's not edge-to-edge
+            scale = sourceRectHint.width() <= sourceRectHint.height()
+                    ? (float) destinationBounds.width() / sourceRectHint.width()
+                    : (float) destinationBounds.height() / sourceRectHint.height();
+        }
         final float left = destinationBounds.left - (insets.left + sourceBounds.left) * scale;
         final float top = destinationBounds.top - (insets.top + sourceBounds.top) * scale;
         mTmpTransform.setScale(scale, scale);
         final float cornerRadius = getScaledCornerRadius(mTmpDestinationRect, destinationBounds);
         tx.setMatrix(leash, mTmpTransform, mTmpFloat9)
-                .setWindowCrop(leash, mTmpDestinationRect)
+                .setCrop(leash, mTmpDestinationRect)
                 .setPosition(leash, left, top)
                 .setCornerRadius(leash, cornerRadius)
                 .setShadowRadius(leash, mShadowRadius);
@@ -127,7 +135,7 @@
             adjustedPositionY = positionY - insets.left * scale;
         }
         tx.setMatrix(leash, mTmpTransform, mTmpFloat9)
-                .setWindowCrop(leash, mTmpDestinationRect)
+                .setCrop(leash, mTmpDestinationRect)
                 .setPosition(leash, adjustedPositionX, adjustedPositionY)
                 .setCornerRadius(leash, cornerRadius)
                 .setShadowRadius(leash, mShadowRadius);