Merge "Set the default for keyboard sync to IS_STUDIO_BUILD." into tm-qpr-dev
diff --git a/protos/view_capture.proto b/protos/view_capture.proto
index 98574dd..349ff36 100644
--- a/protos/view_capture.proto
+++ b/protos/view_capture.proto
@@ -51,4 +51,6 @@
   optional int32 visibility = 16;
 
   repeated ViewNode children = 17;
+
+  optional float elevation = 18;
 }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
index cb1da38..872e64a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
@@ -188,9 +188,6 @@
             AllAppsSwipeController.applyAllAppsToNormalConfig(mActivity, config);
         } else if (fromState == NORMAL && toState == ALL_APPS) {
             AllAppsSwipeController.applyNormalToAllAppsAnimConfig(mActivity, config);
-        } else if (fromState == OVERVIEW && toState == OVERVIEW_SPLIT_SELECT) {
-            config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE,
-                    clampToProgress(LINEAR, 0, 0.167f));
         }
     }
 }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java b/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java
index cb08ac8..e79d56b 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java
@@ -16,8 +16,6 @@
 
 package com.android.launcher3.uioverrides.states;
 
-import android.content.Context;
-
 import com.android.launcher3.Launcher;
 import com.android.quickstep.views.RecentsView;
 
@@ -26,8 +24,6 @@
  * pinned and user is selecting the second one
  */
 public class SplitScreenSelectState extends OverviewState {
-    private static final int OVERVIEW_SPLIT_SELECT_SLIDE_IN_DURATION = 500;
-
     public SplitScreenSelectState(int id) {
         super(id);
     }
@@ -42,9 +38,4 @@
         RecentsView recentsView = launcher.getOverviewPanel();
         return recentsView.getSplitSelectTranslation();
     }
-
-    @Override
-    public int getTransitionDuration(Context context, boolean isToState) {
-        return OVERVIEW_SPLIT_SELECT_SLIDE_IN_DURATION;
-    }
 }
diff --git a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
index 69a295b..a0860ee 100644
--- a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
@@ -26,6 +26,7 @@
 import android.graphics.Rect;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.SystemProperties;
 import android.view.View;
 import android.view.WindowInsets;
 import android.window.SplashScreen;
@@ -278,7 +279,8 @@
         }
 
         private boolean isAvailable(BaseDraggingActivity activity, int displayId) {
-            return ActivityManagerWrapper.getInstance().supportsFreeformMultiWindow(activity);
+            return ActivityManagerWrapper.getInstance().supportsFreeformMultiWindow(activity)
+                    && !SystemProperties.getBoolean("persist.wm.debug.desktop_mode", false);
         }
     };
 
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index 3bd72fe..a809c9c 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -593,6 +593,15 @@
         Animator launcherAnim;
         final AnimatorListenerAdapter windowAnimEndListener;
         if (launcherClosing) {
+            // Since Overview is in launcher, just opening overview sets willFinishToHome to true.
+            // Now that we are closing the launcher, we need to (re)set willFinishToHome back to
+            // false. Otherwise, RecentsAnimationController can't differentiate between closing
+            // overview to 3p home vs closing overview to app.
+            final RecentsAnimationController raController =
+                    recentsView.getRecentsAnimationController();
+            if (raController != null) {
+                raController.setWillFinishToHome(false);
+            }
             Context context = v.getContext();
             DeviceProfile dp = BaseActivity.fromContext(context).getDeviceProfile();
             launcherAnim = dp.isTablet
diff --git a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
index d93f015..7a66ea0 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
@@ -2,9 +2,8 @@
 
 import static com.android.launcher3.AbstractFloatingView.TYPE_TASK_MENU;
 import static com.android.launcher3.anim.Interpolators.ACCEL;
-import static com.android.launcher3.anim.Interpolators.FASTER_OUT_SLOWER_IN;
+import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
-import static com.android.launcher3.anim.Interpolators.clampToProgress;
 
 import android.animation.ValueAnimator;
 import android.content.Context;
@@ -201,16 +200,10 @@
         RectF floatingTaskViewBounds = new RectF();
 
         if (fadeWithThumbnail) {
-            // FloatingTaskThumbnailView: thumbnail fades out to transparent
-            animation.addFloat(mThumbnailView, LauncherAnimUtils.VIEW_ALPHA,
-                    1, 0, clampToProgress(LINEAR, 0, 0.267f));
-
-            // SplitPlaceholderView: gray background fades in at the same time, then new icon fades
-            // in
             animation.addFloat(mSplitPlaceholderView, SplitPlaceholderView.ALPHA_FLOAT,
-                    0, 1, clampToProgress(LINEAR, 0, 0.267f));
-            animation.addFloat(mSplitPlaceholderView, SplitPlaceholderView.ICON_ALPHA,
-                    0, 1, clampToProgress(LINEAR, 0.333f, 0.5f));
+                    0, 1, ACCEL);
+            animation.addFloat(mThumbnailView, LauncherAnimUtils.VIEW_ALPHA,
+                    1, 0, DEACCEL_3);
         } else if (isStagedTask) {
             // Fade in the placeholder view when split is initiated from homescreen / all apps
             // icons.
@@ -221,15 +214,12 @@
         }
 
         MultiValueUpdateListener listener = new MultiValueUpdateListener() {
-            // SplitPlaceholderView: rectangle translates and stretches to new position
-            final FloatProp mDx = new FloatProp(0, prop.dX, 0, animDuration,
-                    clampToProgress(FASTER_OUT_SLOWER_IN, 0, 0.833f));
-            final FloatProp mDy = new FloatProp(0, prop.dY, 0, animDuration,
-                    clampToProgress(FASTER_OUT_SLOWER_IN, 0, 0.833f));
+            final FloatProp mDx = new FloatProp(0, prop.dX, 0, animDuration, LINEAR);
+            final FloatProp mDy = new FloatProp(0, prop.dY, 0, animDuration, LINEAR);
             final FloatProp mTaskViewScaleX = new FloatProp(1f, prop.finalTaskViewScaleX, 0,
-                    animDuration, clampToProgress(FASTER_OUT_SLOWER_IN, 0, 0.833f));
+                    animDuration, LINEAR);
             final FloatProp mTaskViewScaleY = new FloatProp(1f, prop.finalTaskViewScaleY, 0,
-                    animDuration, clampToProgress(FASTER_OUT_SLOWER_IN, 0, 0.833f));
+                    animDuration, LINEAR);
             @Override
             public void onUpdate(float percent, boolean initOnly) {
                 // Calculate the icon position.
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index a153f26..64068ad 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -35,7 +35,6 @@
 import static com.android.launcher3.anim.Interpolators.ACCEL_0_75;
 import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
 import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
-import static com.android.launcher3.anim.Interpolators.EMPHASIZED_DECELERATE;
 import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
 import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
@@ -114,7 +113,6 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.UiThread;
 import androidx.core.graphics.ColorUtils;
-import androidx.dynamicanimation.animation.SpringForce;
 
 import com.android.launcher3.BaseActivity;
 import com.android.launcher3.BaseActivity.MultiWindowModeChangedListener;
@@ -127,7 +125,6 @@
 import com.android.launcher3.anim.AnimatorListeners;
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.anim.PendingAnimation;
-import com.android.launcher3.anim.SpringAnimationBuilder;
 import com.android.launcher3.anim.SpringProperty;
 import com.android.launcher3.compat.AccessibilityManagerCompat;
 import com.android.launcher3.config.FeatureFlags;
@@ -445,9 +442,6 @@
     private static final float ANIMATION_DISMISS_PROGRESS_MIDPOINT = 0.5f;
     private static final float END_DISMISS_TRANSLATION_INTERPOLATION_OFFSET = 0.75f;
 
-    private static final float INITIAL_SPRING_DISMISS_TRANSLATION_INTERPOLATION_OFFSET = 0.133f;
-    private static final float ADDITIONAL_SPRING_DISMISS_TRANSLATION_INTERPOLATION_OFFSET = 0.033f;
-
     private static final float SIGNIFICANT_MOVE_SCREEN_WIDTH_PERCENTAGE = 0.15f;
 
     protected final RecentsOrientedState mOrientationState;
@@ -2831,20 +2825,7 @@
 
         RectF startingTaskRect = new RectF();
         if (mSplitHiddenTaskView != null) {
-            // Split staging is initiated, hide the original TaskView except for the icon (which
-            // needs to animate out over time)
-            // If needed, visibility should be toggled back on in resetFromSplitSelectionState().
-            for (int i = 0; i < mSplitHiddenTaskView.getChildCount(); i++) {
-                View child = mSplitHiddenTaskView.getChildAt(i);
-                if (child != mSplitHiddenTaskView.mIconView) {
-                    child.setVisibility(INVISIBLE);
-                }
-            }
-
-            // Icon animates out over time
-            anim.addFloat(mSplitHiddenTaskView, TaskView.ICON_ALPHA, 1, 0,
-                    clampToProgress(LINEAR, 0, 0.167f));
-
+            mSplitHiddenTaskView.setVisibility(INVISIBLE);
             mFirstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
                     mSplitHiddenTaskView.getThumbnail(),
                     mSplitHiddenTaskView.getThumbnail().getThumbnail(),
@@ -2861,15 +2842,9 @@
                     false /* fadeWithThumbnail */, true /* isStagedTask */);
         }
 
-        // SplitInstructionsView: animate in
         mSplitInstructionsView = SplitInstructionsView.getSplitInstructionsView(mActivity);
         mSplitInstructionsView.setAlpha(0);
-        anim.addFloat(mSplitInstructionsView, SplitInstructionsView.CONTAINER_ALPHA, 0, 1,
-                clampToProgress(LINEAR, 0, 0.167f));
-        anim.addFloat(mSplitInstructionsView, SplitInstructionsView.TEXT_ALPHA, 0, 1,
-                clampToProgress(LINEAR, 0.1f, 0.267f));
-        anim.addFloat(mSplitInstructionsView, mSplitInstructionsView.UNFOLD, 0.1f, 1,
-                clampToProgress(EMPHASIZED_DECELERATE, 0, 0.667f));
+        anim.addFloat(mSplitInstructionsView, SplitInstructionsView.ALPHA_FLOAT, 0, 1, ACCEL);
 
         InteractionJankMonitorWrapper.begin(this,
                 InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER, "First tile selected");
@@ -3149,22 +3124,11 @@
                 // Animate task with index >= dismissed index and in the same row as the
                 // dismissed index or next focused index. Offset successive task dismissal
                 // durations for a staggered effect.
-                distanceFromDismissedTask++;
-                // If user is initiating splitscreen from the focused (large) task, we use a
-                // spring-based animation and timings. For other, smaller, repositions, we currently
-                // fall back on a less complicated linear animation and timings.
-                float animationStartProgress = isFocusedTaskDismissed && nextFocusedTaskView == null
-                        ? Utilities.boundToRange(
-                                INITIAL_SPRING_DISMISS_TRANSLATION_INTERPOLATION_OFFSET
-                                        + ADDITIONAL_SPRING_DISMISS_TRANSLATION_INTERPOLATION_OFFSET
-                                        * (int) Math.ceil(distanceFromDismissedTask / 2f), 0f,
-                        dismissTranslationInterpolationEnd)
-                        : Utilities.boundToRange(
-                                INITIAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET
-                                        + ADDITIONAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET
-                                        * distanceFromDismissedTask, 0f,
-                                dismissTranslationInterpolationEnd);
-
+                float animationStartProgress = Utilities.boundToRange(
+                        INITIAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET
+                                + ADDITIONAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET
+                                * ++distanceFromDismissedTask, 0f,
+                        dismissTranslationInterpolationEnd);
                 if (taskView == nextFocusedTaskView) {
                     // Enlarge the task to be focused next, and translate into focus position.
                     float scale = mTaskWidth / (float) mLastComputedGridTaskSize.width();
@@ -3199,36 +3163,12 @@
                             primaryTranslation +=
                                     mIsRtl ? -mSplitPlaceholderSize : mSplitPlaceholderSize;
                         }
-
-                        // Transitioning to split select -- set up staggered spring animation for
-                        // other TaskViews.
-                        Animator taskSlideIn = new SpringAnimationBuilder(taskView.mActivity)
-                                .setDampingRatio(0.85f)
-                                .setStiffness(SpringForce.STIFFNESS_LOW)
-                                .setEndValue(mIsRtl ? primaryTranslation : -primaryTranslation)
-                                .setStartValue(
-                                        taskView.getPrimaryDismissTranslationProperty()
-                                                .get(taskView)
-                                )
-                                .build(taskView, taskView.getPrimaryDismissTranslationProperty());
-                        long taskSlideInDuration = taskSlideIn.getDuration();
-                        anim.add(taskSlideIn);
-                        taskSlideIn
-                                .setDuration(taskSlideInDuration)
-                                .setStartDelay(
-                                        Math.round(animationStartProgress * anim.getDuration()));
-                    } else {
-                        // Task was dismissed individually -- translate other TaskViews to fill the
-                        // vacant space.
-
-                        // TODO (b/242075836): This dismiss animation uses a linear transition.
-                        // When the above bug is fixed, it can use the same (nicer) spring
-                        // transition as the focused task split case above.
-                        anim.setFloat(taskView, taskView.getPrimaryDismissTranslationProperty(),
-                                mIsRtl ? primaryTranslation : -primaryTranslation,
-                                clampToProgress(LINEAR, animationStartProgress,
-                                        dismissTranslationInterpolationEnd));
                     }
+
+                    anim.setFloat(taskView, taskView.getPrimaryDismissTranslationProperty(),
+                            mIsRtl ? primaryTranslation : -primaryTranslation,
+                            clampToProgress(LINEAR, animationStartProgress,
+                                    dismissTranslationInterpolationEnd));
                 }
             }
         }
@@ -3249,8 +3189,7 @@
         final boolean finalCloseGapBetweenClearAll = closeGapBetweenClearAll;
         final boolean finalSnapToLastTask = snapToLastTask;
         final boolean finalIsFocusedTaskDismissed = isFocusedTaskDismissed;
-
-        Consumer endConsumer = new Consumer<Boolean>() {
+        mPendingAnimation.addEndListener(new Consumer<Boolean>() {
             @Override
             public void accept(Boolean success) {
                 if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mEnableDrawingLiveTile
@@ -3460,9 +3399,7 @@
                 onDismissAnimationEnds();
                 mPendingAnimation = null;
             }
-        };
-
-        mPendingAnimation.addListener(AnimatorListeners.forEndCallback(endConsumer));
+        });
         return anim;
     }
 
@@ -4283,6 +4220,7 @@
         resetTaskVisuals();
         mSplitHiddenTaskViewIndex = -1;
         if (mSplitHiddenTaskView != null) {
+            mSplitHiddenTaskView.setVisibility(VISIBLE);
             mSplitHiddenTaskView = null;
         }
     }
diff --git a/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java b/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java
index d0d715f..7d94505 100644
--- a/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java
+++ b/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java
@@ -25,7 +25,6 @@
 import android.widget.FrameLayout;
 
 import androidx.annotation.Nullable;
-import androidx.appcompat.widget.AppCompatTextView;
 
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
@@ -41,10 +40,9 @@
  */
 public class SplitInstructionsView extends FrameLayout {
     private final StatefulActivity mLauncher;
-    private AppCompatTextView mTextView;
 
-    public static final FloatProperty<SplitInstructionsView> CONTAINER_ALPHA =
-            new FloatProperty<SplitInstructionsView>("SplitInstructionsContainerAlpha") {
+    public static final FloatProperty<SplitInstructionsView> ALPHA_FLOAT =
+            new FloatProperty<SplitInstructionsView>("SplitInstructionsAlpha") {
                 @Override
                 public void setValue(SplitInstructionsView splitInstructionsView, float v) {
                     splitInstructionsView.setVisibility(v != 0 ? VISIBLE : GONE);
@@ -57,32 +55,6 @@
                 }
             };
 
-    public static final FloatProperty<SplitInstructionsView> UNFOLD =
-            new FloatProperty<SplitInstructionsView>("SplitInstructionsUnfold") {
-                @Override
-                public void setValue(SplitInstructionsView splitInstructionsView, float v) {
-                    splitInstructionsView.setScaleY(v);
-                }
-
-                @Override
-                public Float get(SplitInstructionsView splitInstructionsView) {
-                    return splitInstructionsView.getScaleY();
-                }
-            };
-
-    public static final FloatProperty<SplitInstructionsView> TEXT_ALPHA =
-            new FloatProperty<SplitInstructionsView>("SplitInstructionsTextAlpha") {
-                @Override
-                public void setValue(SplitInstructionsView splitInstructionsView, float v) {
-                    splitInstructionsView.mTextView.setAlpha(v);
-                }
-
-                @Override
-                public Float get(SplitInstructionsView splitInstructionsView) {
-                    return splitInstructionsView.mTextView.getAlpha();
-                }
-            };
-
     public SplitInstructionsView(Context context) {
         this(context, null);
     }
@@ -105,9 +77,6 @@
                         false
                 );
 
-        splitInstructionsView.mTextView = splitInstructionsView.findViewById(
-                R.id.split_instructions_text);
-
         dragLayer.addView(splitInstructionsView);
         return splitInstructionsView;
     }
diff --git a/quickstep/src/com/android/quickstep/views/SplitPlaceholderView.java b/quickstep/src/com/android/quickstep/views/SplitPlaceholderView.java
index ae6aae1..28080d4 100644
--- a/quickstep/src/com/android/quickstep/views/SplitPlaceholderView.java
+++ b/quickstep/src/com/android/quickstep/views/SplitPlaceholderView.java
@@ -47,19 +47,6 @@
                 }
             };
 
-    public static final FloatProperty<SplitPlaceholderView> ICON_ALPHA =
-            new FloatProperty<SplitPlaceholderView>("SplitViewIconAlpha") {
-                @Override
-                public void setValue(SplitPlaceholderView splitPlaceholderView, float v) {
-                    splitPlaceholderView.mIconView.setAlpha(v);
-                }
-
-                @Override
-                public Float get(SplitPlaceholderView splitPlaceholderView) {
-                    return splitPlaceholderView.mIconView.getAlpha();
-                }
-            };
-
     @Nullable
     private IconView mIconView;
 
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index d2c2988..b089155 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -323,19 +323,6 @@
                 }
             };
 
-    public static final FloatProperty<TaskView> ICON_ALPHA =
-            new FloatProperty<TaskView>("iconAlpha") {
-                @Override
-                public void setValue(TaskView taskView, float v) {
-                    taskView.mIconView.setAlpha(v);
-                }
-
-                @Override
-                public Float get(TaskView taskView) {
-                    return taskView.mIconView.getAlpha();
-                }
-            };
-
     @Nullable
     protected Task mTask;
     protected TaskThumbnailView mSnapshotView;
diff --git a/quickstep/tests/src/com/android/quickstep/DeviceProfileTest.kt b/quickstep/tests/src/com/android/quickstep/DeviceProfileTest.kt
index 45a342a..9977207 100644
--- a/quickstep/tests/src/com/android/quickstep/DeviceProfileTest.kt
+++ b/quickstep/tests/src/com/android/quickstep/DeviceProfileTest.kt
@@ -73,13 +73,14 @@
                 "\ticonTextSizePx: 36.0px (13.714286dp)\n" +
                 "\ticonDrawablePaddingPx: 17.0px (6.4761906dp)\n" +
                 "\tfolderCellWidthPx: 210.0px (80.0dp)\n" +
-                "\tfolderCellHeightPx: 272.0px (103.61905dp)\n" +
+                "\tfolderCellHeightPx: 247.0px (94.09524dp)\n" +
                 "\tfolderChildIconSizePx: 158.0px (60.190475dp)\n" +
                 "\tfolderChildTextSizePx: 37.0px (14.095238dp)\n" +
-                "\tfolderChildDrawablePaddingPx: 21.0px (8.0dp)\n" +
-                "\tfolderCellLayoutBorderSpaceOriginalPx: 42.0px (16.0dp)\n" +
+                "\tfolderChildDrawablePaddingPx: 13.0px (4.952381dp)\n" +
                 "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
                 "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
+                "\tfolderContentPaddingLeftRight: 42.0px (16.0dp)\n" +
+                "\tfolderTopPadding: 63.0px (24.0dp)\n" +
                 "\tbottomSheetTopPadding: 146.0px (55.61905dp)\n" +
                 "\tallAppsShiftRange: 788.0px (300.1905dp)\n" +
                 "\tallAppsTopPadding: 0.0px (0.0dp)\n" +
@@ -192,13 +193,14 @@
                 "\ticonTextSizePx: 36.0px (13.714286dp)\n" +
                 "\ticonDrawablePaddingPx: 17.0px (6.4761906dp)\n" +
                 "\tfolderCellWidthPx: 210.0px (80.0dp)\n" +
-                "\tfolderCellHeightPx: 272.0px (103.61905dp)\n" +
+                "\tfolderCellHeightPx: 247.0px (94.09524dp)\n" +
                 "\tfolderChildIconSizePx: 158.0px (60.190475dp)\n" +
                 "\tfolderChildTextSizePx: 37.0px (14.095238dp)\n" +
-                "\tfolderChildDrawablePaddingPx: 21.0px (8.0dp)\n" +
-                "\tfolderCellLayoutBorderSpaceOriginalPx: 42.0px (16.0dp)\n" +
+                "\tfolderChildDrawablePaddingPx: 13.0px (4.952381dp)\n" +
                 "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
                 "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
+                "\tfolderContentPaddingLeftRight: 42.0px (16.0dp)\n" +
+                "\tfolderTopPadding: 63.0px (24.0dp)\n" +
                 "\tbottomSheetTopPadding: 146.0px (55.61905dp)\n" +
                 "\tallAppsShiftRange: 788.0px (300.1905dp)\n" +
                 "\tallAppsTopPadding: 0.0px (0.0dp)\n" +
@@ -316,9 +318,10 @@
                 "\tfolderChildIconSizePx: 120.0px (60.0dp)\n" +
                 "\tfolderChildTextSizePx: 28.0px (14.0dp)\n" +
                 "\tfolderChildDrawablePaddingPx: 16.0px (8.0dp)\n" +
-                "\tfolderCellLayoutBorderSpaceOriginalPx: 0.0px (0.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
+                "\tfolderCellLayoutBorderSpacePx Horizontal: 32.0px (16.0dp)\n" +
+                "\tfolderCellLayoutBorderSpacePx Vertical: 32.0px (16.0dp)\n" +
+                "\tfolderContentPaddingLeftRight: 32.0px (16.0dp)\n" +
+                "\tfolderTopPadding: 48.0px (24.0dp)\n" +
                 "\tbottomSheetTopPadding: 104.0px (52.0dp)\n" +
                 "\tallAppsShiftRange: 1496.0px (748.0dp)\n" +
                 "\tallAppsTopPadding: 104.0px (52.0dp)\n" +
@@ -436,9 +439,10 @@
                 "\tfolderChildIconSizePx: 120.0px (60.0dp)\n" +
                 "\tfolderChildTextSizePx: 28.0px (14.0dp)\n" +
                 "\tfolderChildDrawablePaddingPx: 16.0px (8.0dp)\n" +
-                "\tfolderCellLayoutBorderSpaceOriginalPx: 0.0px (0.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
+                "\tfolderCellLayoutBorderSpacePx Horizontal: 32.0px (16.0dp)\n" +
+                "\tfolderCellLayoutBorderSpacePx Vertical: 32.0px (16.0dp)\n" +
+                "\tfolderContentPaddingLeftRight: 32.0px (16.0dp)\n" +
+                "\tfolderTopPadding: 48.0px (24.0dp)\n" +
                 "\tbottomSheetTopPadding: 104.0px (52.0dp)\n" +
                 "\tallAppsShiftRange: 1496.0px (748.0dp)\n" +
                 "\tallAppsTopPadding: 104.0px (52.0dp)\n" +
@@ -551,14 +555,15 @@
                 "\ticonSizePx: 120.0px (60.0dp)\n" +
                 "\ticonTextSizePx: 28.0px (14.0dp)\n" +
                 "\ticonDrawablePaddingPx: 14.0px (7.0dp)\n" +
-                "\tfolderCellWidthPx: 204.0px (102.0dp)\n" +
-                "\tfolderCellHeightPx: 240.0px (120.0dp)\n" +
+                "\tfolderCellWidthPx: 240.0px (120.0dp)\n" +
+                "\tfolderCellHeightPx: 208.0px (104.0dp)\n" +
                 "\tfolderChildIconSizePx: 120.0px (60.0dp)\n" +
                 "\tfolderChildTextSizePx: 28.0px (14.0dp)\n" +
-                "\tfolderChildDrawablePaddingPx: 27.0px (13.5dp)\n" +
-                "\tfolderCellLayoutBorderSpaceOriginalPx: 0.0px (0.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
+                "\tfolderChildDrawablePaddingPx: 16.0px (8.0dp)\n" +
+                "\tfolderCellLayoutBorderSpacePx Horizontal: 32.0px (16.0dp)\n" +
+                "\tfolderCellLayoutBorderSpacePx Vertical: 32.0px (16.0dp)\n" +
+                "\tfolderContentPaddingLeftRight: 32.0px (16.0dp)\n" +
+                "\tfolderTopPadding: 48.0px (24.0dp)\n" +
                 "\tbottomSheetTopPadding: 704.0px (352.0dp)\n" +
                 "\tallAppsShiftRange: 1936.0px (968.0dp)\n" +
                 "\tallAppsTopPadding: 624.0px (312.0dp)\n" +
@@ -671,14 +676,15 @@
                 "\ticonSizePx: 120.0px (60.0dp)\n" +
                 "\ticonTextSizePx: 28.0px (14.0dp)\n" +
                 "\ticonDrawablePaddingPx: 14.0px (7.0dp)\n" +
-                "\tfolderCellWidthPx: 204.0px (102.0dp)\n" +
-                "\tfolderCellHeightPx: 240.0px (120.0dp)\n" +
+                "\tfolderCellWidthPx: 240.0px (120.0dp)\n" +
+                "\tfolderCellHeightPx: 208.0px (104.0dp)\n" +
                 "\tfolderChildIconSizePx: 120.0px (60.0dp)\n" +
                 "\tfolderChildTextSizePx: 28.0px (14.0dp)\n" +
-                "\tfolderChildDrawablePaddingPx: 27.0px (13.5dp)\n" +
-                "\tfolderCellLayoutBorderSpaceOriginalPx: 0.0px (0.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
+                "\tfolderChildDrawablePaddingPx: 16.0px (8.0dp)\n" +
+                "\tfolderCellLayoutBorderSpacePx Horizontal: 32.0px (16.0dp)\n" +
+                "\tfolderCellLayoutBorderSpacePx Vertical: 32.0px (16.0dp)\n" +
+                "\tfolderContentPaddingLeftRight: 32.0px (16.0dp)\n" +
+                "\tfolderTopPadding: 48.0px (24.0dp)\n" +
                 "\tbottomSheetTopPadding: 704.0px (352.0dp)\n" +
                 "\tallAppsShiftRange: 1936.0px (968.0dp)\n" +
                 "\tallAppsTopPadding: 624.0px (312.0dp)\n" +
@@ -792,13 +798,14 @@
                 "\ticonTextSizePx: 36.0px (13.714286dp)\n" +
                 "\ticonDrawablePaddingPx: 17.0px (6.4761906dp)\n" +
                 "\tfolderCellWidthPx: 210.0px (80.0dp)\n" +
-                "\tfolderCellHeightPx: 267.0px (101.71429dp)\n" +
+                "\tfolderCellHeightPx: 247.0px (94.09524dp)\n" +
                 "\tfolderChildIconSizePx: 158.0px (60.190475dp)\n" +
                 "\tfolderChildTextSizePx: 37.0px (14.095238dp)\n" +
-                "\tfolderChildDrawablePaddingPx: 19.0px (7.2380953dp)\n" +
-                "\tfolderCellLayoutBorderSpaceOriginalPx: 42.0px (16.0dp)\n" +
+                "\tfolderChildDrawablePaddingPx: 13.0px (4.952381dp)\n" +
                 "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
                 "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
+                "\tfolderContentPaddingLeftRight: 42.0px (16.0dp)\n" +
+                "\tfolderTopPadding: 63.0px (24.0dp)\n" +
                 "\tbottomSheetTopPadding: 110.0px (41.904762dp)\n" +
                 "\tallAppsShiftRange: 1730.0px (659.0476dp)\n" +
                 "\tallAppsTopPadding: 110.0px (41.904762dp)\n" +
@@ -912,13 +919,14 @@
                 "\ticonTextSizePx: 36.0px (13.714286dp)\n" +
                 "\ticonDrawablePaddingPx: 17.0px (6.4761906dp)\n" +
                 "\tfolderCellWidthPx: 210.0px (80.0dp)\n" +
-                "\tfolderCellHeightPx: 267.0px (101.71429dp)\n" +
+                "\tfolderCellHeightPx: 247.0px (94.09524dp)\n" +
                 "\tfolderChildIconSizePx: 158.0px (60.190475dp)\n" +
                 "\tfolderChildTextSizePx: 37.0px (14.095238dp)\n" +
-                "\tfolderChildDrawablePaddingPx: 19.0px (7.2380953dp)\n" +
-                "\tfolderCellLayoutBorderSpaceOriginalPx: 42.0px (16.0dp)\n" +
+                "\tfolderChildDrawablePaddingPx: 13.0px (4.952381dp)\n" +
                 "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
                 "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
+                "\tfolderContentPaddingLeftRight: 42.0px (16.0dp)\n" +
+                "\tfolderTopPadding: 63.0px (24.0dp)\n" +
                 "\tbottomSheetTopPadding: 110.0px (41.904762dp)\n" +
                 "\tallAppsShiftRange: 1730.0px (659.0476dp)\n" +
                 "\tallAppsTopPadding: 110.0px (41.904762dp)\n" +
@@ -1031,14 +1039,15 @@
                 "\ticonSizePx: 136.0px (51.809525dp)\n" +
                 "\ticonTextSizePx: 31.0px (11.809524dp)\n" +
                 "\ticonDrawablePaddingPx: 17.0px (6.4761906dp)\n" +
-                "\tfolderCellWidthPx: 192.0px (73.14286dp)\n" +
-                "\tfolderCellHeightPx: 304.0px (115.809525dp)\n" +
+                "\tfolderCellWidthPx: 210.0px (80.0dp)\n" +
+                "\tfolderCellHeightPx: 247.0px (94.09524dp)\n" +
                 "\tfolderChildIconSizePx: 158.0px (60.190475dp)\n" +
                 "\tfolderChildTextSizePx: 37.0px (14.095238dp)\n" +
-                "\tfolderChildDrawablePaddingPx: 32.0px (12.190476dp)\n" +
-                "\tfolderCellLayoutBorderSpaceOriginalPx: 42.0px (16.0dp)\n" +
+                "\tfolderChildDrawablePaddingPx: 13.0px (4.952381dp)\n" +
                 "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
                 "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
+                "\tfolderContentPaddingLeftRight: 42.0px (16.0dp)\n" +
+                "\tfolderTopPadding: 63.0px (24.0dp)\n" +
                 "\tbottomSheetTopPadding: 110.0px (41.904762dp)\n" +
                 "\tallAppsShiftRange: 2098.0px (799.2381dp)\n" +
                 "\tallAppsTopPadding: 110.0px (41.904762dp)\n" +
@@ -1151,14 +1160,15 @@
                 "\ticonSizePx: 136.0px (51.809525dp)\n" +
                 "\ticonTextSizePx: 31.0px (11.809524dp)\n" +
                 "\ticonDrawablePaddingPx: 17.0px (6.4761906dp)\n" +
-                "\tfolderCellWidthPx: 192.0px (73.14286dp)\n" +
-                "\tfolderCellHeightPx: 304.0px (115.809525dp)\n" +
+                "\tfolderCellWidthPx: 210.0px (80.0dp)\n" +
+                "\tfolderCellHeightPx: 247.0px (94.09524dp)\n" +
                 "\tfolderChildIconSizePx: 158.0px (60.190475dp)\n" +
                 "\tfolderChildTextSizePx: 37.0px (14.095238dp)\n" +
-                "\tfolderChildDrawablePaddingPx: 32.0px (12.190476dp)\n" +
-                "\tfolderCellLayoutBorderSpaceOriginalPx: 42.0px (16.0dp)\n" +
+                "\tfolderChildDrawablePaddingPx: 13.0px (4.952381dp)\n" +
                 "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
                 "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
+                "\tfolderContentPaddingLeftRight: 42.0px (16.0dp)\n" +
+                "\tfolderTopPadding: 63.0px (24.0dp)\n" +
                 "\tbottomSheetTopPadding: 110.0px (41.904762dp)\n" +
                 "\tallAppsShiftRange: 2098.0px (799.2381dp)\n" +
                 "\tallAppsTopPadding: 110.0px (41.904762dp)\n" +
@@ -1270,14 +1280,15 @@
                 "\ticonSizePx: 142.0px (54.095238dp)\n" +
                 "\ticonTextSizePx: 0.0px (0.0dp)\n" +
                 "\ticonDrawablePaddingPx: 0.0px (0.0dp)\n" +
-                "\tfolderCellWidthPx: 179.0px (68.190475dp)\n" +
-                "\tfolderCellHeightPx: 212.0px (80.7619dp)\n" +
-                "\tfolderChildIconSizePx: 135.0px (51.42857dp)\n" +
-                "\tfolderChildTextSizePx: 35.0px (13.333333dp)\n" +
-                "\tfolderChildDrawablePaddingPx: 10.0px (3.8095238dp)\n" +
-                "\tfolderCellLayoutBorderSpaceOriginalPx: 42.0px (16.0dp)\n" +
+                "\tfolderCellWidthPx: 175.0px (66.666664dp)\n" +
+                "\tfolderCellHeightPx: 205.0px (78.09524dp)\n" +
+                "\tfolderChildIconSizePx: 131.0px (49.904762dp)\n" +
+                "\tfolderChildTextSizePx: 34.0px (12.952381dp)\n" +
+                "\tfolderChildDrawablePaddingPx: 9.0px (3.4285715dp)\n" +
                 "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
                 "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
+                "\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
+                "\tfolderTopPadding: 42.0px (16.0dp)\n" +
                 "\tbottomSheetTopPadding: 114.0px (43.42857dp)\n" +
                 "\tallAppsShiftRange: 788.0px (300.1905dp)\n" +
                 "\tallAppsTopPadding: 0.0px (0.0dp)\n" +
@@ -1389,14 +1400,15 @@
                 "\ticonSizePx: 142.0px (54.095238dp)\n" +
                 "\ticonTextSizePx: 0.0px (0.0dp)\n" +
                 "\ticonDrawablePaddingPx: 0.0px (0.0dp)\n" +
-                "\tfolderCellWidthPx: 163.0px (62.095238dp)\n" +
-                "\tfolderCellHeightPx: 192.0px (73.14286dp)\n" +
-                "\tfolderChildIconSizePx: 123.0px (46.857143dp)\n" +
-                "\tfolderChildTextSizePx: 32.0px (12.190476dp)\n" +
+                "\tfolderCellWidthPx: 159.0px (60.57143dp)\n" +
+                "\tfolderCellHeightPx: 187.0px (71.2381dp)\n" +
+                "\tfolderChildIconSizePx: 119.0px (45.333332dp)\n" +
+                "\tfolderChildTextSizePx: 31.0px (11.809524dp)\n" +
                 "\tfolderChildDrawablePaddingPx: 8.0px (3.047619dp)\n" +
-                "\tfolderCellLayoutBorderSpaceOriginalPx: 42.0px (16.0dp)\n" +
                 "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
                 "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
+                "\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
+                "\tfolderTopPadding: 42.0px (16.0dp)\n" +
                 "\tbottomSheetTopPadding: 114.0px (43.42857dp)\n" +
                 "\tallAppsShiftRange: 788.0px (300.1905dp)\n" +
                 "\tallAppsTopPadding: 0.0px (0.0dp)\n" +
diff --git a/res/layout/user_folder_icon_normalized.xml b/res/layout/user_folder_icon_normalized.xml
index 11eea60..337014a 100644
--- a/res/layout/user_folder_icon_normalized.xml
+++ b/res/layout/user_folder_icon_normalized.xml
@@ -30,7 +30,7 @@
     <LinearLayout
         android:id="@+id/folder_footer"
         android:layout_width="match_parent"
-        android:layout_height="48dp"
+        android:layout_height="@dimen/folder_label_height"
         android:clipChildren="false"
         android:orientation="horizontal"
         android:paddingLeft="12dp"
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index df1ca14..8623414 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -184,7 +184,7 @@
         <attr name="isScalable" format="boolean" />
         <attr name="devicePaddingId" format="reference" />
         <!-- By default all categories are enabled -->
-        <attr name="deviceCategory" format="integer" >
+        <attr name="deviceCategory" format="integer">
             <!-- Enable on phone only -->
             <flag name="phone" value="1" />
             <!-- Enable on tablets only -->
@@ -193,6 +193,18 @@
             <flag name="multi_display" value="4" />
         </attr>
 
+        <!-- By default all are false -->
+        <attr name="inlineQsb" format="integer">
+            <!-- Enable on landscape only -->
+            <flag name="portrait" value="1" />
+            <!-- Enable on portrait only -->
+            <flag name="landscape" value="2" />
+            <!-- Enable on two panel portrait only -->
+            <flag name="twoPanelPortrait" value="4" />
+            <!-- Enable on two panel landscape only -->
+            <flag name="twoPanelLandscape" value="8" />
+        </attr>
+
     </declare-styleable>
 
     <declare-styleable name="DevicePadding">
@@ -327,6 +339,19 @@
         if not specified -->
         <attr name="allAppsBorderSpaceTwoPanelLandscapeVertical" format="float" />
 
+        <!-- defaults to minCellHeight if not specified
+        when GridDisplayOption#isScalable is true. -->
+        <attr name="folderCellHeight" format="float" />
+        <!-- defaults to minCellWidth, if not specified -->
+        <attr name="folderCellWidth" format="float" />
+
+        <!-- defaults to borderSpace, if not specified -->
+        <!-- space to be used horizontally and vertically -->
+        <attr name="folderBorderSpace" format="float" />
+
+        <!-- defaults to folderBorderSpace vertical, if not specified -->
+        <attr name="folderTopPadding" format="float" />
+
         <!-- defaults to res.hotseat_bar_bottom_space_default, if not specified -->
         <attr name="hotseatBarBottomSpace" format="float" />
         <!-- defaults to hotseatBarBottomSpace, if not specified -->
@@ -373,17 +398,6 @@
         <!-- defaults to horizontalMargin if not specified -->
         <attr name="horizontalMarginTwoPanelPortrait" format="float"/>
 
-        <!-- By default all are false -->
-        <attr name="inlineQsb" format="integer" >
-            <!-- Enable on landscape only -->
-            <flag name="portrait" value="1" />
-            <!-- Enable on portrait only -->
-            <flag name="landscape" value="2" />
-            <!-- Enable on two panel portrait only -->
-            <flag name="twoPanelPortrait" value="4" />
-            <!-- Enable on two panel landscape only -->
-            <flag name="twoPanelLandscape" value="8" />
-        </attr>
     </declare-styleable>
 
     <declare-styleable name="CellLayout">
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 546ee35..a9d1127 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -251,7 +251,7 @@
     <dimen name="folder_cell_y_padding">6dp</dimen>
     <!-- label text size = workspace text size multiplied by this scale -->
     <dimen name="folder_label_text_scale">1.14</dimen>
-    <dimen name="folder_label_height">48dp</dimen>
+    <dimen name="folder_label_height">56dp</dimen>
 
     <dimen name="folder_content_padding_left_right">8dp</dimen>
     <dimen name="folder_content_padding_top">16dp</dimen>
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 20352a3..14a467a 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -149,7 +149,6 @@
 
     // Folder content
     public Point folderCellLayoutBorderSpacePx;
-    public int folderCellLayoutBorderSpaceOriginalPx;
     public int folderContentPaddingLeftRight;
     public int folderContentPaddingTop;
 
@@ -327,9 +326,8 @@
                 pxFromDp(inv.allAppsBorderSpaces[mTypeIndex].x, mMetrics),
                 pxFromDp(inv.allAppsBorderSpaces[mTypeIndex].y, mMetrics));
         cellLayoutBorderSpaceOriginalPx = new Point(cellLayoutBorderSpacePx);
-        folderCellLayoutBorderSpaceOriginalPx = pxFromDp(inv.folderBorderSpace, mMetrics);
-        folderCellLayoutBorderSpacePx = new Point(folderCellLayoutBorderSpaceOriginalPx,
-                folderCellLayoutBorderSpaceOriginalPx);
+        folderCellLayoutBorderSpacePx = new Point(pxFromDp(inv.folderBorderSpaces.x, mMetrics),
+                pxFromDp(inv.folderBorderSpaces.y, mMetrics));
 
         workspacePageIndicatorHeight = res.getDimensionPixelSize(
                 R.dimen.workspace_page_indicator_height);
@@ -932,16 +930,14 @@
         int textHeight = Utilities.calculateTextHeight(folderChildTextSizePx);
 
         if (isScalableGrid) {
-            int minWidth = folderChildIconSizePx + iconDrawablePaddingPx * 2;
-            int minHeight = folderChildIconSizePx + iconDrawablePaddingPx * 2 + textHeight;
+            folderCellWidthPx = pxFromDp(inv.folderCellSize.x, mMetrics, scale);
+            folderCellHeightPx = pxFromDp(inv.folderCellSize.y, mMetrics, scale);
 
-            folderCellWidthPx = (int) Math.max(minWidth, cellWidthPx * scale);
-            folderCellHeightPx = (int) Math.max(minHeight, cellHeightPx * scale);
-
-            int scaledSpace = (int) (folderCellLayoutBorderSpaceOriginalPx * scale);
-            folderCellLayoutBorderSpacePx = new Point(scaledSpace, scaledSpace);
-            folderContentPaddingLeftRight = scaledSpace;
-            folderContentPaddingTop = scaledSpace;
+            folderCellLayoutBorderSpacePx = new Point(
+                    pxFromDp(inv.folderBorderSpaces.x, mMetrics, scale),
+                    pxFromDp(inv.folderBorderSpaces.y, mMetrics, scale));
+            folderContentPaddingLeftRight = folderCellLayoutBorderSpacePx.x;
+            folderContentPaddingTop = pxFromDp(inv.folderTopPadding, mMetrics, scale);
         } else {
             int cellPaddingX = (int) (res.getDimensionPixelSize(R.dimen.folder_cell_x_padding)
                     * scale);
@@ -1417,12 +1413,13 @@
         writer.println(prefix + pxToDpStr("folderChildTextSizePx", folderChildTextSizePx));
         writer.println(prefix + pxToDpStr("folderChildDrawablePaddingPx",
                 folderChildDrawablePaddingPx));
-        writer.println(prefix + pxToDpStr("folderCellLayoutBorderSpaceOriginalPx",
-                folderCellLayoutBorderSpaceOriginalPx));
         writer.println(prefix + pxToDpStr("folderCellLayoutBorderSpacePx Horizontal",
                 folderCellLayoutBorderSpacePx.x));
         writer.println(prefix + pxToDpStr("folderCellLayoutBorderSpacePx Vertical",
                 folderCellLayoutBorderSpacePx.y));
+        writer.println(prefix + pxToDpStr("folderContentPaddingLeftRight",
+                folderContentPaddingLeftRight));
+        writer.println(prefix + pxToDpStr("folderTopPadding", folderContentPaddingTop));
 
         writer.println(prefix + pxToDpStr("bottomSheetTopPadding", bottomSheetTopPadding));
 
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index cf2a3f8..6a262c3 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -127,9 +127,12 @@
     public PointF[] minCellSize;
 
     public PointF[] borderSpaces;
-    public float folderBorderSpace;
     public int inlineNavButtonsEndSpacing;
 
+    public PointF folderBorderSpaces;
+    public PointF folderCellSize;
+    public float folderTopPadding;
+
     public float[] horizontalMargin;
 
     public PointF[] allAppsCellSize;
@@ -255,8 +258,6 @@
                 COUNT_SIZES);
         System.arraycopy(defaultDisplayOption.borderSpaces, 0, result.borderSpaces, 0,
                 COUNT_SIZES);
-        System.arraycopy(defaultDisplayOption.inlineQsb, 0, result.inlineQsb, 0,
-                COUNT_SIZES);
 
         initGrid(context, myInfo, result, deviceType);
     }
@@ -353,7 +354,10 @@
         minCellSize = displayOption.minCellSize;
 
         borderSpaces = displayOption.borderSpaces;
-        folderBorderSpace = displayOption.folderBorderSpace;
+
+        folderBorderSpaces = displayOption.folderBorderSpaces;
+        folderCellSize = displayOption.folderCellSize;
+        folderTopPadding = displayOption.folderTopPadding;
 
         horizontalMargin = displayOption.horizontalMargin;
 
@@ -381,7 +385,7 @@
             devicePaddings = new DevicePaddings(context, devicePaddingId);
         }
 
-        inlineQsb = displayOption.inlineQsb;
+        inlineQsb = closestProfile.inlineQsb;
 
         // If the partner customization apk contains any grid overrides, apply them
         // Supported overrides: numRows, numColumns, iconSize
@@ -717,6 +721,12 @@
         private static final int DEVICE_CATEGORY_ALL =
                 DEVICE_CATEGORY_PHONE | DEVICE_CATEGORY_TABLET | DEVICE_CATEGORY_MULTI_DISPLAY;
 
+        private static final int INLINE_QSB_FOR_PORTRAIT = 1 << 0;
+        private static final int INLINE_QSB_FOR_LANDSCAPE = 1 << 1;
+        private static final int INLINE_QSB_FOR_TWO_PANEL_PORTRAIT = 1 << 2;
+        private static final int INLINE_QSB_FOR_TWO_PANEL_LANDSCAPE = 1 << 3;
+        private static final int DONT_INLINE_QSB = 0;
+
         public final String name;
         public final int numRows;
         public final int numColumns;
@@ -733,6 +743,8 @@
 
         private final int[] hotseatColumnSpan = new int[COUNT_SIZES];
 
+        private final boolean[] inlineQsb = new boolean[COUNT_SIZES];
+
         private int inlineNavButtonsEndSpacing;
         private final String dbFile;
 
@@ -805,6 +817,19 @@
                         && ((deviceCategory & DEVICE_CATEGORY_MULTI_DISPLAY)
                             == DEVICE_CATEGORY_MULTI_DISPLAY));
 
+            int inlineForRotation = a.getInt(R.styleable.GridDisplayOption_inlineQsb,
+                    DONT_INLINE_QSB);
+            inlineQsb[INDEX_DEFAULT] =
+                    (inlineForRotation & INLINE_QSB_FOR_PORTRAIT) == INLINE_QSB_FOR_PORTRAIT;
+            inlineQsb[INDEX_LANDSCAPE] =
+                    (inlineForRotation & INLINE_QSB_FOR_LANDSCAPE) == INLINE_QSB_FOR_LANDSCAPE;
+            inlineQsb[INDEX_TWO_PANEL_PORTRAIT] =
+                    (inlineForRotation & INLINE_QSB_FOR_TWO_PANEL_PORTRAIT)
+                            == INLINE_QSB_FOR_TWO_PANEL_PORTRAIT;
+            inlineQsb[INDEX_TWO_PANEL_LANDSCAPE] =
+                    (inlineForRotation & INLINE_QSB_FOR_TWO_PANEL_LANDSCAPE)
+                            == INLINE_QSB_FOR_TWO_PANEL_LANDSCAPE;
+
             a.recycle();
             extraAttrs = Themes.createValueMap(context, attrs,
                     IntArray.wrap(R.styleable.GridDisplayOption));
@@ -813,22 +838,18 @@
 
     @VisibleForTesting
     static final class DisplayOption {
-        private static final int INLINE_QSB_FOR_PORTRAIT = 1 << 0;
-        private static final int INLINE_QSB_FOR_LANDSCAPE = 1 << 1;
-        private static final int INLINE_QSB_FOR_TWO_PANEL_PORTRAIT = 1 << 2;
-        private static final int INLINE_QSB_FOR_TWO_PANEL_LANDSCAPE = 1 << 3;
-        private static final int DONT_INLINE_QSB = 0;
-
         public final GridOption grid;
 
         private final float minWidthDps;
         private final float minHeightDps;
         private final boolean canBeDefault;
-        private final boolean[] inlineQsb = new boolean[COUNT_SIZES];
 
         private final PointF[] minCellSize = new PointF[COUNT_SIZES];
 
-        private float folderBorderSpace;
+        private final PointF folderCellSize;
+        private final PointF folderBorderSpaces;
+        private float folderTopPadding;
+
         private final PointF[] borderSpaces = new PointF[COUNT_SIZES];
         private final float[] horizontalMargin = new float[COUNT_SIZES];
         private final float[] hotseatBarBottomSpace = new float[COUNT_SIZES];
@@ -852,19 +873,6 @@
 
             canBeDefault = a.getBoolean(R.styleable.ProfileDisplayOption_canBeDefault, false);
 
-            int inlineForRotation = a.getInt(R.styleable.ProfileDisplayOption_inlineQsb,
-                    DONT_INLINE_QSB);
-            inlineQsb[INDEX_DEFAULT] =
-                    (inlineForRotation & INLINE_QSB_FOR_PORTRAIT) == INLINE_QSB_FOR_PORTRAIT;
-            inlineQsb[INDEX_LANDSCAPE] =
-                    (inlineForRotation & INLINE_QSB_FOR_LANDSCAPE) == INLINE_QSB_FOR_LANDSCAPE;
-            inlineQsb[INDEX_TWO_PANEL_PORTRAIT] =
-                    (inlineForRotation & INLINE_QSB_FOR_TWO_PANEL_PORTRAIT)
-                            == INLINE_QSB_FOR_TWO_PANEL_PORTRAIT;
-            inlineQsb[INDEX_TWO_PANEL_LANDSCAPE] =
-                    (inlineForRotation & INLINE_QSB_FOR_TWO_PANEL_LANDSCAPE)
-                            == INLINE_QSB_FOR_TWO_PANEL_LANDSCAPE;
-
             float x;
             float y;
 
@@ -924,7 +932,20 @@
                     borderSpaceTwoPanelLandscape);
             borderSpaces[INDEX_TWO_PANEL_LANDSCAPE] = new PointF(x, y);
 
-            folderBorderSpace = borderSpace;
+            x = a.getFloat(R.styleable.ProfileDisplayOption_folderCellWidth,
+                    minCellSize[INDEX_DEFAULT].x);
+            y = a.getFloat(R.styleable.ProfileDisplayOption_folderCellHeight,
+                    minCellSize[INDEX_DEFAULT].y);
+            folderCellSize = new PointF(x, y);
+
+            float folderBorderSpace = a.getFloat(R.styleable.ProfileDisplayOption_folderBorderSpace,
+                    borderSpace);
+
+            x = y = folderBorderSpace;
+            folderBorderSpaces = new PointF(x, y);
+
+            folderTopPadding = a.getFloat(R.styleable.ProfileDisplayOption_folderTopPadding,
+                    folderBorderSpaces.y);
 
             x = a.getFloat(R.styleable.ProfileDisplayOption_allAppsCellWidth,
                     minCellSize[INDEX_DEFAULT].x);
@@ -1097,8 +1118,10 @@
                 allAppsIconSizes[i] = 0;
                 allAppsIconTextSizes[i] = 0;
                 allAppsBorderSpaces[i] = new PointF();
-                inlineQsb[i] = false;
             }
+            folderBorderSpaces = new PointF();
+            folderCellSize = new PointF();
+            folderTopPadding = 0f;
         }
 
         private DisplayOption multiply(float w) {
@@ -1119,8 +1142,11 @@
                 allAppsBorderSpaces[i].x *= w;
                 allAppsBorderSpaces[i].y *= w;
             }
-
-            folderBorderSpace *= w;
+            folderBorderSpaces.x *= w;
+            folderBorderSpaces.y *= w;
+            folderCellSize.x *= w;
+            folderCellSize.y *= w;
+            folderTopPadding *= w;
 
             return this;
         }
@@ -1142,10 +1168,12 @@
                 allAppsIconTextSizes[i] += p.allAppsIconTextSizes[i];
                 allAppsBorderSpaces[i].x += p.allAppsBorderSpaces[i].x;
                 allAppsBorderSpaces[i].y += p.allAppsBorderSpaces[i].y;
-                inlineQsb[i] |= p.inlineQsb[i];
             }
-
-            folderBorderSpace += p.folderBorderSpace;
+            folderBorderSpaces.x += p.folderBorderSpaces.x;
+            folderBorderSpaces.y += p.folderBorderSpaces.y;
+            folderCellSize.x += p.folderCellSize.x;
+            folderCellSize.y += p.folderCellSize.y;
+            folderTopPadding += p.folderTopPadding;
 
             return this;
         }
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index b716912..f4a8ce5 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -2063,20 +2063,11 @@
 
                     if (container != LauncherSettings.Favorites.CONTAINER_HOTSEAT &&
                             cell instanceof LauncherAppWidgetHostView) {
-                        final CellLayout cellLayout = dropTargetLayout;
+
                         // We post this call so that the widget has a chance to be placed
                         // in its final location
-
-                        final LauncherAppWidgetHostView hostView = (LauncherAppWidgetHostView) cell;
-                        AppWidgetProviderInfo pInfo = hostView.getAppWidgetInfo();
-                        if (pInfo != null && pInfo.resizeMode != AppWidgetProviderInfo.RESIZE_NONE
-                                && !options.isAccessibleDrag) {
-                            onCompleteRunnable = () -> {
-                                if (!isPageInTransition()) {
-                                    AppWidgetResizeFrame.showForWidget(hostView, cellLayout);
-                                }
-                            };
-                        }
+                        onCompleteRunnable = getWidgetResizeFrameRunnable(options,
+                                (LauncherAppWidgetHostView) cell, dropTargetLayout);
                     }
                     mLauncher.getModelWriter().modifyItemInDatabase(info, container, screenId,
                             lp.cellX, lp.cellY, item.spanX, item.spanY);
@@ -2097,8 +2088,16 @@
                 }
             } else {
                 // When drag is cancelled, reattach content view back to its original parent.
-                if (mDragInfo.cell instanceof LauncherAppWidgetHostView) {
+                if (cell instanceof LauncherAppWidgetHostView) {
                     d.dragView.detachContentView(/* reattachToPreviousParent= */ true);
+
+                    final CellLayout cellLayout = getParentCellLayoutForView(cell);
+                    boolean pageIsVisible = isVisible(cellLayout);
+
+                    if (pageIsVisible) {
+                        onCompleteRunnable = getWidgetResizeFrameRunnable(options,
+                                (LauncherAppWidgetHostView) cell, cellLayout);
+                    }
                 }
             }
 
@@ -2151,6 +2150,21 @@
         }
     }
 
+    @Nullable
+    private Runnable getWidgetResizeFrameRunnable(DragOptions options,
+            LauncherAppWidgetHostView hostView, CellLayout cellLayout) {
+        AppWidgetProviderInfo pInfo = hostView.getAppWidgetInfo();
+        if (pInfo != null && pInfo.resizeMode != AppWidgetProviderInfo.RESIZE_NONE
+                && !options.isAccessibleDrag) {
+            return () -> {
+                if (!isPageInTransition()) {
+                    AppWidgetResizeFrame.showForWidget(hostView, cellLayout);
+                }
+            };
+        }
+        return null;
+    }
+
     public void onNoCellFound(
             View dropTargetLayout, ItemInfo itemInfo, @Nullable InstanceId logInstanceId) {
         int strId = mLauncher.isHotseatLayout(dropTargetLayout)
diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java
index 464b3ed..0a77aa7 100644
--- a/src/com/android/launcher3/anim/Interpolators.java
+++ b/src/com/android/launcher3/anim/Interpolators.java
@@ -50,8 +50,6 @@
     public static final Interpolator ACCEL_DEACCEL = new AccelerateDecelerateInterpolator();
 
     public static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
-    public static final Interpolator FASTER_OUT_SLOWER_IN =
-            new PathInterpolator(0.3f, 0f, 0.1f, 1f);
 
     public static final Interpolator AGGRESSIVE_EASE = new PathInterpolator(0.2f, 0f, 0f, 1f);
     public static final Interpolator AGGRESSIVE_EASE_IN_OUT = new PathInterpolator(0.6f,0, 0.4f, 1);
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index e351173..eabbf60 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -169,6 +169,13 @@
             "ENABLE_SMARTSPACE_DISMISS", true,
             "Adds a menu option to dismiss the current Enhanced Smartspace card.");
 
+    /**
+     * Enables region sampling for text color: Needs system health assessment before turning on
+     */
+    public static final BooleanFlag ENABLE_REGION_SAMPLING =  getDebugFlag(
+            "ENABLE_REGION_SAMPLING", false,
+            "Enable region sampling to determine color of text on screen.");
+
     public static final BooleanFlag ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS =
             getDebugFlag(
             "ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS", false,
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index 2a0fe3a..9ac1c0e 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -440,7 +440,7 @@
     public void setSplitInstructionsParams(View out, DeviceProfile dp, int splitInstructionsHeight,
             int splitInstructionsWidth, int threeButtonNavShift) {
         out.setPivotX(0);
-        out.setPivotY(splitInstructionsHeight);
+        out.setPivotY(0);
         out.setRotation(getDegreesRotated());
         int distanceToEdge = out.getResources().getDimensionPixelSize(
                 R.dimen.split_instructions_bottom_margin_phone_landscape);
@@ -448,8 +448,8 @@
         int insetCorrectionX = dp.getInsets().left;
         // Center the view in case of unbalanced insets on top or bottom of screen
         int insetCorrectionY = (dp.getInsets().bottom - dp.getInsets().top) / 2;
-        out.setTranslationX(distanceToEdge - insetCorrectionX);
-        out.setTranslationY(((-splitInstructionsHeight - splitInstructionsWidth) / 2f)
+        out.setTranslationX(splitInstructionsHeight + distanceToEdge - insetCorrectionX);
+        out.setTranslationY(((splitInstructionsHeight - splitInstructionsWidth) / 2f)
                 + insetCorrectionY);
         FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) out.getLayoutParams();
         // Setting gravity to LEFT instead of the lint-recommended START because we always want this
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index f89c0e5..dd9f642 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -500,7 +500,7 @@
     public void setSplitInstructionsParams(View out, DeviceProfile dp, int splitInstructionsHeight,
             int splitInstructionsWidth, int threeButtonNavShift) {
         out.setPivotX(0);
-        out.setPivotY(splitInstructionsHeight);
+        out.setPivotY(0);
         out.setRotation(getDegreesRotated());
         int distanceToEdge;
         if ((DisplayController.getNavigationMode(out.getContext()) == THREE_BUTTONS)
diff --git a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
index 55bb5e8..387e980 100644
--- a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
@@ -190,7 +190,7 @@
     public void setSplitInstructionsParams(View out, DeviceProfile dp, int splitInstructionsHeight,
             int splitInstructionsWidth, int threeButtonNavShift) {
         out.setPivotX(0);
-        out.setPivotY(splitInstructionsHeight);
+        out.setPivotY(0);
         out.setRotation(getDegreesRotated());
         int distanceToEdge = out.getResources().getDimensionPixelSize(
                 R.dimen.split_instructions_bottom_margin_phone_landscape);
@@ -198,8 +198,9 @@
         int insetCorrectionX = dp.getInsets().right;
         // Center the view in case of unbalanced insets on top or bottom of screen
         int insetCorrectionY = (dp.getInsets().bottom - dp.getInsets().top) / 2;
-        out.setTranslationX(splitInstructionsWidth - distanceToEdge + insetCorrectionX);
-        out.setTranslationY(((-splitInstructionsHeight + splitInstructionsWidth) / 2f)
+        out.setTranslationX(splitInstructionsWidth - splitInstructionsHeight - distanceToEdge
+                + insetCorrectionX);
+        out.setTranslationY(((splitInstructionsHeight + splitInstructionsWidth) / 2f)
                 + insetCorrectionY);
         FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) out.getLayoutParams();
         // Setting gravity to RIGHT instead of the lint-recommended END because we always want this
diff --git a/src/com/android/launcher3/util/ViewCapture.java b/src/com/android/launcher3/util/ViewCapture.java
index cf4e84a..58c8269 100644
--- a/src/com/android/launcher3/util/ViewCapture.java
+++ b/src/com/android/launcher3/util/ViewCapture.java
@@ -240,6 +240,7 @@
         public float translateX, translateY;
         public float scaleX, scaleY;
         public float alpha;
+        public float elevation;
 
         public int visibility;
         public boolean willNotDraw;
@@ -271,6 +272,7 @@
 
             visibility = view.getVisibility();
             willNotDraw = view.willNotDraw();
+            elevation = view.getElevation();
         }
 
         /**
@@ -303,6 +305,7 @@
                     .setAlpha(alpha)
                     .setVisibility(visibility)
                     .setWillNotDraw(willNotDraw)
+                    .setElevation(elevation)
                     .setClipChildren(clipChildren);
 
             ViewPropertyRef result = next;
diff --git a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
index 77ade80..2c1cbdf 100644
--- a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
+++ b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
@@ -96,8 +96,6 @@
             numColumns = 4
             numSearchContainerColumns = 4
 
-            numFolderRows = 3
-            numFolderColumns = 3
             iconSize = floatArrayOf(60f, 54f, 60f, 60f)
             iconTextSize = FloatArray(4) { 14f }
             deviceType = InvariantDeviceProfile.TYPE_PHONE
@@ -115,7 +113,14 @@
                     PointF(16f, 16f),
                     PointF(16f, 16f)
             ).toTypedArray()
-            folderBorderSpace = 16f
+
+            numFolderRows = 3
+            numFolderColumns = 3
+            folderBorderSpaces = PointF(16f, 16f)
+            folderTopPadding = 24f
+            folderCellSize = PointF(80f, 94f)
+
+
             inlineNavButtonsEndSpacing = R.dimen.taskbar_button_margin_4_5
 
             horizontalMargin = FloatArray(4) { 22f }
@@ -199,6 +204,13 @@
                     PointF(16f, 64f),
                     PointF(16f, 64f)
             ).toTypedArray()
+
+            numFolderRows = 3
+            numFolderColumns = 3
+            folderBorderSpaces = PointF(16f, 16f)
+            folderTopPadding = 24f
+            folderCellSize = PointF(120f, 104f)
+
             inlineNavButtonsEndSpacing = R.dimen.taskbar_button_margin_6_5
 
             horizontalMargin = floatArrayOf(54f, 120f, 54f, 54f)
@@ -273,8 +285,6 @@
             numColumns = 4
             numSearchContainerColumns = 4
 
-            numFolderRows = 3
-            numFolderColumns = 4
             iconSize = floatArrayOf(60f, 52f, 52f, 60f)
             iconTextSize = floatArrayOf(14f, 14f, 12f, 14f)
             deviceType = InvariantDeviceProfile.TYPE_MULTI_DISPLAY
@@ -292,7 +302,13 @@
                     PointF(16f, 20f),
                     PointF(20f, 20f)
             ).toTypedArray()
-            folderBorderSpace = 16f
+
+            numFolderRows = 3
+            numFolderColumns = 3
+            folderBorderSpaces = PointF(16f, 16f)
+            folderTopPadding = 24f
+            folderCellSize = PointF(80f, 94f)
+
             inlineNavButtonsEndSpacing = R.dimen.taskbar_button_margin_4_4
 
             horizontalMargin = floatArrayOf(21.5f, 21.5f, 22.5f, 30.5f)