Merge "Fix folder outline not matching the v28 radius." into sc-dev
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 9773366..2a24624 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -16,20 +16,30 @@
 
 <resources>
 
-    <dimen name="task_thumbnail_top_margin">24dp</dimen>
-    <dimen name="task_thumbnail_half_top_margin">12dp</dimen>
+    <dimen name="task_thumbnail_top_margin">80dp</dimen>
+    <dimen name="task_thumbnail_half_top_margin">40dp</dimen>
     <dimen name="task_thumbnail_icon_size">48dp</dimen>
-    <dimen name="task_icon_top_margin">-16dp</dimen>
+    <dimen name="task_icon_top_margin">16dp</dimen>
     <!-- For screens without rounded corners -->
     <dimen name="task_corner_radius_small">2dp</dimen>
 
+    <dimen name="overview_proactive_row_height">48dp</dimen>
+    <dimen name="overview_proactive_row_bottom_margin">16dp</dimen>
+
+    <dimen name="overview_minimum_next_prev_size">48dp</dimen>
+    <dimen name="overview_task_margin">16dp</dimen>
+
     <!-- Overrideable in overlay that provides the Overview Actions. -->
-    <dimen name="overview_actions_height">66dp</dimen>
-    <dimen name="overview_actions_bottom_margin_gesture">16dp</dimen>
+    <dimen name="overview_actions_height">48dp</dimen>
+    <dimen name="overview_actions_bottom_margin_gesture">12dp</dimen>
     <dimen name="overview_actions_bottom_margin_three_button">8dp</dimen>
     <dimen name="overview_actions_horizontal_margin">16dp</dimen>
 
-    <dimen name="recents_row_spacing">48dp</dimen>
+    <dimen name="overview_grid_top_margin">77dp</dimen>
+    <dimen name="overview_grid_bottom_margin">90dp</dimen>
+    <dimen name="overview_grid_side_margin">54dp</dimen>
+    <dimen name="overview_grid_row_spacing">42dp</dimen>
+
     <dimen name="recents_page_spacing">16dp</dimen>
     <dimen name="recents_clear_all_deadzone_vertical_margin">70dp</dimen>
 
@@ -59,10 +69,6 @@
     <dimen name="task_card_menu_option_vertical_padding">8dp</dimen>
     <dimen name="task_card_menu_shadow_height">3dp</dimen>
     <dimen name="task_card_menu_horizontal_padding">0dp</dimen>
-    <dimen name="portrait_task_card_horz_space_big_overview">132dp</dimen>
-    <dimen name="portrait_modal_task_card_horz_space">60dp</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>
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index ce14197..7c1d9fa 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -33,6 +33,7 @@
 import android.content.res.Resources;
 import android.graphics.Rect;
 import android.os.Build;
+import android.view.Gravity;
 import android.view.MotionEvent;
 
 import androidx.annotation.Nullable;
@@ -53,6 +54,7 @@
 import com.android.quickstep.util.AnimatorControllerWithResistance;
 import com.android.quickstep.util.SplitScreenBounds;
 import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.TaskView;
 import com.android.systemui.shared.recents.model.ThumbnailData;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
 
@@ -197,33 +199,23 @@
      */
     public final void calculateTaskSize(Context context, DeviceProfile dp, Rect outRect,
             PagedOrientationHandler orientedState) {
-        calculateTaskSize(context, dp, getExtraSpace(context, dp, orientedState), outRect);
-    }
-
-    protected abstract float getExtraSpace(Context context, DeviceProfile dp,
-            PagedOrientationHandler orientedState);
-
-    private void calculateTaskSize(Context context, DeviceProfile dp, float extraVerticalSpace,
-            Rect outRect) {
         Resources res = context.getResources();
 
-        final int paddingResId;
-        if (dp.isMultiWindowMode) {
-            paddingResId = R.dimen.multi_window_task_card_horz_space;
-        } else if (dp.isVerticalBarLayout()) {
-            paddingResId = R.dimen.landscape_task_card_horz_space;
-        } else {
-            paddingResId = R.dimen.portrait_task_card_horz_space_big_overview;
-        }
-        float paddingHorz = res.getDimension(paddingResId);
-        float paddingVert = 0;
+        int taskMargin = res.getDimensionPixelSize(R.dimen.overview_task_margin);
+        int taskIconAndMargin = res.getDimensionPixelSize(R.dimen.task_thumbnail_icon_size)
+                + res.getDimensionPixelSize(R.dimen.task_icon_top_margin);
+        int proactiveRowAndMargin = res.getDimensionPixelSize(R.dimen.overview_proactive_row_height)
+                + res.getDimensionPixelSize(R.dimen.overview_proactive_row_bottom_margin);
 
-        calculateTaskSizeInternal(context, dp, extraVerticalSpace, paddingHorz, paddingVert,
-                res.getDimension(R.dimen.task_thumbnail_top_margin), outRect);
+        calculateTaskSizeInternal(context, dp,
+                taskIconAndMargin + taskMargin,
+                proactiveRowAndMargin + getOverviewActionsHeight(context) + taskMargin,
+                res.getDimensionPixelSize(R.dimen.overview_minimum_next_prev_size) + taskMargin,
+                outRect);
     }
 
     private void calculateTaskSizeInternal(Context context, DeviceProfile dp,
-            float extraVerticalSpace, float paddingHorz, float paddingVert, float topIconMargin,
+            int claimedSpaceAbove, int claimedSpaceBelow, int minimumHorizontalPadding,
             Rect outRect) {
         float taskWidth, taskHeight;
         Rect insets = dp.getInsets();
@@ -231,52 +223,64 @@
             WindowBounds bounds = SplitScreenBounds.INSTANCE.getSecondaryWindowBounds(context);
             taskWidth = bounds.availableSize.x;
             taskHeight = bounds.availableSize.y;
-        } else {
+        } else if (TaskView.CLIP_STATUS_AND_NAV_BARS) {
             taskWidth = dp.availableWidthPx;
             taskHeight = dp.availableHeightPx;
+        } else {
+            taskWidth = dp.widthPx;
+            taskHeight = dp.heightPx;
         }
 
-        // 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;
+        Rect potentialTaskRect = new Rect(0, 0, dp.widthPx, dp.heightPx);
+        potentialTaskRect.inset(insets.left, insets.top, insets.right, insets.bottom);
+        potentialTaskRect.inset(
+                minimumHorizontalPadding,
+                claimedSpaceAbove,
+                minimumHorizontalPadding,
+                claimedSpaceBelow);
 
-        float availableHeight = launcherVisibleHeight
-                - topIconMargin - extraVerticalSpace - paddingVert;
-        float availableWidth = launcherVisibleWidth - paddingHorz;
+        float scale = Math.min(
+                potentialTaskRect.width() / taskWidth,
+                potentialTaskRect.height() / taskHeight);
+        int outWidth = Math.round(scale * taskWidth);
+        int outHeight = Math.round(scale * taskHeight);
 
-        float scale = Math.min(availableWidth / taskWidth, availableHeight / taskHeight);
-        float outWidth = scale * taskWidth;
-        float outHeight = scale * taskHeight;
+        Gravity.apply(Gravity.CENTER, outWidth, outHeight, potentialTaskRect, outRect);
+    }
 
-        // Center in the visible space
-        float x = insets.left + (launcherVisibleWidth - outWidth) / 2;
-        float y = insets.top + Math.max(topIconMargin,
-                (launcherVisibleHeight - extraVerticalSpace - outHeight) / 2);
-        outRect.set(Math.round(x), Math.round(y),
-                Math.round(x) + Math.round(outWidth), Math.round(y) + Math.round(outHeight));
+    /**
+     * Calculates the overview grid size for the provided device configuration.
+     */
+    public final void calculateGridSize(Context context, DeviceProfile dp, Rect outRect) {
+        Resources res = context.getResources();
+        int topMargin = res.getDimensionPixelSize(R.dimen.overview_grid_top_margin);
+        int bottomMargin = res.getDimensionPixelSize(R.dimen.overview_grid_bottom_margin);
+        int sideMargin = res.getDimensionPixelSize(R.dimen.overview_grid_side_margin);
+
+        Rect insets = dp.getInsets();
+        outRect.set(0, 0, dp.widthPx, dp.heightPx);
+        outRect.inset(Math.max(insets.left, sideMargin), Math.max(insets.top, topMargin),
+                Math.max(insets.right, sideMargin), Math.max(insets.bottom, bottomMargin));
     }
 
     /**
      * Calculates the modal taskView size for the provided device configuration
      */
     public final void calculateModalTaskSize(Context context, DeviceProfile dp, Rect outRect) {
-        float paddingHorz = context.getResources().getDimension(dp.isMultiWindowMode
-                ? R.dimen.multi_window_task_card_horz_space
-                : dp.isVerticalBarLayout()
-                        ? R.dimen.landscape_task_card_horz_space
-                        : R.dimen.portrait_modal_task_card_horz_space);
-        float extraVerticalSpace = getOverviewActionsHeight(context);
-        float paddingVert = 0;
-        float topIconMargin = 0;
-        calculateTaskSizeInternal(context, dp, extraVerticalSpace, paddingHorz, paddingVert,
-                topIconMargin, outRect);
+        Resources res = context.getResources();
+        calculateTaskSizeInternal(
+                context, dp,
+                res.getDimensionPixelSize(R.dimen.overview_task_margin),
+                getOverviewActionsHeight(context)
+                        + res.getDimensionPixelSize(R.dimen.overview_task_margin),
+                res.getDimensionPixelSize(R.dimen.overview_task_margin),
+                outRect);
     }
 
-    /** Gets the space that the overview actions will take, including margins. */
-    public final float getOverviewActionsHeight(Context context) {
+    /** Gets the space that the overview actions will take, including bottom margin. */
+    public final int getOverviewActionsHeight(Context context) {
         Resources res = context.getResources();
-        float actionsBottomMargin = 0;
+        int actionsBottomMargin = 0;
         if (getMode(context) == Mode.THREE_BUTTONS) {
             actionsBottomMargin = res.getDimensionPixelSize(
                     R.dimen.overview_actions_bottom_margin_three_button);
@@ -284,9 +288,8 @@
             actionsBottomMargin = res.getDimensionPixelSize(
                     R.dimen.overview_actions_bottom_margin_gesture);
         }
-        float overviewActionsHeight = actionsBottomMargin
+        return actionsBottomMargin
                 + res.getDimensionPixelSize(R.dimen.overview_actions_height);
-        return overviewActionsHeight;
     }
 
     /**
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index 96e4f38..db290d6 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -26,7 +26,6 @@
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.R;
 import com.android.launcher3.touch.PagedOrientationHandler;
 import com.android.quickstep.fallback.RecentsState;
 import com.android.quickstep.util.ActivityInitListener;
@@ -155,10 +154,4 @@
         }
         activity.<RecentsView>getOverviewPanel().startHome();
     }
-
-    @Override
-    protected float getExtraSpace(Context context, DeviceProfile dp,
-            PagedOrientationHandler orientationHandler) {
-        return context.getResources().getDimensionPixelSize(R.dimen.overview_actions_height);
-    }
 }
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index 3f3e5ad..7efbfb8 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -19,13 +19,10 @@
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.LauncherState.OVERVIEW;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
-import static com.android.quickstep.SysUINavigationMode.getMode;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
 
 import android.content.Context;
-import android.content.res.Resources;
 import android.graphics.Rect;
-import android.util.Log;
 import android.view.MotionEvent;
 
 import androidx.annotation.Nullable;
@@ -36,13 +33,11 @@
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherInitListener;
 import com.android.launcher3.LauncherState;
-import com.android.launcher3.R;
 import com.android.launcher3.anim.PendingAnimation;
 import com.android.launcher3.statehandlers.DepthController;
 import com.android.launcher3.statehandlers.DepthController.ClampedDepthProperty;
 import com.android.launcher3.statemanager.StateManager;
 import com.android.launcher3.taskbar.TaskbarController;
-import com.android.launcher3.testing.TestProtocol;
 import com.android.launcher3.touch.PagedOrientationHandler;
 import com.android.quickstep.GestureState.GestureEndTarget;
 import com.android.quickstep.SysUINavigationMode.Mode;
@@ -263,27 +258,6 @@
     }
 
     @Override
-    protected float getExtraSpace(Context context, DeviceProfile dp,
-            PagedOrientationHandler orientationHandler) {
-        Resources res = context.getResources();
-        //TODO: this needs to account for the swipe gesture height and accessibility
-        // UI when shown.
-        float actionsBottomMargin = 0;
-        if (!dp.isVerticalBarLayout()) {
-            if (getMode(context) == Mode.THREE_BUTTONS) {
-                actionsBottomMargin = res.getDimensionPixelSize(
-                    R.dimen.overview_actions_bottom_margin_three_button);
-            } else {
-                actionsBottomMargin = res.getDimensionPixelSize(
-                    R.dimen.overview_actions_bottom_margin_gesture);
-            }
-        }
-        float actionsHeight = actionsBottomMargin
-                + res.getDimensionPixelSize(R.dimen.overview_actions_height);
-        return actionsHeight;
-    }
-
-    @Override
     void onOverviewServiceBound() {
         final BaseQuickstepLauncher activity = getCreatedActivity();
         if (activity == null) return;
diff --git a/quickstep/src/com/android/quickstep/util/ImageActionUtils.java b/quickstep/src/com/android/quickstep/util/ImageActionUtils.java
index d022085..0f2d778 100644
--- a/quickstep/src/com/android/quickstep/util/ImageActionUtils.java
+++ b/quickstep/src/com/android/quickstep/util/ImageActionUtils.java
@@ -99,7 +99,14 @@
             .putExtra(Intent.EXTRA_STREAM, uri)
             .putExtra(Intent.EXTRA_SHORTCUT_ID, shortcutInfo.getId())
             .setClipData(clipdata);
-        context.startActivity(intent);
+
+        if (context.getUserId() != appTarget.getUser().getIdentifier()) {
+            intent.prepareToLeaveUser(context.getUserId());
+            intent.fixUris(context.getUserId());
+            context.startActivityAsUser(intent, appTarget.getUser());
+        } else {
+            context.startActivity(intent);
+        }
     }
 
     /**
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index 215f05a..188efad 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -23,9 +23,9 @@
 import static android.view.Surface.ROTATION_270;
 import static android.view.Surface.ROTATION_90;
 
-import static com.android.launcher3.util.SettingsCache.ROTATION_SETTING_URI;
 import static com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY;
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.launcher3.util.SettingsCache.ROTATION_SETTING_URI;
 
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
@@ -47,11 +47,12 @@
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.util.SettingsCache;
 import com.android.launcher3.testing.TestProtocol;
 import com.android.launcher3.touch.PagedOrientationHandler;
+import com.android.launcher3.util.SettingsCache;
 import com.android.launcher3.util.WindowBounds;
 import com.android.quickstep.BaseActivityInterface;
+import com.android.quickstep.views.TaskView;
 
 import java.lang.annotation.Retention;
 import java.util.function.IntConsumer;
@@ -367,8 +368,12 @@
      */
     public float getFullScreenScaleAndPivot(Rect taskView, DeviceProfile dp, PointF outPivot) {
         Rect insets = dp.getInsets();
-        float fullWidth = dp.widthPx - insets.left - insets.right;
-        float fullHeight = dp.heightPx - insets.top - insets.bottom;
+        float fullWidth = dp.widthPx;
+        float fullHeight = dp.heightPx;
+        if (TaskView.CLIP_STATUS_AND_NAV_BARS) {
+            fullWidth -= insets.left + insets.right;
+            fullHeight -= insets.top + insets.bottom;
+        }
 
         if (dp.isMultiWindowMode) {
             WindowBounds bounds = SplitScreenBounds.INSTANCE.getSecondaryWindowBounds(mContext);
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index 9537247..df1229b 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -79,6 +79,7 @@
     private final boolean mIsRecentsRtl;
 
     private final Rect mTaskRect = new Rect();
+    private final Rect mGridRect = new Rect();
     private boolean mDrawsBelowRecents;
     private final PointF mPivot = new PointF();
     private DeviceProfile mDp;
@@ -124,7 +125,7 @@
         Resources resources = context.getResources();
         mIsRecentsRtl = mOrientationState.getOrientationHandler().getRecentsRtlSetting(resources);
         mTaskThumbnailPadding = (int) resources.getDimension(R.dimen.task_thumbnail_top_margin);
-        mRowSpacing = (int) resources.getDimension(R.dimen.recents_row_spacing);
+        mRowSpacing = (int) resources.getDimension(R.dimen.overview_grid_row_spacing);
     }
 
     /**
@@ -266,6 +267,7 @@
             mOrientationStateId = mOrientationState.getStateId();
 
             getFullScreenScale();
+            mSizeStrategy.calculateGridSize(mContext, mDp, mGridRect);
             mThumbnailData.rotation = mOrientationState.getDisplayRotation();
 
             mPositionHelper.updateThumbnailMatrix(
@@ -304,24 +306,34 @@
         mMatrix.postTranslate(insets.left, insets.top);
         mMatrix.postScale(scale, scale);
 
+        // Apply TaskView matrix: gridProgress related properties
         float interpolatedGridProgress = ACCEL_DEACCEL.getInterpolation(gridProgress.value);
-
-        // Apply TaskView matrix: gridProgress
         final int boxLength = (int) Math.max(taskWidth, taskHeight);
-        float availableHeight =
-                mTaskThumbnailPadding + taskHeight + mSizeStrategy.getOverviewActionsHeight(
-                        mContext);
+        float availableHeight = mGridRect.height();
         float rowHeight = (availableHeight - mRowSpacing) / 2;
         float gridScale = rowHeight / (boxLength + mTaskThumbnailPadding);
         scale = Utilities.mapRange(interpolatedGridProgress, 1f, gridScale);
         mMatrix.postScale(scale, scale, mIsRecentsRtl ? 0 : taskWidth, 0);
-        float taskWidthDiff = taskWidth * (1 - gridScale);
-        float taskWidthOffset = mIsRecentsRtl ? taskWidthDiff : -taskWidthDiff;
-        mOrientationState.getOrientationHandler().set(mMatrix, MATRIX_POST_TRANSLATE,
-                Utilities.mapRange(interpolatedGridProgress, 0, taskWidthOffset));
         mOrientationState.getOrientationHandler().setSecondary(mMatrix, MATRIX_POST_TRANSLATE,
                 Utilities.mapRange(interpolatedGridProgress, 0, gridTranslationSecondary.value));
 
+        // Apply TaskView matrix: task rect and grid rect difference
+        float scaledWidth = taskWidth * gridScale;
+        float taskGridHorizontalDiff;
+        if (mIsRecentsRtl) {
+            float taskRight = mTaskRect.left + scaledWidth;
+            taskGridHorizontalDiff = mGridRect.right - taskRight;
+        } else {
+            float taskLeft = mTaskRect.right - scaledWidth;
+            taskGridHorizontalDiff = mGridRect.left - taskLeft;
+        }
+        float taskGridVerticalDiff =
+                mGridRect.top + mTaskThumbnailPadding * gridScale - mTaskRect.top;
+        mOrientationState.getOrientationHandler().set(mMatrix, MATRIX_POST_TRANSLATE,
+                Utilities.mapRange(interpolatedGridProgress, 0, taskGridHorizontalDiff));
+        mOrientationState.getOrientationHandler().setSecondary(mMatrix, MATRIX_POST_TRANSLATE,
+                Utilities.mapRange(interpolatedGridProgress, 0, taskGridVerticalDiff));
+
         // Apply TaskView matrix: translate, scroll
         mMatrix.postTranslate(mTaskRect.left, mTaskRect.top);
         mOrientationState.getOrientationHandler().set(mMatrix, MATRIX_POST_TRANSLATE,
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index d4548df..9a903dc 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -264,6 +264,7 @@
     protected final TransformParams mLiveTileParams = new TransformParams();
     protected final TaskViewSimulator mLiveTileTaskViewSimulator;
     protected final Rect mLastComputedTaskSize = new Rect();
+    protected final Rect mLastComputedGridSize = new Rect();
     // How much a task that is directly offscreen will be pushed out due to RecentsView scale/pivot.
     protected Float mLastComputedTaskPushOutDistance = null;
     protected boolean mEnableDrawingLiveTile = false;
@@ -471,7 +472,7 @@
         setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
         mTaskTopMargin = getResources()
                 .getDimensionPixelSize(R.dimen.task_thumbnail_top_margin);
-        mRowSpacing = (int) getResources().getDimension(R.dimen.recents_row_spacing);
+        mRowSpacing = getResources().getDimensionPixelSize(R.dimen.overview_grid_row_spacing);
         mSquaredTouchSlop = squaredTouchSlop(context);
 
         mEmptyIcon = context.getDrawable(R.drawable.ic_empty_recents);
@@ -1012,6 +1013,10 @@
         setPadding(mTempRect.left - mInsets.left, mTempRect.top - mInsets.top,
                 dp.widthPx - mInsets.right - mTempRect.right,
                 dp.heightPx - mInsets.bottom - mTempRect.bottom);
+
+        mSizeStrategy.calculateGridSize(mActivity, mActivity.getDeviceProfile(),
+                mLastComputedGridSize);
+
         // Force TaskView to update size from thumbnail
         updateTaskSize();
     }
@@ -1521,22 +1526,10 @@
         }
 
         final int boxLength = Math.max(mTaskWidth, mTaskHeight);
-
-        float availableHeight =
-                mTaskTopMargin + mTaskHeight + mSizeStrategy.getOverviewActionsHeight(mContext);
+        float availableHeight = mLastComputedGridSize.height();
         float rowHeight = (availableHeight - mRowSpacing) / 2;
         float gridScale = rowHeight / (boxLength + mTaskTopMargin);
 
-        TaskView firstTask = getTaskViewAt(0);
-        float firstTaskWidthOffset;
-        if (mIsRtl) {
-            // Move the first task to the right edge.
-            firstTaskWidthOffset = mTaskWidth - firstTask.getLayoutParams().width * gridScale;
-        } else {
-            // Move the first task to the left edge.
-            firstTaskWidthOffset = -firstTask.getLayoutParams().width * (1 - gridScale);
-        }
-
         int topRowWidth = 0;
         int bottomRowWidth = 0;
         float topAccumulatedTranslationX = 0;
@@ -1546,13 +1539,22 @@
         for (int i = 0; i < taskCount; i++) {
             TaskView taskView = getTaskViewAt(i);
             taskView.setGridScale(gridScale);
+            gridTranslations[i] = 0;
 
-            float taskWidthDiff = mTaskWidth - taskView.getLayoutParams().width * gridScale;
-            float taskWidthOffset = mIsRtl ? taskWidthDiff : -taskWidthDiff;
-            // Visually we want to move all task by firstTaskWidthOffset, but calculate page scroll
-            // according to right edge (or left in nonRtl) of TaskView.
-            gridTranslations[i] = firstTaskWidthOffset - taskWidthOffset;
-            taskView.setGridOffsetTranslationX(taskWidthOffset);
+            float scaledWidth = taskView.getLayoutParams().width * gridScale;
+            float taskGridHorizontalDiff;
+            if (mIsRtl) {
+                float taskRight = mLastComputedTaskSize.left + scaledWidth;
+                taskGridHorizontalDiff = mLastComputedGridSize.right - taskRight;
+            } else {
+                float taskLeft = mLastComputedTaskSize.right - scaledWidth;
+                taskGridHorizontalDiff = mLastComputedGridSize.left - taskLeft;
+            }
+            gridTranslations[i] -= taskGridHorizontalDiff;
+            taskView.setGridOffsetTranslationX(taskGridHorizontalDiff);
+
+            float taskGridVerticalDiff = mLastComputedGridSize.top + mTaskTopMargin * gridScale
+                    - mLastComputedTaskSize.top;
 
             // Off-set gap due to task scaling.
             float widthDiff = taskView.getLayoutParams().width * (1 - gridScale);
@@ -1567,7 +1569,7 @@
                 topRowWidth += taskView.getLayoutParams().width * gridScale + mPageSpacing;
                 topSet.add(i);
 
-                taskView.setGridTranslationY(0);
+                taskView.setGridTranslationY(taskGridVerticalDiff);
 
                 // Move horizontally into empty space.
                 float widthOffset = 0;
@@ -1578,15 +1580,14 @@
 
                 float gridTranslationX = mIsRtl ? widthOffset : -widthOffset;
                 gridTranslations[i] += gridTranslationX;
-                topAccumulatedTranslationX += gridTranslationX + gridScaleTranslationX;
-                bottomAccumulatedTranslationX += gridScaleTranslationX;
+                topAccumulatedTranslationX += gridTranslationX;
             } else {
                 gridTranslations[i] += bottomAccumulatedTranslationX;
                 bottomRowWidth += taskView.getLayoutParams().width * gridScale + mPageSpacing;
 
                 // Move into bottom row.
                 float heightOffset = (boxLength + mTaskTopMargin) * gridScale + mRowSpacing;
-                taskView.setGridTranslationY(heightOffset);
+                taskView.setGridTranslationY(heightOffset + taskGridVerticalDiff);
 
                 // Move horizontally into empty space.
                 float widthOffset = 0;
@@ -1597,9 +1598,10 @@
 
                 float gridTranslationX = mIsRtl ? widthOffset : -widthOffset;
                 gridTranslations[i] += gridTranslationX;
-                topAccumulatedTranslationX += gridScaleTranslationX;
-                bottomAccumulatedTranslationX += gridTranslationX + gridScaleTranslationX;
+                bottomAccumulatedTranslationX += gridTranslationX;
             }
+            topAccumulatedTranslationX += gridScaleTranslationX;
+            bottomAccumulatedTranslationX += gridScaleTranslationX;
         }
 
         // Use the accumulated translation of the longer row.
@@ -1632,8 +1634,9 @@
                     mIsRtl ? -shortTotalCompensation : shortTotalCompensation;
         }
 
-        float clearAllTotalTranslationX = firstTaskWidthOffset + clearAllAccumulatedTranslation
-                + clearAllShorterRowCompensation + clearAllShortTotalCompensation;
+        float clearAllTotalTranslationX =
+                clearAllAccumulatedTranslation + clearAllShorterRowCompensation
+                        + clearAllShortTotalCompensation;
 
         // We need to maintain first task's grid translation at 0, now shift translation of all
         // the TaskViews to achieve that.
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index 4c21745..36a5f03 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -212,13 +212,6 @@
         return mDimAlpha;
     }
 
-    public Rect getInsets(Rect fallback) {
-        if (mThumbnailData != null) {
-            return mThumbnailData.insets;
-        }
-        return fallback;
-    }
-
     /**
      * Get the scaled insets that are being used to draw the task view. This is a subsection of
      * the full snapshot.
@@ -230,6 +223,10 @@
             return Insets.NONE;
         }
 
+        if (!TaskView.CLIP_STATUS_AND_NAV_BARS) {
+            return Insets.NONE;
+        }
+
         RectF bitmapRect = new RectF(
                 0, 0,
                 mThumbnailData.thumbnail.getWidth(), mThumbnailData.thumbnail.getHeight());
@@ -459,7 +456,6 @@
         // Contains the portion of the thumbnail that is clipped when fullscreen progress = 0.
         private final RectF mClippedInsets = new RectF();
         private final Matrix mMatrix = new Matrix();
-        private float mClipBottom = -1;
         private boolean mIsOrientationChanged;
 
         public Matrix getMatrix() {
@@ -476,7 +472,8 @@
 
             int thumbnailRotation = thumbnailData.rotation;
             int deltaRotate = getRotationDelta(currentRotation, thumbnailRotation);
-            RectF thumbnailClipHint = new RectF(thumbnailData.insets);
+            RectF thumbnailClipHint = TaskView.CLIP_STATUS_AND_NAV_BARS
+                    ? new RectF(thumbnailData.insets) : new RectF();
 
             float scale = thumbnailData.scale;
             final float thumbnailScale;
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 605eb3f..eace0f8 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -121,6 +121,12 @@
      */
     public static final float MAX_PAGE_SCRIM_ALPHA = 0.4f;
 
+    /**
+     * Should the TaskView display clip off the status and navigation bars in recents. When this
+     * is false the overview shows the whole screen scaled down instead.
+     */
+    public static final boolean CLIP_STATUS_AND_NAV_BARS = false;
+
     private static final float EDGE_SCALE_DOWN_FACTOR_CAROUSEL = 0.03f;
     private static final float EDGE_SCALE_DOWN_FACTOR_GRID = 0.00f;
 
@@ -620,12 +626,11 @@
         int thumbnailPadding = (int) getResources().getDimension(R.dimen.task_thumbnail_top_margin);
         int taskIconMargin = (int) getResources().getDimension(R.dimen.task_icon_top_margin);
         int taskIconHeight = (int) getResources().getDimension(R.dimen.task_thumbnail_icon_size);
-        int iconTopMargin = taskIconMargin - taskIconHeight + thumbnailPadding;
         LayoutParams iconParams = (LayoutParams) mIconView.getLayoutParams();
         switch (orientationHandler.getRotation()) {
             case ROTATION_90:
                 iconParams.gravity = (isRtl ? START : END) | CENTER_VERTICAL;
-                iconParams.rightMargin = -thumbnailPadding;
+                iconParams.rightMargin = -taskIconHeight - taskIconMargin / 2;
                 iconParams.leftMargin = 0;
                 iconParams.topMargin = snapshotParams.topMargin / 2;
                 break;
@@ -633,11 +638,11 @@
                 iconParams.gravity = BOTTOM | CENTER_HORIZONTAL;
                 iconParams.bottomMargin = -thumbnailPadding;
                 iconParams.leftMargin = iconParams.rightMargin = 0;
-                iconParams.topMargin = iconTopMargin;
+                iconParams.topMargin = taskIconMargin;
                 break;
             case ROTATION_270:
                 iconParams.gravity = (isRtl ? END : START) | CENTER_VERTICAL;
-                iconParams.leftMargin = -thumbnailPadding;
+                iconParams.leftMargin = -taskIconHeight - taskIconMargin / 2;
                 iconParams.rightMargin = 0;
                 iconParams.topMargin = snapshotParams.topMargin / 2;
                 break;
@@ -645,7 +650,7 @@
             default:
                 iconParams.gravity = TOP | CENTER_HORIZONTAL;
                 iconParams.leftMargin = iconParams.rightMargin = 0;
-                iconParams.topMargin = iconTopMargin;
+                iconParams.topMargin = taskIconMargin;
                 break;
         }
         mIconView.setLayoutParams(iconParams);
@@ -1191,7 +1196,8 @@
 
             int expectedWidth;
             int expectedHeight;
-            float thumbnailRatio = mTask != null ? mTask.getVisibleThumbnailRatio() : 0f;
+            float thumbnailRatio = mTask != null ? mTask.getVisibleThumbnailRatio(
+                    TaskView.CLIP_STATUS_AND_NAV_BARS) : 0f;
             if (isRunningTask() || thumbnailRatio == 0f) {
                 expectedWidth = taskWidth;
                 expectedHeight = taskHeight + thumbnailPadding;