Merge "Rotate quickswitch task thumbnails" into ub-launcher3-master
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
index 3bc1509..49f667e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -20,7 +20,6 @@
 import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_FULLSCREEN;
 
 import android.content.Context;
-import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.graphics.BitmapShader;
 import android.graphics.Canvas;
@@ -38,11 +37,11 @@
 import android.util.AttributeSet;
 import android.util.FloatProperty;
 import android.util.Property;
+import android.view.Surface;
 import android.view.View;
 import android.view.ViewGroup;
 
 import com.android.launcher3.BaseActivity;
-import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
@@ -102,7 +101,7 @@
     private float mSaturation = 1f;
 
     private boolean mOverlayEnabled;
-    private boolean mRotated;
+    private boolean mIsOrientationChanged;
     private OverviewScreenshotActions mOverviewScreenshotActionsPlugin;
 
     public TaskThumbnailView(Context context) {
@@ -323,7 +322,7 @@
 
     private void updateOverlay() {
         // The overlay doesn't really work when the screenshot is rotated, so don't add it.
-        if (mOverlayEnabled && !mRotated && mBitmapShader != null && mThumbnailData != null) {
+        if (mOverlayEnabled && !mIsOrientationChanged && mBitmapShader != null && mThumbnailData != null) {
             mOverlay.initOverlay(mTask, mThumbnailData, mMatrix);
         } else {
             mOverlay.reset();
@@ -346,6 +345,7 @@
 
     private void updateThumbnailMatrix() {
         boolean isRotated = false;
+        boolean isOrientationDifferent = false;
         mClipBottom = -1;
         if (mBitmapShader != null && mThumbnailData != null) {
             float scale = mThumbnailData.scale;
@@ -356,51 +356,40 @@
                     (thumbnailInsets.top + thumbnailInsets.bottom) * scale;
 
             final float thumbnailScale;
-            final DeviceProfile profile = mActivity.getDeviceProfile();
-
+            int thumbnailRotation = mThumbnailData.rotation;
+            int currentRotation = getDisplay() != null ? getDisplay().getRotation() : 0;
+            int deltaRotate = getRotationDelta(currentRotation, thumbnailRotation);
+            // Landscape vs portrait change
+            boolean windowingModeSupportsRotation = !mActivity.isInMultiWindowMode()
+                    && mThumbnailData.windowingMode == WINDOWING_MODE_FULLSCREEN;
+            isOrientationDifferent = isOrientationChange(deltaRotate)
+                && windowingModeSupportsRotation;
             if (getMeasuredWidth() == 0) {
                 // If we haven't measured , skip the thumbnail drawing and only draw the background
                 // color
                 thumbnailScale = 0f;
             } else {
-                final Configuration configuration =
-                        getContext().getResources().getConfiguration();
                 // Rotate the screenshot if not in multi-window mode
-                isRotated = configuration.orientation != mThumbnailData.orientation &&
-                        !mActivity.isInMultiWindowMode() &&
-                        mThumbnailData.windowingMode == WINDOWING_MODE_FULLSCREEN;
+                isRotated = deltaRotate > 0 && windowingModeSupportsRotation;
                 // Scale the screenshot to always fit the width of the card.
-                thumbnailScale = isRotated
+
+                thumbnailScale = isOrientationDifferent
                         ? getMeasuredWidth() / thumbnailHeight
                         : getMeasuredWidth() / thumbnailWidth;
             }
 
-            if (isRotated) {
-                int rotationDir = profile.isVerticalBarLayout() && !profile.isSeascape() ? -1 : 1;
-                mMatrix.setRotate(90 * rotationDir);
-                int newLeftInset = rotationDir == 1 ? thumbnailInsets.bottom : thumbnailInsets.top;
-                int newTopInset = rotationDir == 1 ? thumbnailInsets.left : thumbnailInsets.right;
-                mClippedInsets.offsetTo(newLeftInset * scale, newTopInset * scale);
-                if (rotationDir == -1) {
-                    // Crop the right/bottom side of the screenshot rather than left/top
-                    float excessHeight = thumbnailWidth * thumbnailScale - getMeasuredHeight();
-                    mClippedInsets.offset(0, excessHeight);
-                }
-                mMatrix.postTranslate(-mClippedInsets.left, -mClippedInsets.top);
-                // Move the screenshot to the thumbnail window (rotation moved it out).
-                if (rotationDir == 1) {
-                    mMatrix.postTranslate(mThumbnailData.thumbnail.getHeight(), 0);
-                } else {
-                    mMatrix.postTranslate(0, mThumbnailData.thumbnail.getWidth());
-                }
-            } else {
-                mClippedInsets.offsetTo(thumbnailInsets.left * scale, thumbnailInsets.top * scale);
+            if (!isRotated) {
+                // No Rotation
+                mClippedInsets.offsetTo(thumbnailInsets.left * scale,
+                    thumbnailInsets.top * scale);
                 mMatrix.setTranslate(-mClippedInsets.left, -mClippedInsets.top);
+            } else {
+                setThumbnailRotation(deltaRotate, thumbnailInsets, scale);
             }
 
             final float widthWithInsets;
             final float heightWithInsets;
-            if (isRotated) {
+            if (isOrientationDifferent) {
                 widthWithInsets = mThumbnailData.thumbnail.getHeight() * thumbnailScale;
                 heightWithInsets = mThumbnailData.thumbnail.getWidth() * thumbnailScale;
             } else {
@@ -415,7 +404,7 @@
             mMatrix.postScale(thumbnailScale, thumbnailScale);
             mBitmapShader.setLocalMatrix(mMatrix);
 
-            float bitmapHeight = Math.max((isRotated ? thumbnailWidth : thumbnailHeight)
+            float bitmapHeight = Math.max((isOrientationDifferent ? thumbnailWidth : thumbnailHeight)
                     * thumbnailScale, 0);
             if (Math.round(bitmapHeight) < getMeasuredHeight()) {
                 mClipBottom = bitmapHeight;
@@ -423,7 +412,7 @@
             mPaint.setShader(mBitmapShader);
         }
 
-        mRotated = isRotated;
+        mIsOrientationChanged = isOrientationDifferent;
         invalidate();
 
         // Update can be called from {@link #onSizeChanged} during layout, post handling of overlay
@@ -431,6 +420,51 @@
         post(this::updateOverlay);
     }
 
+    private int getRotationDelta(int oldRotation, int newRotation) {
+        int delta = newRotation - oldRotation;
+        if (delta < 0) delta += 4;
+        return delta;
+    }
+
+    /**
+     * @param deltaRotation the number of 90 degree turns from the current orientation
+     * @return {@code true} if the change in rotation results in a shift from landscape to portrait
+     * or vice versa, {@code false} otherwise
+     */
+    private boolean isOrientationChange(int deltaRotation) {
+        return deltaRotation == Surface.ROTATION_90 || deltaRotation == Surface.ROTATION_270;
+    }
+
+    private void setThumbnailRotation(int deltaRotate, Rect thumbnailInsets, float scale) {
+        int newLeftInset = 0;
+        int newTopInset = 0;
+        int translateX = 0;
+        int translateY = 0;
+
+        mMatrix.setRotate(90 * deltaRotate);
+        switch (deltaRotate) { /* Counter-clockwise */
+            case Surface.ROTATION_90:
+                newLeftInset = thumbnailInsets.bottom;
+                newTopInset = thumbnailInsets.left;
+                translateX = mThumbnailData.thumbnail.getHeight();
+                break;
+            case Surface.ROTATION_270:
+                newLeftInset = thumbnailInsets.top;
+                newTopInset = thumbnailInsets.right;
+                translateY = mThumbnailData.thumbnail.getWidth();
+                break;
+            case Surface.ROTATION_180:
+                newLeftInset = -thumbnailInsets.top;
+                newTopInset = -thumbnailInsets.left;
+                translateX = mThumbnailData.thumbnail.getWidth();
+                translateY = mThumbnailData.thumbnail.getHeight();
+                break;
+        }
+        mClippedInsets.offsetTo(newLeftInset * scale, newTopInset * scale);
+        mMatrix.postTranslate(translateX - mClippedInsets.left,
+                translateY - mClippedInsets.top);
+    }
+
     @Override
     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
         super.onSizeChanged(w, h, oldw, oldh);