Updating the card size logic

In full screen always follow the device aspect ratio
In multi-window, follow the 1:1 split window size
Rotate the screen shot only in full-screen mode

Bug: 70289009
Change-Id: Id5095565634d4d7920fefa929b28276db80bda5f
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index ab6d8af..c741913 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -20,7 +20,6 @@
     <dimen name="task_thumbnail_icon_size">48dp</dimen>
     <dimen name="task_menu_background_radius">12dp</dimen>
     <dimen name="task_corner_radius">2dp</dimen>
-    <dimen name="task_fade_length">20dp</dimen>
     <dimen name="recents_page_spacing">10dp</dimen>
 
     <!-- The speed in dp/s at which the user needs to be scrolling in recents such that we start
@@ -37,4 +36,13 @@
     <dimen name="recents_empty_message_text_size">16sp</dimen>
     <dimen name="recents_empty_message_text_padding">16dp</dimen>
 
+    <!-- Total space (start + end) between the task card and the edge of the screen
+         in various configurations -->
+    <dimen name="task_card_vert_space">40dp</dimen>
+    <dimen name="portrait_task_card_horz_space">136dp</dimen>
+    <dimen name="landscape_task_card_horz_space">200dp</dimen>
+    <dimen name="multi_window_task_card_horz_space">100dp</dimen>
+    <!-- Copied from framework resource:
+       docked_stack_divider_thickness - 2 * docked_stack_divider_insets -->
+    <dimen name="multi_window_task_divider_size">10dp</dimen>
 </resources>
diff --git a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
index ec54732..9c7db30 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
@@ -19,13 +19,11 @@
 import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
 import static com.android.launcher3.states.RotationHelper.REQUEST_ROTATE;
 
-import android.graphics.Rect;
 import android.view.View;
 
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
-import com.android.launcher3.Workspace;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import com.android.quickstep.views.RecentsView;
 
@@ -47,14 +45,8 @@
 
     @Override
     public float[] getWorkspaceScaleAndTranslation(Launcher launcher) {
-        Rect pageRect = new Rect();
-        RecentsView.getPageRect(launcher.getDeviceProfile(), launcher, pageRect);
-
-        if (launcher.getWorkspace().getNormalChildWidth() <= 0 || pageRect.isEmpty()) {
-            return super.getWorkspaceScaleAndTranslation(launcher);
-        }
-
-        return getScaleAndTranslationForPageRect(launcher, pageRect);
+        // TODO: provide a valid value
+        return new float[]{1, 0, -launcher.getDeviceProfile().hotseatBarSizePx / 2};
     }
 
     @Override
@@ -93,20 +85,6 @@
         };
     }
 
-    public static float[] getScaleAndTranslationForPageRect(Launcher launcher, Rect pageRect) {
-        Workspace ws = launcher.getWorkspace();
-        float childWidth = ws.getNormalChildWidth();
-
-        float scale = pageRect.width() / childWidth;
-        Rect insets = launcher.getDragLayer().getInsets();
-
-        float halfHeight = ws.getExpectedHeight() / 2;
-        float childTop = halfHeight - scale * (halfHeight - ws.getPaddingTop() - insets.top);
-        float translationY = pageRect.top - childTop;
-
-        return new float[] {scale, 0, translationY};
-    }
-
     @Override
     public int getVisibleElements(Launcher launcher) {
         if (launcher.getDeviceProfile().isVerticalBarLayout()) {
diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
index d82b8f4..708bec0 100644
--- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java
+++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
@@ -44,6 +44,7 @@
 import com.android.quickstep.fallback.FallbackRecentsView;
 import com.android.quickstep.util.RemoteAnimationProvider;
 import com.android.quickstep.views.LauncherLayoutListener;
+import com.android.quickstep.views.LauncherRecentsView;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskView;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -122,7 +123,7 @@
 
         @Override
         public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect) {
-            RecentsView.getPageRect(dp, context, outRect);
+            LauncherRecentsView.getPageRect(dp, context, outRect);
             if (dp.isVerticalBarLayout()) {
                 Rect targetInsets = dp.getInsets();
                 int hotseatInset = dp.isSeascape() ? targetInsets.left : targetInsets.right;
@@ -271,7 +272,7 @@
 
         @Override
         public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect) {
-            FallbackRecentsView.getCenterPageRect(dp, context, outRect);
+            FallbackRecentsView.getPageRect(dp, context, outRect);
             if (dp.isVerticalBarLayout()) {
                 Rect targetInsets = dp.getInsets();
                 int hotseatInset = dp.isSeascape() ? targetInsets.left : targetInsets.right;
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 7d7f88f..4ed1656 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -18,15 +18,16 @@
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Rect;
+import android.support.annotation.AnyThread;
 import android.util.AttributeSet;
 import android.view.View;
 
 import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Insettable;
 import com.android.quickstep.RecentsActivity;
+import com.android.quickstep.util.LayoutUtils;
 import com.android.quickstep.views.RecentsView;
 
-public class FallbackRecentsView extends RecentsView<RecentsActivity> implements Insettable {
+public class FallbackRecentsView extends RecentsView<RecentsActivity> {
 
     public FallbackRecentsView(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
@@ -56,30 +57,18 @@
     }
 
     @Override
-    public void setInsets(Rect insets) {
-        mInsets.set(insets);
-        DeviceProfile dp = mActivity.getDeviceProfile();
-        Rect padding = getPadding(dp, getContext());
-        verticalCenter(padding, dp);
-        setPadding(padding.left, padding.top, padding.right, padding.bottom);
-    }
-
-    private static void verticalCenter(Rect padding, DeviceProfile dp) {
-        Rect insets = dp.getInsets();
-        int totalSpace = (padding.top + padding.bottom - insets.top - insets.bottom) / 2;
-        padding.top = insets.top + totalSpace;
-        padding.bottom = insets.bottom + totalSpace;
-    }
-
-    public static void getCenterPageRect(DeviceProfile grid, Context context, Rect outRect) {
-        Rect targetPadding = getPadding(grid, context);
-        verticalCenter(targetPadding, grid);
-        getPageRect(grid, context, outRect, targetPadding);
-    }
-
-    @Override
     public void draw(Canvas canvas) {
         maybeDrawEmptyMessage(canvas);
         super.draw(canvas);
     }
+
+    @Override
+    protected void getTaskSize(DeviceProfile dp, Rect outRect) {
+        LayoutUtils.calculateTaskSize(getContext(), dp, 0, outRect);
+    }
+
+    @AnyThread
+    public static void getPageRect(DeviceProfile grid, Context context, Rect outRect) {
+        LayoutUtils.calculateTaskSize(context, grid, 0, outRect);
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/util/LayoutUtils.java b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
new file mode 100644
index 0000000..f29f9e4
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Rect;
+import android.graphics.RectF;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.R;
+
+public class LayoutUtils {
+
+    public static void calculateLauncherTaskSize(Context context, DeviceProfile dp, Rect outRect) {
+        float extraSpace = dp.isVerticalBarLayout() ? 0 : dp.hotseatBarSizePx;
+        calculateTaskSize(context, dp, extraSpace, outRect);
+    }
+
+    public static void calculateTaskSize(Context context, DeviceProfile dp,
+            float extraVerticalSpace, Rect outRect) {
+        float taskWidth, taskHeight, paddingHorz;
+        Resources res = context.getResources();
+        Rect insets = dp.getInsets();
+
+        if (dp.isMultiWindowMode) {
+            DeviceProfile fullDp = dp.getFullScreenProfile();
+            // Use availableWidthPx and availableHeightPx instead of widthPx and heightPx to
+            // account for system insets
+            taskWidth = fullDp.availableWidthPx;
+            taskHeight = fullDp.availableHeightPx;
+            float halfDividerSize = res.getDimension(R.dimen.multi_window_task_divider_size) / 2;
+
+            if (fullDp.isLandscape) {
+                taskWidth = taskWidth / 2 - halfDividerSize;
+            } else {
+                taskHeight = taskHeight / 2 - halfDividerSize;
+            }
+            paddingHorz = res.getDimension(R.dimen.multi_window_task_card_horz_space);
+        } else {
+            taskWidth = dp.availableWidthPx;
+            taskHeight = dp.availableHeightPx;
+            paddingHorz = res.getDimension(dp.isVerticalBarLayout()
+                    ? R.dimen.landscape_task_card_horz_space
+                    : R.dimen.portrait_task_card_horz_space);
+        }
+
+        float topIconMargin = res.getDimension(R.dimen.task_thumbnail_top_margin);
+        float paddingVert = res.getDimension(R.dimen.task_card_vert_space);
+
+        // Note this should be same as dp.availableWidthPx and dp.availableHeightPx unless
+        // we override the insets ourselves.
+        int launcherVisibleWidth = dp.widthPx - insets.left - insets.right;
+        int launcherVisibleHeight = dp.heightPx - insets.top - insets.bottom;
+
+        float availableHeight = launcherVisibleHeight
+                - topIconMargin - extraVerticalSpace - paddingVert;
+        float availableWidth = launcherVisibleWidth - paddingHorz;
+
+        float scale = Math.min(availableWidth / taskWidth, availableHeight / taskHeight);
+        float outWidth = scale * taskWidth;
+        float outHeight = scale * taskHeight;
+
+        // Center in the visible space
+        float x = insets.left + (taskWidth - outWidth) / 2;
+        float y = insets.top + Math.max(topIconMargin,
+                (launcherVisibleHeight - extraVerticalSpace - outHeight) / 2);
+        outRect.set(Math.round(x), Math.round(y),
+                Math.round(x + outWidth), Math.round(y + outHeight));
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 6788827..4b4af3f 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -27,22 +27,22 @@
 import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.os.Build;
+import android.support.annotation.AnyThread;
 import android.util.AttributeSet;
 import android.util.FloatProperty;
 import android.view.View;
 import android.view.ViewDebug;
 
 import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Insettable;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
-import com.android.launcher3.R;
+import com.android.quickstep.util.LayoutUtils;
 
 /**
  * {@link RecentsView} used in Launcher activity
  */
 @TargetApi(Build.VERSION_CODES.O)
-public class LauncherRecentsView extends RecentsView<Launcher> implements Insettable {
+public class LauncherRecentsView extends RecentsView<Launcher> {
 
     public static final FloatProperty<LauncherRecentsView> TRANSLATION_Y_FACTOR =
             new FloatProperty<LauncherRecentsView>("translationYFactor") {
@@ -61,8 +61,6 @@
     @ViewDebug.ExportedProperty(category = "launcher")
     private float mTranslationYFactor;
 
-    private Rect mPagePadding = new Rect();
-
     public LauncherRecentsView(Context context) {
         this(context, null);
     }
@@ -77,16 +75,6 @@
     }
 
     @Override
-    public void setInsets(Rect insets) {
-        mInsets.set(insets);
-        DeviceProfile dp = mActivity.getDeviceProfile();
-        Rect padding = getPadding(dp, getContext());
-        setPadding(padding.left, padding.top, padding.right, padding.bottom);
-        mPagePadding.set(padding);
-        mPagePadding.top += getResources().getDimensionPixelSize(R.dimen.task_thumbnail_top_margin);
-    }
-
-    @Override
     protected void onAllTasksRemoved() {
         mActivity.getStateManager().goToState(NORMAL);
     }
@@ -99,7 +87,7 @@
 
     public void setTranslationYFactor(float translationFactor) {
         mTranslationYFactor = translationFactor;
-        setTranslationY(mTranslationYFactor * (mPagePadding.bottom - mPagePadding.top));
+        setTranslationY(mTranslationYFactor * (getPaddingBottom() - getPaddingTop()));
     }
 
     @Override
@@ -138,4 +126,14 @@
                 mActivity.getAllAppsController(), ALL_APPS_PROGRESS, allAppsProgressOffscreen));
         return anim;
     }
+
+    @Override
+    protected void getTaskSize(DeviceProfile dp, Rect outRect) {
+        LayoutUtils.calculateLauncherTaskSize(getContext(), dp, outRect);
+    }
+
+    @AnyThread
+    public static void getPageRect(DeviceProfile grid, Context context, Rect outRect) {
+        LayoutUtils.calculateLauncherTaskSize(context, grid, outRect);
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 83fb634..c19f5dd 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -53,6 +53,7 @@
 
 import com.android.launcher3.BaseActivity;
 import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Insettable;
 import com.android.launcher3.PagedView;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
@@ -72,7 +73,6 @@
 import com.android.systemui.shared.recents.model.ThumbnailData;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.TaskStackChangeListener;
-import com.android.systemui.shared.system.WindowManagerWrapper;
 
 import java.util.ArrayList;
 
@@ -81,7 +81,9 @@
  */
 @TargetApi(Build.VERSION_CODES.P)
 public abstract class RecentsView<T extends BaseActivity>
-        extends PagedView implements OnSharedPreferenceChangeListener {
+        extends PagedView implements OnSharedPreferenceChangeListener, Insettable {
+
+    private final Rect mTempRect = new Rect();
 
     public static final FloatProperty<RecentsView> CONTENT_ALPHA =
             new FloatProperty<RecentsView>("contentAlpha") {
@@ -96,8 +98,6 @@
         }
     };
 
-
-
     public static final FloatProperty<RecentsView> ADJACENT_SCALE =
             new FloatProperty<RecentsView>("adjacentScale") {
         @Override
@@ -113,8 +113,6 @@
     private static final String PREF_FLIP_RECENTS = "pref_flip_recents";
     private static final int DISMISS_TASK_DURATION = 300;
 
-    private static final Rect sTempStableInsets = new Rect();
-
     protected final T mActivity;
     private final QuickScrubController mQuickScrubController;
     private final float mFastFlingVelocity;
@@ -394,69 +392,20 @@
         }
     }
 
-    protected static Rect getPadding(DeviceProfile profile, Context context) {
-        WindowManagerWrapper.getInstance().getStableInsets(sTempStableInsets);
-        Rect padding = new Rect(profile.workspacePadding);
-
-        float taskWidth = profile.widthPx - sTempStableInsets.left - sTempStableInsets.right;
-        float taskHeight = profile.heightPx - sTempStableInsets.top - sTempStableInsets.bottom;
-
-        float overviewHeight, overviewWidth;
-        if (profile.isVerticalBarLayout()) {
-            float maxPadding = Math.max(padding.left, padding.right);
-
-            // Use the same padding on both sides for symmetry.
-            float availableWidth = taskWidth - 2 * maxPadding;
-            float availableHeight = profile.availableHeightPx - padding.top - padding.bottom
-                    - sTempStableInsets.top;
-            float scaledRatio = Math.min(availableWidth / taskWidth, availableHeight / taskHeight);
-            overviewHeight = taskHeight * scaledRatio;
-            overviewWidth = taskWidth * scaledRatio;
-
-        } else {
-            overviewHeight = profile.availableHeightPx - padding.top - padding.bottom
-                    - sTempStableInsets.top;
-            overviewWidth = taskWidth * overviewHeight / taskHeight;
-        }
-
-        padding.bottom = profile.availableHeightPx - padding.top - sTempStableInsets.top
-                - Math.round(overviewHeight);
-        padding.left = padding.right = (int) ((profile.availableWidthPx - overviewWidth) / 2);
-
-        // If the height ratio is larger than the width ratio, the screenshot will get cropped
-        // at the bottom when swiping up. In this case, increase the top/bottom padding to make it
-        // the same aspect ratio.
-        Rect pageRect = new Rect();
-        getPageRect(profile, context, pageRect, padding);
-        float widthRatio = (float) pageRect.width() / taskWidth;
-        float heightRatio = (float) pageRect.height() / taskHeight;
-        if (heightRatio > widthRatio) {
-            float additionalVerticalPadding = pageRect.height() - widthRatio * taskHeight;
-            additionalVerticalPadding = Math.round(additionalVerticalPadding);
-            padding.top += additionalVerticalPadding / 2;
-            padding.bottom += additionalVerticalPadding / 2;
-        }
-
-        return padding;
-    }
-
-    public static void getPageRect(DeviceProfile grid, Context context, Rect outRect) {
-        Rect targetPadding = getPadding(grid, context);
-        getPageRect(grid, context, outRect, targetPadding);
-    }
-
-    protected static void getPageRect(DeviceProfile grid, Context context, Rect outRect,
-            Rect targetPadding) {
-        Rect insets = grid.getInsets();
-        outRect.set(
-                targetPadding.left + insets.left,
-                targetPadding.top + insets.top,
-                grid.widthPx - targetPadding.right - insets.right,
-                grid.heightPx - targetPadding.bottom - insets.bottom);
-        outRect.top += context.getResources()
+    @Override
+    public void setInsets(Rect insets) {
+        mInsets.set(insets);
+        DeviceProfile dp = mActivity.getDeviceProfile();
+        getTaskSize(dp, mTempRect);
+        mTempRect.top -= getResources()
                 .getDimensionPixelSize(R.dimen.task_thumbnail_top_margin);
+        setPadding(mTempRect.left - mInsets.left, mTempRect.top - mInsets.top,
+                dp.widthPx - mTempRect.right - mInsets.right,
+                dp.heightPx - mTempRect.bottom - mInsets.bottom);
     }
 
+    protected abstract void getTaskSize(DeviceProfile dp, Rect outRect);
+
     @Override
     protected boolean computeScrollHelper() {
         boolean scrolling = super.computeScrollHelper();
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index 8b41b58..58b7db7 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -22,12 +22,9 @@
 import android.graphics.BitmapShader;
 import android.graphics.Canvas;
 import android.graphics.Color;
-import android.graphics.ComposeShader;
 import android.graphics.LightingColorFilter;
-import android.graphics.LinearGradient;
 import android.graphics.Matrix;
 import android.graphics.Paint;
-import android.graphics.PorterDuff.Mode;
 import android.graphics.Rect;
 import android.graphics.Shader;
 import android.util.AttributeSet;
@@ -50,14 +47,16 @@
     private static final LightingColorFilter[] sDimFilterCache = new LightingColorFilter[256];
 
     private final float mCornerRadius;
-    private final float mFadeLength;
 
+    private final BaseActivity mActivity;
     private final TaskOverlay mOverlay;
     private final Paint mPaint = new Paint();
-    private final Paint mLockedPaint = new Paint();
+    private final Paint mBackgroundPaint = new Paint();
 
     private final Matrix mMatrix = new Matrix();
 
+    private float mClipBottom = -1;
+
     private Task mTask;
     private ThumbnailData mThumbnailData;
     protected BitmapShader mBitmapShader;
@@ -75,10 +74,10 @@
     public TaskThumbnailView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
         mCornerRadius = getResources().getDimension(R.dimen.task_corner_radius);
-        mFadeLength = getResources().getDimension(R.dimen.task_fade_length);
         mOverlay = TaskOverlayFactory.get(context).createOverlay(this);
         mPaint.setFilterBitmap(true);
-        mLockedPaint.setColor(Color.WHITE);
+        mBackgroundPaint.setColor(Color.WHITE);
+        mActivity = BaseActivity.fromContext(context);
     }
 
     public void bind() {
@@ -90,7 +89,9 @@
      */
     public void setThumbnail(Task task, ThumbnailData thumbnailData) {
         mTask = task;
-        mPaint.setColor(task == null ? Color.BLACK : task.colorBackground | 0xFF000000);
+        int color = task == null ? Color.BLACK : task.colorBackground | 0xFF000000;
+        mPaint.setColor(color);
+        mBackgroundPaint.setColor(color);
 
         if (thumbnailData != null && thumbnailData.thumbnail != null) {
             Bitmap bm = thumbnailData.thumbnail;
@@ -128,8 +129,23 @@
         if (mTask == null) {
             return;
         }
-        canvas.drawRoundRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mCornerRadius,
-                mCornerRadius, mTask.isLocked ? mLockedPaint : mPaint);
+        int width = getMeasuredWidth();
+        int height = getMeasuredHeight();
+        if (mClipBottom > 0 && !mTask.isLocked) {
+            canvas.save();
+            canvas.clipRect(0, 0, width, mClipBottom);
+
+            canvas.drawRoundRect(0, 0, width, height, mCornerRadius, mCornerRadius, mPaint);
+            canvas.restore();
+            canvas.save();
+            canvas.clipRect(0, mClipBottom, width, height);
+            canvas.drawRoundRect(0, 0, width, height, mCornerRadius, mCornerRadius,
+                    mBackgroundPaint);
+            canvas.restore();
+        } else {
+            canvas.drawRoundRect(0, 0, width, height, mCornerRadius,
+                    mCornerRadius, mTask.isLocked ? mBackgroundPaint : mPaint);
+        }
     }
 
     private void updateThumbnailPaintFilter() {
@@ -137,7 +153,7 @@
         if (mBitmapShader != null) {
             LightingColorFilter filter = getLightingColorFilter(mul);
             mPaint.setColorFilter(filter);
-            mLockedPaint.setColorFilter(filter);
+            mBackgroundPaint.setColorFilter(filter);
         } else {
             mPaint.setColorFilter(null);
             mPaint.setColor(Color.argb(255, mul, mul, mul));
@@ -147,47 +163,38 @@
 
     private void updateThumbnailMatrix() {
         boolean rotate = false;
+        mClipBottom = -1;
         if (mBitmapShader != null && mThumbnailData != null) {
             float scale = mThumbnailData.scale;
+            Rect thumbnailInsets  = mThumbnailData.insets;
             float thumbnailWidth = mThumbnailData.thumbnail.getWidth() -
-                    (mThumbnailData.insets.left + mThumbnailData.insets.right) * scale;
+                    (thumbnailInsets.left + thumbnailInsets.right) * scale;
             float thumbnailHeight = mThumbnailData.thumbnail.getHeight() -
-                    (mThumbnailData.insets.top + mThumbnailData.insets.bottom) * scale;
+                    (thumbnailInsets.top + thumbnailInsets.bottom) * scale;
+
             final float thumbnailScale;
-            final DeviceProfile profile = BaseActivity.fromContext(getContext())
-                    .getDeviceProfile();
+            final DeviceProfile profile = mActivity.getDeviceProfile();
+
             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().getApplicationContext().getResources().getConfiguration();
-                if (configuration.orientation == mThumbnailData.orientation) {
-                    // If we are in the same orientation as the screenshot, just scale it to the
-                    // width of the task view
-                    thumbnailScale = getMeasuredWidth() / thumbnailWidth;
-                } else {
-                    if (FeatureFlags.OVERVIEW_USE_SCREENSHOT_ORIENTATION) {
-                        rotate = true;
-                        // Scale the height (will be width after rotation) to the width of this view
-                        thumbnailScale = getMeasuredWidth() / thumbnailHeight;
-                    } else {
-                        if (configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
-                            // Scale the landscape thumbnail up to app size, then scale that to the
-                            // task view size to match other portrait screenshots
-                            thumbnailScale = ((float) getMeasuredWidth() / profile.widthPx);
-                        } else {
-                            // Otherwise, scale the screenshot to fit 1:1 in the current orientation
-                            thumbnailScale = 1;
-                        }
-                    }
-                }
+                        getContext().getResources().getConfiguration();
+                // Rotate the screenshot if not in multi-window mode
+                rotate = FeatureFlags.OVERVIEW_USE_SCREENSHOT_ORIENTATION &&
+                        configuration.orientation != mThumbnailData.orientation &&
+                        !mActivity.isInMultiWindowModeCompat();
+                // Scale the screenshot to always fit the width of the card.
+                thumbnailScale = rotate
+                        ? getMeasuredWidth() / thumbnailHeight
+                        : getMeasuredWidth() / thumbnailWidth;
             }
+
             if (rotate) {
                 int rotationDir = profile.isVerticalBarLayout() && !profile.isSeascape() ? -1 : 1;
                 mMatrix.setRotate(90 * rotationDir);
-                Rect thumbnailInsets  = mThumbnailData.insets;
                 int newLeftInset = rotationDir == 1 ? thumbnailInsets.bottom : thumbnailInsets.top;
                 int newTopInset = rotationDir == 1 ? thumbnailInsets.left : thumbnailInsets.right;
                 mMatrix.postTranslate(-newLeftInset * scale, -newTopInset * scale);
@@ -209,27 +216,11 @@
             mMatrix.postScale(thumbnailScale, thumbnailScale);
             mBitmapShader.setLocalMatrix(mMatrix);
 
-            Shader shader = mBitmapShader;
-            if (!FeatureFlags.OVERVIEW_USE_SCREENSHOT_ORIENTATION) {
-                float bitmapHeight = Math.max(thumbnailHeight * thumbnailScale, 0);
-                if (Math.round(bitmapHeight) < getMeasuredHeight()) {
-                    int color = mPaint.getColor();
-                    LinearGradient fade = new LinearGradient(
-                            0, bitmapHeight - mFadeLength, 0, bitmapHeight,
-                            color & 0x00FFFFFF, color, Shader.TileMode.CLAMP);
-                    shader = new ComposeShader(fade, shader, Mode.DST_OVER);
-                }
-
-                float bitmapWidth = Math.max(thumbnailWidth * thumbnailScale, 0);
-                if (Math.round(bitmapWidth) < getMeasuredWidth()) {
-                    int color = mPaint.getColor();
-                    LinearGradient fade = new LinearGradient(
-                            bitmapWidth - mFadeLength, 0, bitmapWidth, 0,
-                            color & 0x00FFFFFF, color, Shader.TileMode.CLAMP);
-                    shader = new ComposeShader(fade, shader, Mode.DST_OVER);
-                }
+            float bitmapHeight = Math.max(thumbnailHeight * thumbnailScale, 0);
+            if (Math.round(bitmapHeight) < getMeasuredHeight()) {
+                mClipBottom = bitmapHeight;
             }
-            mPaint.setShader(shader);
+            mPaint.setShader(mBitmapShader);
         }
 
         if (rotate) {
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 6f35752..4deed73 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -41,7 +41,7 @@
     public final boolean transposeLayoutWithOrientation;
 
     // Device properties in current orientation
-    private final boolean isLandscape;
+    public final boolean isLandscape;
     public final boolean isMultiWindowMode;
 
     public final int widthPx;