Align task thumbnails to edge when cropped.

Align to left edge unless RTL enabled. Do not rotate thumbnails if they
would not fit nicely once rotated.

Test: manual - Ensure task thumbnails align with left edge if cropped.
Bug: 177402412
Change-Id: I6e03715061120deb5a8fde005d676170eed0f819
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index df1229b..867b972 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -270,10 +270,12 @@
             mSizeStrategy.calculateGridSize(mContext, mDp, mGridRect);
             mThumbnailData.rotation = mOrientationState.getDisplayRotation();
 
+            // mIsRecentsRtl is the inverse of TaskView RTL.
+            boolean isRtlEnabled = !mIsRecentsRtl;
             mPositionHelper.updateThumbnailMatrix(
                     mThumbnailPosition, mThumbnailData,
                     mTaskRect.width(), mTaskRect.height(),
-                    mDp, mOrientationState.getRecentsActivityRotation());
+                    mDp, mOrientationState.getRecentsActivityRotation(), isRtlEnabled);
             mPositionHelper.getMatrix().invert(mInversePositionMatrix);
 
             PagedOrientationHandler poh = mOrientationState.getOrientationHandler();
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index 36a5f03..17d075f 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -379,9 +379,10 @@
                     mThumbnailData.thumbnail.getHeight());
             int currentRotation = getTaskView().getRecentsView().getPagedViewOrientedState()
                     .getRecentsActivityRotation();
+            boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
             mPreviewPositionHelper.updateThumbnailMatrix(mPreviewRect, mThumbnailData,
                     getMeasuredWidth(), getMeasuredHeight(), mActivity.getDeviceProfile(),
-                    currentRotation);
+                    currentRotation, isRtl);
 
             mBitmapShader.setLocalMatrix(mPreviewPositionHelper.mMatrix);
             mPaint.setShader(mBitmapShader);
@@ -466,7 +467,8 @@
          * Updates the matrix based on the provided parameters
          */
         public void updateThumbnailMatrix(Rect thumbnailBounds, ThumbnailData thumbnailData,
-                int canvasWidth, int canvasHeight, DeviceProfile dp, int currentRotation) {
+                int canvasWidth, int canvasHeight, DeviceProfile dp, int currentRotation,
+                boolean isRtl) {
             boolean isRotated = false;
             boolean isOrientationDifferent;
 
@@ -500,6 +502,17 @@
                 float availableHeight = surfaceHeight
                         - (thumbnailClipHint.top + thumbnailClipHint.bottom);
 
+                if (isRotated) {
+                    float canvasAspect = canvasWidth / (float) canvasHeight;
+                    float availableAspect = availableHeight / availableWidth;
+                    // Do not rotate thumbnail if it would not improve fit
+                    if (Utilities.isRelativePercentDifferenceGreaterThan(canvasAspect,
+                            availableAspect, 0.1f)) {
+                        isRotated = false;
+                        isOrientationDifferent = false;
+                    }
+                }
+
                 final float targetW, targetH;
                 if (isOrientationDifferent) {
                     targetW = canvasHeight;
@@ -535,28 +548,25 @@
                     }
                 }
 
-                // Update the clip hints
-                float halfExtraW = (availableWidth - croppedWidth) / 2;
-                thumbnailClipHint.left += halfExtraW;
-                thumbnailClipHint.right += halfExtraW;
-                if (thumbnailClipHint.left < 0) {
-                    thumbnailClipHint.right += thumbnailClipHint.left;
-                    thumbnailClipHint.left = 0;
-                } else if (thumbnailClipHint.right < 0) {
-                    thumbnailClipHint.left += thumbnailClipHint.right;
+                // Update the clip hints. Align to 0,0, crop the remaining.
+                if (isRtl) {
+                    if (thumbnailClipHint.right < 0) {
+                        thumbnailClipHint.left += thumbnailClipHint.right;
+                    }
                     thumbnailClipHint.right = 0;
+                    thumbnailClipHint.left += availableWidth - croppedWidth;
+                } else {
+                    if (thumbnailClipHint.left < 0) {
+                        thumbnailClipHint.right += thumbnailClipHint.left;
+                    }
+                    thumbnailClipHint.left = 0;
+                    thumbnailClipHint.right += availableWidth - croppedWidth;
                 }
-
-                float halfExtraH = (availableHeight - croppedHeight) / 2;
-                thumbnailClipHint.top += halfExtraH;
-                thumbnailClipHint.bottom += halfExtraH;
                 if (thumbnailClipHint.top < 0) {
                     thumbnailClipHint.bottom += thumbnailClipHint.top;
-                    thumbnailClipHint.top = 0;
-                } else if (thumbnailClipHint.bottom < 0) {
-                    thumbnailClipHint.top += thumbnailClipHint.bottom;
-                    thumbnailClipHint.bottom = 0;
                 }
+                thumbnailClipHint.top = 0;
+                thumbnailClipHint.bottom += availableHeight - croppedHeight;
 
                 thumbnailScale = targetW / (croppedWidth * scale);
             }
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index c440303..94c6574 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -690,6 +690,16 @@
         };
     }
 
+    /**
+     * Compares the ratio of two quantities and returns whether that ratio is greater than the
+     * provided bound. Order of quantities does not matter. Bound should be a decimal representation
+     * of a percentage.
+     */
+    public static boolean isRelativePercentDifferenceGreaterThan(float first, float second,
+            float bound) {
+        return (Math.abs(first - second) / Math.abs((first + second) / 2.0f)) > bound;
+    }
+
     private static class FixedSizeEmptyDrawable extends ColorDrawable {
 
         private final int mSize;