Merge "Removing some obsolete features" into tm-qpr-dev
diff --git a/go/quickstep/res/values-or/strings.xml b/go/quickstep/res/values-or/strings.xml
index 36de437..6a3c5dc 100644
--- a/go/quickstep/res/values-or/strings.xml
+++ b/go/quickstep/res/values-or/strings.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_share_drop_target_label" msgid="5804774105974539508">"ଆପ୍ ସେୟାର୍ କରନ୍ତୁ"</string>
+    <string name="app_share_drop_target_label" msgid="5804774105974539508">"ଆପ ସେୟାର କରନ୍ତୁ"</string>
     <string name="action_listen" msgid="2370304050784689486">"ଶୁଣନ୍ତୁ"</string>
     <string name="action_translate" msgid="8028378961867277746">"ଅନୁବାଦ କରନ୍ତୁ"</string>
     <string name="action_search" msgid="6269564710943755464">"Lens"</string>
diff --git a/proguard.flags b/proguard.flags
index a450183..53a68de 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -2,10 +2,6 @@
   *;
 }
 
--keep class com.android.launcher3.graphics.ShadowDrawable {
-  public <init>(...);
-}
-
 # The support library contains references to newer platform versions.
 # Don't warn about those in case this app is linking against an older
 # platform version.  We know about them, and they are safe.
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/res/values-land/dimens.xml b/quickstep/res/values-land/dimens.xml
index 8368069..905fbda 100644
--- a/quickstep/res/values-land/dimens.xml
+++ b/quickstep/res/values-land/dimens.xml
@@ -77,7 +77,7 @@
 
     <!--  Taskbar 3 button spacing  -->
     <dimen name="taskbar_button_margin_5_5">94.5dp</dimen>
-    <dimen name="taskbar_button_margin_6_5">94.5dp</dimen>
+    <dimen name="taskbar_button_margin_6_5">219.6dp</dimen>
     <dimen name="taskbar_button_margin_4_5">84dp</dimen>
     <dimen name="taskbar_button_margin_4_4">79dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 35215e1..c85e71c 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -263,6 +263,7 @@
     <dimen name="taskbar_contextual_buttons_size">35dp</dimen>
     <dimen name="taskbar_stashed_size">24dp</dimen>
     <dimen name="taskbar_stashed_handle_width">220dp</dimen>
+    <dimen name="taskbar_stashed_small_screen">108dp</dimen>
     <dimen name="taskbar_unstash_input_area">316dp</dimen>
     <dimen name="taskbar_stashed_handle_height">4dp</dimen>
     <dimen name="taskbar_edu_wave_anim_trans_y">25dp</dimen>
@@ -276,8 +277,9 @@
 
     <!--  Taskbar 3 button spacing  -->
     <dimen name="taskbar_button_space_inbetween">24dp</dimen>
+    <dimen name="taskbar_button_space_inbetween_phone">40dp</dimen>
     <dimen name="taskbar_button_margin_5_5">26dp</dimen>
-    <dimen name="taskbar_button_margin_6_5">26dp</dimen>
+    <dimen name="taskbar_button_margin_6_5">75dp</dimen>
     <dimen name="taskbar_button_margin_4_5">47dp</dimen>
     <dimen name="taskbar_button_margin_4_4">47dp</dimen>
     <dimen name="taskbar_button_margin_default">47dp</dimen>
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index e21dcba..c2e8658 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -110,7 +110,7 @@
  */
 public abstract class BaseQuickstepLauncher extends Launcher {
 
-    private DepthController mDepthController = new DepthController(this);
+    private DepthController mDepthController;
     private QuickstepTransitionManager mAppTransitionManager;
 
     /**
@@ -247,7 +247,6 @@
     @Override
     public void onScrollChanged(float progress) {
         super.onScrollChanged(progress);
-        mDepthController.onOverlayScrollChanged(progress);
         onTaskbarInAppDisplayProgressUpdate(progress, MINUS_ONE_PAGE_PROGRESS_INDEX);
     }
 
@@ -345,6 +344,7 @@
         mAppTransitionManager.registerRemoteTransitions();
 
         mTISBindHelper = new TISBindHelper(this, this::onTISConnected);
+        mDepthController = new DepthController(this);
     }
 
     private void onTISConnected(TISBinder binder) {
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index 3e13a44..d348cc3 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -43,7 +43,6 @@
 import static com.android.launcher3.config.FeatureFlags.SEPARATE_RECENTS_ACTIVITY;
 import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
 import static com.android.launcher3.statehandlers.DepthController.DEPTH;
-import static com.android.launcher3.testing.shared.TestProtocol.BAD_STATE;
 import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
 import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
 import static com.android.launcher3.views.FloatingIconView.getFloatingIconView;
@@ -77,9 +76,9 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings;
-import android.util.Log;
 import android.util.Pair;
 import android.util.Size;
+import android.view.CrossWindowBlurListeners;
 import android.view.SurfaceControl;
 import android.view.View;
 import android.view.ViewRootImpl;
@@ -95,6 +94,7 @@
 import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
 import com.android.launcher3.LauncherAnimationRunner.RemoteAnimationFactory;
 import com.android.launcher3.anim.AnimationSuccessListener;
+import com.android.launcher3.anim.AnimatorListeners;
 import com.android.launcher3.dragndrop.DragLayer;
 import com.android.launcher3.icons.FastBitmapDrawable;
 import com.android.launcher3.shortcuts.DeepShortcutView;
@@ -137,7 +137,6 @@
 import com.android.wm.shell.startingsurface.IStartingWindowListener;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.LinkedHashMap;
 import java.util.List;
 
@@ -146,8 +145,6 @@
  */
 public class QuickstepTransitionManager implements OnDeviceProfileChangeListener {
 
-    private static final String TAG = "QuickstepTransition";
-
     private static final boolean ENABLE_SHELL_STARTING_SURFACE =
             SystemProperties.getBoolean("persist.debug.shell_starting_surface", true);
 
@@ -447,7 +444,7 @@
                         4 - rotationChange);
             }
         }
-        if (mDeviceProfile.isTaskbarPresentInApps) {
+        if (mDeviceProfile.isTaskbarPresentInApps && !target.willShowImeOnTarget) {
             // Animate to above the taskbar.
             bounds.bottom -= target.contentInsets.bottom;
         }
@@ -520,6 +517,7 @@
                 appsView.setAlpha(startAlpha);
                 SCALE_PROPERTY.set(appsView, startScale);
                 appsView.setLayerType(View.LAYER_TYPE_NONE, null);
+                mLauncher.resumeExpensiveViewUpdates();
             };
         } else if (mLauncher.isInState(OVERVIEW)) {
             endListener = composeViewContentAnimator(launcherAnimator, alphas, scales);
@@ -623,28 +621,9 @@
         RecentsView overview = mLauncher.getOverviewPanel();
         ObjectAnimator alpha = ObjectAnimator.ofFloat(overview,
                 RecentsView.CONTENT_ALPHA, alphas);
-        Log.d(BAD_STATE, "QTM composeViewContentAnimator alphas=" + Arrays.toString(alphas));
-        alpha.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationStart(Animator animation) {
-                Log.d(BAD_STATE, "QTM composeViewContentAnimator onStart");
-            }
-
-            @Override
-            public void onAnimationCancel(Animator animation) {
-                float alpha = overview == null ? -1 : RecentsView.CONTENT_ALPHA.get(overview);
-                Log.d(BAD_STATE, "QTM composeViewContentAnimator onCancel, alpha=" + alpha);
-            }
-
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                Log.d(BAD_STATE, "QTM composeViewContentAnimator onEnd");
-            }
-        });
         alpha.setDuration(CONTENT_ALPHA_DURATION);
         alpha.setInterpolator(LINEAR);
         anim.play(alpha);
-        Log.d(BAD_STATE, "QTM composeViewContentAnimator setFreezeVisibility=true");
         overview.setFreezeViewVisibility(true);
 
         ObjectAnimator scaleAnim = ObjectAnimator.ofFloat(overview, SCALE_PROPERTY, scales);
@@ -653,10 +632,10 @@
         anim.play(scaleAnim);
 
         return () -> {
-            Log.d(BAD_STATE, "QTM composeViewContentAnimator onEnd setFreezeVisibility=false");
             overview.setFreezeViewVisibility(false);
             SCALE_PROPERTY.set(overview, 1f);
             mLauncher.getStateManager().reapplyState();
+            mLauncher.resumeExpensiveViewUpdates();
         };
     }
 
@@ -1067,54 +1046,37 @@
     private ObjectAnimator getBackgroundAnimator() {
         // When launching an app from overview that doesn't map to a task, we still want to just
         // blur the wallpaper instead of the launcher surface as well
-        boolean allowBlurringLauncher = mLauncher.getStateManager().getState() != OVERVIEW;
-        DepthController depthController = mLauncher.getDepthController();
+        boolean allowBlurringLauncher = mLauncher.getStateManager().getState() != OVERVIEW
+                && BlurUtils.supportsBlursOnWindows();
+
+        MyDepthController depthController = new MyDepthController(mLauncher);
         ObjectAnimator backgroundRadiusAnim = ObjectAnimator.ofFloat(depthController, DEPTH,
-                BACKGROUND_APP.getDepth(mLauncher))
+                        BACKGROUND_APP.getDepth(mLauncher))
                 .setDuration(APP_LAUNCH_DURATION);
+
         if (allowBlurringLauncher) {
-            final SurfaceControl dimLayer;
-            if (BlurUtils.supportsBlursOnWindows()) {
-                // Create a temporary effect layer, that lives on top of launcher, so we can apply
-                // the blur to it. The EffectLayer will be fullscreen, which will help with caching
-                // optimizations on the SurfaceFlinger side:
-                // - Results would be able to be cached as a texture
-                // - There won't be texture allocation overhead, because EffectLayers don't have
-                //   buffers
-                ViewRootImpl viewRootImpl = mLauncher.getDragLayer().getViewRootImpl();
-                SurfaceControl parent = viewRootImpl != null
-                        ? viewRootImpl.getSurfaceControl()
-                        : null;
-                dimLayer = new SurfaceControl.Builder()
-                        .setName("Blur layer")
-                        .setParent(parent)
-                        .setOpaque(false)
-                        .setHidden(false)
-                        .setEffectLayer()
-                        .build();
-            } else {
-                dimLayer = null;
-            }
+            // Create a temporary effect layer, that lives on top of launcher, so we can apply
+            // the blur to it. The EffectLayer will be fullscreen, which will help with caching
+            // optimizations on the SurfaceFlinger side:
+            // - Results would be able to be cached as a texture
+            // - There won't be texture allocation overhead, because EffectLayers don't have
+            //   buffers
+            ViewRootImpl viewRootImpl = mLauncher.getDragLayer().getViewRootImpl();
+            SurfaceControl parent = viewRootImpl != null
+                    ? viewRootImpl.getSurfaceControl()
+                    : null;
+            SurfaceControl dimLayer = new SurfaceControl.Builder()
+                    .setName("Blur layer")
+                    .setParent(parent)
+                    .setOpaque(false)
+                    .setHidden(false)
+                    .setEffectLayer()
+                    .build();
 
-            depthController.setSurface(dimLayer);
-            backgroundRadiusAnim.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationStart(Animator animation) {
-                    depthController.setIsInLaunchTransition(true);
-                }
-
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    depthController.setIsInLaunchTransition(false);
-                    depthController.setSurface(null);
-                    if (dimLayer != null) {
-                        new SurfaceControl.Transaction()
-                                .remove(dimLayer)
-                                .apply();
-                    }
-                }
-            });
+            backgroundRadiusAnim.addListener(AnimatorListeners.forEndCallback(() ->
+                    new SurfaceControl.Transaction().remove(dimLayer).apply()));
         }
+
         return backgroundRadiusAnim;
     }
 
@@ -1456,7 +1418,7 @@
         animation.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationStart(Animator animation) {
-                anim.start(mLauncher, velocityPxPerS);
+                anim.start(mLauncher, mDeviceProfile, velocityPxPerS);
             }
         });
         return anim;
@@ -1959,4 +1921,17 @@
             return Utilities.mapToRange(progress, start, end, 1, 0, ACCEL_1_5);
         }
     }
+
+    private static class MyDepthController extends DepthController {
+        MyDepthController(Launcher l) {
+            super(l);
+            setCrossWindowBlursEnabled(
+                    CrossWindowBlurListeners.getInstance().isCrossWindowBlurEnabled());
+        }
+
+        @Override
+        public void setSurface(SurfaceControl surface) {
+            super.setSurface(surface);
+        }
+    }
 }
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
index eda0823..1311b1d 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
@@ -23,13 +23,8 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
-import android.app.WallpaperManager;
-import android.os.IBinder;
-import android.os.SystemProperties;
 import android.util.FloatProperty;
-import android.view.AttachedSurfaceControl;
 import android.view.CrossWindowBlurListeners;
-import android.view.SurfaceControl;
 import android.view.View;
 import android.view.ViewRootImpl;
 import android.view.ViewTreeObserver;
@@ -37,12 +32,11 @@
 import com.android.launcher3.BaseActivity;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
-import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.PendingAnimation;
 import com.android.launcher3.statemanager.StateManager.StateHandler;
 import com.android.launcher3.states.StateAnimationConfig;
-import com.android.systemui.shared.system.BlurUtils;
+import com.android.quickstep.util.BaseDepthController;
 
 import java.io.PrintWriter;
 import java.util.function.Consumer;
@@ -50,23 +44,9 @@
 /**
  * Controls blur and wallpaper zoom, for the Launcher surface only.
  */
-public class DepthController implements StateHandler<LauncherState>,
+public class DepthController extends BaseDepthController implements StateHandler<LauncherState>,
         BaseActivity.MultiWindowModeChangedListener {
 
-    private static final boolean OVERLAY_SCROLL_ENABLED = false;
-    public static final FloatProperty<DepthController> DEPTH =
-            new FloatProperty<DepthController>("depth") {
-                @Override
-                public void setValue(DepthController depthController, float depth) {
-                    depthController.setDepth(depth);
-                }
-
-                @Override
-                public Float get(DepthController depthController) {
-                    return depthController.mDepth;
-                }
-            };
-
     /**
      * A property that updates the background blur within a given range of values (ie. even if the
      * animator goes beyond 0..1, the interpolated value will still be bounded).
@@ -92,96 +72,46 @@
         }
     }
 
-    private final ViewTreeObserver.OnDrawListener mOnDrawListener =
-            new ViewTreeObserver.OnDrawListener() {
-                @Override
-                public void onDraw() {
-                    View view = mLauncher.getDragLayer();
-                    ViewRootImpl viewRootImpl = view.getViewRootImpl();
-                    boolean applied = setSurface(
-                            viewRootImpl != null ? viewRootImpl.getSurfaceControl() : null);
-                    if (!applied) {
-                        dispatchTransactionSurface(mDepth);
-                    }
-                    view.post(() -> view.getViewTreeObserver().removeOnDrawListener(this));
-                }
-            };
+    private final ViewTreeObserver.OnDrawListener mOnDrawListener = this::onLauncherDraw;
 
-    private final Consumer<Boolean> mCrossWindowBlurListener = new Consumer<Boolean>() {
-        @Override
-        public void accept(Boolean enabled) {
-            mCrossWindowBlursEnabled = enabled;
-            dispatchTransactionSurface(mDepth);
-        }
-    };
+    private final Consumer<Boolean> mCrossWindowBlurListener = this::setCrossWindowBlursEnabled;
 
-    private final Runnable mOpaquenessListener = new Runnable() {
-        @Override
-        public void run() {
-            dispatchTransactionSurface(mDepth);
-        }
-    };
+    private final Runnable mOpaquenessListener = this::applyDepthAndBlur;
 
-    private final Launcher mLauncher;
-    /**
-     * Blur radius when completely zoomed out, in pixels.
-     */
-    private int mMaxBlurRadius;
-    private boolean mCrossWindowBlursEnabled;
-    private WallpaperManager mWallpaperManager;
-    private SurfaceControl mSurface;
-    /**
-     * How visible the -1 overlay is, from 0 to 1.
-     */
-    private float mOverlayScrollProgress;
-    /**
-     * Ratio from 0 to 1, where 0 is fully zoomed out, and 1 is zoomed in.
-     * @see android.service.wallpaper.WallpaperService.Engine#onZoomChanged(float)
-     */
-    private float mDepth;
-    /**
-     * Last blur value, in pixels, that was applied.
-     * For debugging purposes.
-     */
-    private int mCurrentBlur;
     /**
      * If we're launching and app and should not be blurring the screen for performance reasons.
      */
     private boolean mBlurDisabledForAppLaunch;
-    /**
-     * If we requested early wake-up offsets to SurfaceFlinger.
-     */
-    private boolean mInEarlyWakeUp;
+
 
     // Workaround for animating the depth when multiwindow mode changes.
     private boolean mIgnoreStateChangesDuringMultiWindowAnimation = false;
 
-    // Hints that there is potentially content behind Launcher and that we shouldn't optimize by
-    // marking the launcher surface as opaque.  Only used in certain Launcher states.
-    private boolean mHasContentBehindLauncher;
-
     private View.OnAttachStateChangeListener mOnAttachListener;
 
     public DepthController(Launcher l) {
-        mLauncher = l;
+        super(l);
+    }
+
+    private void onLauncherDraw() {
+        View view = mLauncher.getDragLayer();
+        ViewRootImpl viewRootImpl = view.getViewRootImpl();
+        setSurface(viewRootImpl != null ? viewRootImpl.getSurfaceControl() : null);
+        view.post(() -> view.getViewTreeObserver().removeOnDrawListener(mOnDrawListener));
     }
 
     private void ensureDependencies() {
-        if (mWallpaperManager == null) {
-            mMaxBlurRadius = mLauncher.getResources().getInteger(R.integer.max_depth_blur_radius);
-            mWallpaperManager = mLauncher.getSystemService(WallpaperManager.class);
-        }
-
         if (mLauncher.getRootView() != null && mOnAttachListener == null) {
+            View rootView = mLauncher.getRootView();
             mOnAttachListener = new View.OnAttachStateChangeListener() {
                 @Override
                 public void onViewAttachedToWindow(View view) {
+                    CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(),
+                            mCrossWindowBlurListener);
+                    mLauncher.getScrimView().addOpaquenessListener(mOpaquenessListener);
+
                     // To handle the case where window token is invalid during last setDepth call.
-                    IBinder windowToken = mLauncher.getRootView().getWindowToken();
-                    if (windowToken != null) {
-                        mWallpaperManager.setWallpaperZoomOut(windowToken, mDepth);
-                    }
-                    onAttached();
+                    applyDepthAndBlur();
                 }
 
                 @Override
@@ -190,23 +120,13 @@
                     mLauncher.getScrimView().removeOpaquenessListener(mOpaquenessListener);
                 }
             };
-            mLauncher.getRootView().addOnAttachStateChangeListener(mOnAttachListener);
-            if (mLauncher.getRootView().isAttachedToWindow()) {
-                onAttached();
+            rootView.addOnAttachStateChangeListener(mOnAttachListener);
+            if (rootView.isAttachedToWindow()) {
+                mOnAttachListener.onViewAttachedToWindow(rootView);
             }
         }
     }
 
-    private void onAttached() {
-        CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(),
-                mCrossWindowBlurListener);
-        mLauncher.getScrimView().addOpaquenessListener(mOpaquenessListener);
-    }
-
-    public void setHasContentBehindLauncher(boolean hasContentBehindLauncher) {
-        mHasContentBehindLauncher = hasContentBehindLauncher;
-    }
-
     /**
      * Sets if the underlying activity is started or not
      */
@@ -219,26 +139,6 @@
         }
     }
 
-    /**
-     * Sets the specified app target surface to apply the blur to.
-     * @return true when surface was valid and transaction was dispatched.
-     */
-    public boolean setSurface(SurfaceControl surface) {
-        // Set launcher as the SurfaceControl when we don't need an external target anymore.
-        if (surface == null) {
-            ViewRootImpl viewRootImpl = mLauncher.getDragLayer().getViewRootImpl();
-            surface = viewRootImpl != null ? viewRootImpl.getSurfaceControl() : null;
-        }
-        if (mSurface != surface) {
-            mSurface = surface;
-            if (surface != null) {
-                dispatchTransactionSurface(mDepth);
-                return true;
-            }
-        }
-        return false;
-    }
-
     @Override
     public void setState(LauncherState toState) {
         if (mSurface == null || mIgnoreStateChangesDuringMultiWindowAnimation) {
@@ -249,7 +149,7 @@
         if (Float.compare(mDepth, toDepth) != 0) {
             setDepth(toDepth);
         } else if (toState == LauncherState.OVERVIEW) {
-            dispatchTransactionSurface(mDepth);
+            applyDepthAndBlur();
         } else if (toState == LauncherState.BACKGROUND_APP) {
             mLauncher.getDragLayer().getViewTreeObserver().addOnDrawListener(mOnDrawListener);
         }
@@ -269,90 +169,10 @@
         }
     }
 
-    /**
-     * If we're launching an app from the home screen.
-     */
-    public void setIsInLaunchTransition(boolean inLaunchTransition) {
-        boolean blurEnabled = SystemProperties.getBoolean("ro.launcher.blur.appLaunch", true);
-        mBlurDisabledForAppLaunch = inLaunchTransition && !blurEnabled;
-        if (!inLaunchTransition) {
-            // Reset depth at the end of the launch animation, so the wallpaper won't be
-            // zoomed out if an app crashes.
-            setDepth(0f);
-        }
-    }
-
-    private void setDepth(float depth) {
-        depth = Utilities.boundToRange(depth, 0, 1);
-        // Round out the depth to dedupe frequent, non-perceptable updates
-        int depthI = (int) (depth * 256);
-        float depthF = depthI / 256f;
-        if (Float.compare(mDepth, depthF) == 0) {
-            return;
-        }
-        dispatchTransactionSurface(depthF);
-        mDepth = depthF;
-    }
-
-    public void onOverlayScrollChanged(float progress) {
-        if (!OVERLAY_SCROLL_ENABLED) {
-            return;
-        }
-        // Add some padding to the progress, such we don't change the depth on the last frames of
-        // the animation. It's possible that a user flinging the feed quickly would scroll
-        // horizontally by accident, causing the device to enter client composition unnecessarily.
-        progress = Math.min(progress * 1.1f, 1f);
-
-        // Round out the progress to dedupe frequent, non-perceptable updates
-        int progressI = (int) (progress * 256);
-        float progressF = Utilities.boundToRange(progressI / 256f, 0f, 1f);
-        if (Float.compare(mOverlayScrollProgress, progressF) == 0) {
-            return;
-        }
-        mOverlayScrollProgress = progressF;
-        dispatchTransactionSurface(mDepth);
-    }
-
-    private boolean dispatchTransactionSurface(float depth) {
-        boolean supportsBlur = BlurUtils.supportsBlursOnWindows();
-        if (supportsBlur && (mSurface == null || !mSurface.isValid())) {
-            return false;
-        }
+    @Override
+    protected void applyDepthAndBlur() {
         ensureDependencies();
-        depth = Math.max(depth, mOverlayScrollProgress);
-        IBinder windowToken = mLauncher.getRootView().getWindowToken();
-        if (windowToken != null) {
-            mWallpaperManager.setWallpaperZoomOut(windowToken, depth);
-        }
-
-        if (supportsBlur) {
-            boolean hasOpaqueBg = mLauncher.getScrimView().isFullyOpaque();
-            boolean isSurfaceOpaque = !mHasContentBehindLauncher && hasOpaqueBg;
-
-            mCurrentBlur = !mCrossWindowBlursEnabled || mBlurDisabledForAppLaunch || hasOpaqueBg
-                    ? 0 : (int) (depth * mMaxBlurRadius);
-            SurfaceControl.Transaction transaction = new SurfaceControl.Transaction()
-                    .setBackgroundBlurRadius(mSurface, mCurrentBlur)
-                    .setOpaque(mSurface, isSurfaceOpaque);
-
-            // Set early wake-up flags when we know we're executing an expensive operation, this way
-            // SurfaceFlinger will adjust its internal offsets to avoid jank.
-            boolean wantsEarlyWakeUp = depth > 0 && depth < 1;
-            if (wantsEarlyWakeUp && !mInEarlyWakeUp) {
-                transaction.setEarlyWakeupStart();
-                mInEarlyWakeUp = true;
-            } else if (!wantsEarlyWakeUp && mInEarlyWakeUp) {
-                transaction.setEarlyWakeupEnd();
-                mInEarlyWakeUp = false;
-            }
-
-            AttachedSurfaceControl rootSurfaceControl =
-                    mLauncher.getRootView().getRootSurfaceControl();
-            if (rootSurfaceControl != null) {
-                rootSurfaceControl.applyTransactionOnDraw(transaction);
-            }
-        }
-        return true;
+        super.applyDepthAndBlur();
     }
 
     @Override
@@ -377,7 +197,6 @@
         writer.println(prefix + "\tmMaxBlurRadius=" + mMaxBlurRadius);
         writer.println(prefix + "\tmCrossWindowBlursEnabled=" + mCrossWindowBlursEnabled);
         writer.println(prefix + "\tmSurface=" + mSurface);
-        writer.println(prefix + "\tmOverlayScrollProgress=" + mOverlayScrollProgress);
         writer.println(prefix + "\tmDepth=" + mDepth);
         writer.println(prefix + "\tmCurrentBlur=" + mCurrentBlur);
         writer.println(prefix + "\tmBlurDisabledForAppLaunch=" + mBlurDisabledForAppLaunch);
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
index b01168d..f1f18c1 100644
--- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
@@ -15,15 +15,20 @@
  */
 package com.android.launcher3.taskbar;
 
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
 import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
 import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor;
 import static com.android.launcher3.taskbar.LauncherTaskbarUIController.SYSUI_SURFACE_PROGRESS_INDEX;
+import static com.android.launcher3.taskbar.TaskbarManager.isPhoneButtonNavMode;
+import static com.android.launcher3.taskbar.TaskbarManager.isPhoneMode;
 import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_A11Y;
 import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_BACK;
 import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_HOME;
 import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_IME_SWITCH;
 import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_RECENTS;
 import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_KEYGUARD;
+import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_SMALL_SCREEN;
 import static com.android.launcher3.taskbar.Utilities.appendFlag;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
@@ -109,6 +114,7 @@
     private static final int FLAG_NOTIFICATION_SHADE_EXPANDED = 1 << 10;
     private static final int FLAG_SCREEN_PINNING_ACTIVE = 1 << 11;
     private static final int FLAG_VOICE_INTERACTION_WINDOW_SHOWING = 1 << 12;
+    private static final int FLAG_SMALL_SCREEN = 1 << 13;
 
     private static final String NAV_BUTTONS_SEPARATE_WINDOW_TITLE = "Taskbar Nav Buttons";
 
@@ -122,7 +128,7 @@
 
     private final TaskbarActivityContext mContext;
     private final FrameLayout mNavButtonsView;
-    private final ViewGroup mNavButtonContainer;
+    private final LinearLayout mNavButtonContainer;
     // Used for IME+A11Y buttons
     private final ViewGroup mEndContextualContainer;
     private final ViewGroup mStartContextualContainer;
@@ -180,9 +186,13 @@
      */
     public void init(TaskbarControllers controllers) {
         mControllers = controllers;
-        mNavButtonsView.getLayoutParams().height = mContext.getDeviceProfile().taskbarSize;
-
         boolean isThreeButtonNav = mContext.isThreeButtonNav();
+        DeviceProfile deviceProfile = mContext.getDeviceProfile();
+        Resources resources = mContext.getResources();
+        mNavButtonsView.getLayoutParams().height = !isPhoneMode(deviceProfile) ?
+                deviceProfile.taskbarSize :
+                resources.getDimensionPixelSize(R.dimen.taskbar_size);
+
         mIsImeRenderingNavButtons =
                 InputMethodService.canImeRenderGesturalNavButtons() && mContext.imeDrawsImeNavBar();
         if (!mIsImeRenderingNavButtons) {
@@ -201,6 +211,11 @@
                 flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0
                         && (flags & FLAG_SCREEN_PINNING_ACTIVE) == 0));
 
+        mPropertyHolders.add(new StatePropertyHolder(
+                mControllers.taskbarViewController.getTaskbarIconAlpha()
+                        .getProperty(ALPHA_INDEX_SMALL_SCREEN),
+                flags -> (flags & FLAG_SMALL_SCREEN) == 0));
+
         mPropertyHolders.add(new StatePropertyHolder(mControllers.taskbarDragLayerController
                 .getKeyguardBgTaskbar(), flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0));
 
@@ -231,7 +246,7 @@
             initButtons(mNavButtonContainer, mEndContextualContainer,
                     mControllers.navButtonController);
             updateButtonLayoutSpacing();
-
+            updateStateForFlag(FLAG_SMALL_SCREEN, isPhoneButtonNavMode(mContext));
             if (isInSetup) {
                 // Since setup wizard only has back button enabled, it looks strange to be
                 // end-aligned, so start-align instead.
@@ -244,18 +259,18 @@
 
                 // TODO(b/210906568) Dark intensity is currently not propagated during setup, so set
                 //  it based on dark theme for now.
-                int mode = mContext.getResources().getConfiguration().uiMode
+                int mode = resources.getConfiguration().uiMode
                         & Configuration.UI_MODE_NIGHT_MASK;
                 boolean isDarkTheme = mode == Configuration.UI_MODE_NIGHT_YES;
                 mTaskbarNavButtonDarkIntensity.updateValue(isDarkTheme ? 0 : 1);
             } else if (isInKidsMode) {
-                int iconSize = mContext.getResources().getDimensionPixelSize(
+                int iconSize = resources.getDimensionPixelSize(
                         R.dimen.taskbar_icon_size_kids);
-                int buttonWidth = mContext.getResources().getDimensionPixelSize(
+                int buttonWidth = resources.getDimensionPixelSize(
                         R.dimen.taskbar_nav_buttons_width_kids);
-                int buttonHeight = mContext.getResources().getDimensionPixelSize(
+                int buttonHeight = resources.getDimensionPixelSize(
                         R.dimen.taskbar_nav_buttons_height_kids);
-                int buttonRadius = mContext.getResources().getDimensionPixelSize(
+                int buttonRadius = resources.getDimensionPixelSize(
                         R.dimen.taskbar_nav_buttons_corner_radius_kids);
                 int paddingleft = (buttonWidth - iconSize) / 2;
                 int paddingRight = paddingleft;
@@ -277,7 +292,7 @@
                         buttonWidth,
                         buttonHeight
                 );
-                int homeButtonLeftMargin = mContext.getResources().getDimensionPixelSize(
+                int homeButtonLeftMargin = resources.getDimensionPixelSize(
                         R.dimen.taskbar_home_button_left_margin_kids);
                 homeLayoutparams.setMargins(homeButtonLeftMargin, 0, 0, 0);
                 mHomeButton.setLayoutParams(homeLayoutparams);
@@ -287,7 +302,7 @@
                         buttonWidth,
                         buttonHeight
                 );
-                int backButtonLeftMargin = mContext.getResources().getDimensionPixelSize(
+                int backButtonLeftMargin = resources.getDimensionPixelSize(
                         R.dimen.taskbar_back_button_left_margin_kids);
                 backLayoutParams.setMargins(backButtonLeftMargin, 0, 0, 0);
                 mBackButton.setLayoutParams(backLayoutParams);
@@ -342,7 +357,7 @@
             if (!mIsImeRenderingNavButtons) {
                 View imeDownButton = addButton(R.drawable.ic_sysbar_back, BUTTON_BACK,
                         mStartContextualContainer, mControllers.navButtonController, R.id.back);
-                imeDownButton.setRotation(Utilities.isRtl(mContext.getResources()) ? 90 : -90);
+                imeDownButton.setRotation(Utilities.isRtl(resources) ? 90 : -90);
                 // Only show when IME is visible.
                 mPropertyHolders.add(new StatePropertyHolder(imeDownButton,
                         flags -> (flags & FLAG_IME_VISIBLE) != 0));
@@ -614,6 +629,9 @@
     }
 
     private void updateNavButtonTranslationY() {
+        if (isPhoneButtonNavMode(mContext)) {
+            return;
+        }
         final float normalTranslationY = mTaskbarNavButtonTranslationY.value;
         final float imeAdjustmentTranslationY = mTaskbarNavButtonTranslationYForIme.value;
         TaskbarUIController uiController = mControllers.uiController;
@@ -676,17 +694,29 @@
         updateButtonLayoutSpacing();
     }
 
-    /** Adds the correct spacing to 3 button nav container. No-op if using gesture nav */
+    /**
+     * Adds the correct spacing to 3 button nav container. No-op if using gesture nav or kids mode.
+     */
     private void updateButtonLayoutSpacing() {
-        if (!mContext.isThreeButtonNav()) {
+        if (!mContext.isThreeButtonNav() || mContext.isNavBarKidsModeActive()) {
             return;
         }
+
+        if (isPhoneButtonNavMode(mContext)) {
+            updatePhoneButtonSpacing();
+            return;
+        }
+
         DeviceProfile dp = mContext.getDeviceProfile();
         Resources res = mContext.getResources();
 
         // Add spacing after the end of the last nav button
         FrameLayout.LayoutParams navButtonParams =
                 (FrameLayout.LayoutParams) mNavButtonContainer.getLayoutParams();
+        navButtonParams.gravity = Gravity.END;
+        navButtonParams.width = FrameLayout.LayoutParams.WRAP_CONTENT;
+        navButtonParams.height = MATCH_PARENT;
+
         int navMarginEnd = (int) res.getDimension(dp.inv.inlineNavButtonsEndSpacing);
         int contextualWidth = mEndContextualContainer.getWidth();
         // If contextual buttons are showing, we check if the end margin is enough for the
@@ -704,6 +734,39 @@
             View navButton = mNavButtonContainer.getChildAt(i);
             LinearLayout.LayoutParams buttonLayoutParams =
                     (LinearLayout.LayoutParams) navButton.getLayoutParams();
+            buttonLayoutParams.weight = 0;
+            if (i == 0) {
+                buttonLayoutParams.setMarginEnd(spaceInBetween / 2);
+            } else if (i == mNavButtonContainer.getChildCount() - 1) {
+                buttonLayoutParams.setMarginStart(spaceInBetween / 2);
+            } else {
+                buttonLayoutParams.setMarginStart(spaceInBetween / 2);
+                buttonLayoutParams.setMarginEnd(spaceInBetween / 2);
+            }
+        }
+    }
+
+    /** Uniformly spaces out the 3 button nav for smaller phone screens */
+    private void updatePhoneButtonSpacing() {
+        DeviceProfile dp = mContext.getDeviceProfile();
+        Resources res = mContext.getResources();
+
+        // TODO: Polish pending, this is just to make it usable
+        FrameLayout.LayoutParams navContainerParams =
+                (FrameLayout.LayoutParams) mNavButtonContainer.getLayoutParams();
+        int endStartMargins = res.getDimensionPixelSize(R.dimen.taskbar_nav_buttons_size);
+        navContainerParams.gravity = Gravity.CENTER;
+        navContainerParams.setMarginEnd(endStartMargins);
+        navContainerParams.setMarginStart(endStartMargins);
+        mNavButtonContainer.setLayoutParams(navContainerParams);
+
+        // Add the spaces in between the nav buttons
+        int spaceInBetween = res.getDimensionPixelSize(R.dimen.taskbar_button_space_inbetween_phone);
+        for (int i = 0; i < mNavButtonContainer.getChildCount(); i++) {
+            View navButton = mNavButtonContainer.getChildAt(i);
+            LinearLayout.LayoutParams buttonLayoutParams =
+                    (LinearLayout.LayoutParams) navButton.getLayoutParams();
+            buttonLayoutParams.weight = 1;
             if (i == 0) {
                 buttonLayoutParams.setMarginEnd(spaceInBetween / 2);
             } else if (i == mNavButtonContainer.getChildCount() - 1) {
@@ -723,6 +786,8 @@
         }
 
         moveNavButtonsBackToTaskbarWindow();
+        mNavButtonContainer.removeAllViews();
+        mAllButtons.clear();
     }
 
     /**
diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
index 800e162..6b67b50 100644
--- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
@@ -25,6 +25,7 @@
 import android.view.View;
 import android.view.ViewOutlineProvider;
 
+import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.RevealOutlineAnimation;
@@ -55,9 +56,9 @@
     private final TaskbarActivityContext mActivity;
     private final SharedPreferences mPrefs;
     private final StashedHandleView mStashedHandleView;
-    private final int mStashedHandleWidth;
+    private int mStashedHandleWidth;
     private final int mStashedHandleHeight;
-    private final RegionSamplingHelper mRegionSamplingHelper;
+    private RegionSamplingHelper mRegionSamplingHelper;
     private final MultiValueAlpha mTaskbarStashedHandleAlpha;
     private final AnimatedFloat mTaskbarStashedHandleHintScale = new AnimatedFloat(
             this::updateStashedHandleHintScale);
@@ -85,30 +86,27 @@
                 mPrefs.getBoolean(SHARED_PREFS_STASHED_HANDLE_REGION_DARK_KEY, false),
                 false /* animate */);
         final Resources resources = mActivity.getResources();
-        mStashedHandleWidth = resources.getDimensionPixelSize(R.dimen.taskbar_stashed_handle_width);
         mStashedHandleHeight = resources.getDimensionPixelSize(
                 R.dimen.taskbar_stashed_handle_height);
-        mRegionSamplingHelper = new RegionSamplingHelper(mStashedHandleView,
-                new RegionSamplingHelper.SamplingCallback() {
-                    @Override
-                    public void onRegionDarknessChanged(boolean isRegionDark) {
-                        mStashedHandleView.updateHandleColor(isRegionDark, true /* animate */);
-                        mPrefs.edit().putBoolean(SHARED_PREFS_STASHED_HANDLE_REGION_DARK_KEY,
-                                isRegionDark).apply();
-                    }
-
-                    @Override
-                    public Rect getSampledRegion(View sampledView) {
-                        return mStashedHandleView.getSampledRegion();
-                    }
-                }, Executors.UI_HELPER_EXECUTOR);
     }
 
     public void init(TaskbarControllers controllers) {
         mControllers = controllers;
-        mStashedHandleView.getLayoutParams().height = mActivity.getDeviceProfile().taskbarSize;
+        DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+        Resources resources = mActivity.getResources();
+        if (isPhoneGestureNavMode(mActivity.getDeviceProfile())) {
+            mStashedHandleView.getLayoutParams().height =
+                    resources.getDimensionPixelSize(R.dimen.taskbar_size);
+            mStashedHandleWidth =
+                    resources.getDimensionPixelSize(R.dimen.taskbar_stashed_small_screen);
+        } else {
+            mStashedHandleView.getLayoutParams().height = deviceProfile.taskbarSize;
+            mStashedHandleWidth =
+                    resources.getDimensionPixelSize(R.dimen.taskbar_stashed_handle_width);
+        }
 
-        mTaskbarStashedHandleAlpha.getProperty(ALPHA_INDEX_STASHED).setValue(0);
+        mTaskbarStashedHandleAlpha.getProperty(ALPHA_INDEX_STASHED).setValue(
+                isPhoneGestureNavMode(deviceProfile) ? 1 : 0);
         mTaskbarStashedHandleHintScale.updateValue(1f);
 
         final int stashedTaskbarHeight = mControllers.taskbarStashController.getStashedHeight();
@@ -135,10 +133,37 @@
             view.setPivotX(stashedCenterX);
             view.setPivotY(stashedCenterY);
         });
+        initRegionSampler();
+        if (isPhoneGestureNavMode(deviceProfile)) {
+            onIsStashedChanged(true);
+        }
     }
 
+    private void initRegionSampler() {
+        mRegionSamplingHelper = new RegionSamplingHelper(mStashedHandleView,
+                new RegionSamplingHelper.SamplingCallback() {
+                    @Override
+                    public void onRegionDarknessChanged(boolean isRegionDark) {
+                        mStashedHandleView.updateHandleColor(isRegionDark, true /* animate */);
+                        mPrefs.edit().putBoolean(SHARED_PREFS_STASHED_HANDLE_REGION_DARK_KEY,
+                                isRegionDark).apply();
+                    }
+
+                    @Override
+                    public Rect getSampledRegion(View sampledView) {
+                        return mStashedHandleView.getSampledRegion();
+                    }
+                }, Executors.UI_HELPER_EXECUTOR);
+    }
+
+
     public void onDestroy() {
         mRegionSamplingHelper.stopAndDestroy();
+        mRegionSamplingHelper = null;
+    }
+
+    private boolean isPhoneGestureNavMode(DeviceProfile deviceProfile) {
+        return TaskbarManager.isPhoneMode(deviceProfile) && !mActivity.isThreeButtonNav();
     }
 
     public MultiValueAlpha getStashedHandleAlpha() {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 2280b95..e1bcbe2 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -24,6 +24,7 @@
 import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
 import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_OPEN;
+import static com.android.launcher3.taskbar.TaskbarManager.FLAG_HIDE_NAVBAR_WINDOW;
 import static com.android.launcher3.testing.shared.ResourceUtils.getBoolByName;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
@@ -118,7 +119,7 @@
     // The size we should return to when we call setTaskbarWindowFullscreen(false)
     private int mLastRequestedNonFullscreenHeight;
 
-    private final NavigationMode mNavMode;
+    private NavigationMode mNavMode;
     private final boolean mImeDrawsImeNavBar;
     private final ViewCache mViewCache = new ViewCache();
 
@@ -130,6 +131,8 @@
     // The flag to know if the window is excluded from magnification region computation.
     private boolean mIsExcludeFromMagnificationRegion = false;
     private boolean mBindingItems = false;
+    private boolean mAddedWindow = false;
+
 
     private final TaskbarShortcutMenuAccessibilityDelegate mAccessibilityDelegate;
 
@@ -218,7 +221,12 @@
         mControllers.init(sharedState);
         updateSysuiStateFlags(sharedState.sysuiStateFlags, true /* fromInit */);
 
-        mWindowManager.addView(mDragLayer, mWindowLayoutParams);
+        if (!mAddedWindow) {
+            mWindowManager.addView(mDragLayer, mWindowLayoutParams);
+            mAddedWindow = true;
+        } else {
+            mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
+        }
     }
 
     @Override
@@ -227,7 +235,8 @@
     }
 
     /** Updates {@link DeviceProfile} instances for any Taskbar windows. */
-    public void updateDeviceProfile(DeviceProfile dp) {
+    public void updateDeviceProfile(DeviceProfile dp, NavigationMode navMode) {
+        mNavMode = navMode;
         mControllers.taskbarAllAppsController.updateDeviceProfile(dp);
         mDeviceProfile = dp.copy(this);
         updateIconSize(getResources());
@@ -461,7 +470,10 @@
         mIsDestroyed = true;
         setUIController(TaskbarUIController.DEFAULT);
         mControllers.onDestroy();
-        mWindowManager.removeViewImmediate(mDragLayer);
+        if (!FLAG_HIDE_NAVBAR_WINDOW) {
+            mWindowManager.removeViewImmediate(mDragLayer);
+            mAddedWindow = false;
+        }
     }
 
     public void updateSysuiStateFlags(int systemUiStateFlags, boolean fromInit) {
@@ -596,6 +608,12 @@
      * Returns the default height of the window, including the static corner radii above taskbar.
      */
     public int getDefaultTaskbarWindowHeight() {
+        if (FLAG_HIDE_NAVBAR_WINDOW && mDeviceProfile.isPhone) {
+            Resources resources = getResources();
+            return isThreeButtonNav() ?
+                    resources.getDimensionPixelSize(R.dimen.taskbar_size) :
+                    resources.getDimensionPixelSize(R.dimen.taskbar_stashed_size);
+        }
         return mDeviceProfile.taskbarSize + Math.max(getLeftCornerRadius(), getRightCornerRadius());
     }
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
index 1c8148b..ee17ad0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
@@ -86,8 +86,14 @@
         }
     }
 
+    protected void onDestroy(boolean forceDestroy) {
+        if (forceDestroy) {
+            ViewTreeObserverWrapper.removeOnComputeInsetsListener(mTaskbarInsetsComputer);
+        }
+    }
+
     protected void onDestroy() {
-        ViewTreeObserverWrapper.removeOnComputeInsetsListener(mTaskbarInsetsComputer);
+        onDestroy(!TaskbarManager.FLAG_HIDE_NAVBAR_WINDOW);
     }
 
     @Override
@@ -101,7 +107,7 @@
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
 
-        onDestroy();
+        onDestroy(true);
     }
 
     @Override
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
index 77ef83c..ec9760c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
@@ -18,6 +18,7 @@
 import android.content.res.Resources;
 import android.graphics.Rect;
 
+import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
 import com.android.launcher3.util.TouchController;
 import com.android.quickstep.AnimatedFloat;
@@ -173,7 +174,15 @@
          * Returns how tall the background should be drawn at the bottom of the screen.
          */
         public int getTaskbarBackgroundHeight() {
-            return mActivity.getDeviceProfile().taskbarSize;
+            DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+            if (TaskbarManager.isPhoneMode(deviceProfile)) {
+                Resources resources = mActivity.getResources();
+                return mActivity.isThreeButtonNav() ?
+                        resources.getDimensionPixelSize(R.dimen.taskbar_size) :
+                        resources.getDimensionPixelSize(R.dimen.taskbar_stashed_size);
+            } else {
+                return deviceProfile.taskbarSize;
+            }
         }
 
         /**
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index 85e76b2..0bda3cd 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -32,6 +32,7 @@
 
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.BaseQuickstepLauncher;
+import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.QuickstepTransitionManager;
 import com.android.launcher3.Utilities;
@@ -48,6 +49,7 @@
 import java.io.PrintWriter;
 import java.util.HashMap;
 import java.util.StringJoiner;
+import java.util.function.Consumer;
 import java.util.function.Supplier;
 
 /**
@@ -92,6 +94,15 @@
     // We skip any view synchronizations during init/destroy.
     private boolean mCanSyncViews;
 
+    private final Consumer<Float> mIconAlphaForHomeConsumer = alpha -> {
+        mLauncher.getHotseat().setIconsAlpha(alpha > 0 ? 0 : 1);
+        mLauncher.getHotseat().setQsbAlpha(
+                mLauncher.getDeviceProfile().isQsbInline && alpha > 0 ? 0 : 1);
+    };
+
+    private final DeviceProfile.OnDeviceProfileChangeListener mOnDeviceProfileChangeListener =
+            dp -> mIconAlphaForHomeConsumer.accept(mIconAlphaForHome.getValue());
+
     private final StateManager.StateListener<LauncherState> mStateListener =
             new StateManager.StateListener<LauncherState>() {
 
@@ -131,13 +142,7 @@
                 .getTaskbarBackgroundAlpha();
         MultiValueAlpha taskbarIconAlpha = mControllers.taskbarViewController.getTaskbarIconAlpha();
         mIconAlphaForHome = taskbarIconAlpha.getProperty(ALPHA_INDEX_HOME);
-        mIconAlphaForHome.setConsumer(
-                alpha -> {
-                    mLauncher.getHotseat().setIconsAlpha(alpha > 0 ? 0 : 1);
-                    if (mLauncher.getDeviceProfile().isQsbInline) {
-                        mLauncher.getHotseat().setQsbAlpha(alpha > 0 ? 0 : 1);
-                    }
-                });
+        mIconAlphaForHome.setConsumer(mIconAlphaForHomeConsumer);
 
         mIconAlignmentForResumedState.finishAnimation();
         onIconAlignmentRatioChangedForAppAndHomeTransition();
@@ -150,6 +155,7 @@
         applyState(0);
 
         mCanSyncViews = true;
+        mLauncher.addOnDeviceProfileChangeListener(mOnDeviceProfileChangeListener);
     }
 
     public void onDestroy() {
@@ -164,6 +170,7 @@
         mLauncher.getStateManager().removeStateListener(mStateListener);
 
         mCanSyncViews = true;
+        mLauncher.removeOnDeviceProfileChangeListener(mOnDeviceProfileChangeListener);
     }
 
     public Animator createAnimToLauncher(@NonNull LauncherState toState,
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index 06262c0..1212c61 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -30,6 +30,7 @@
 import android.hardware.display.DisplayManager;
 import android.net.Uri;
 import android.os.Handler;
+import android.os.SystemProperties;
 import android.provider.Settings;
 import android.view.Display;
 
@@ -58,6 +59,9 @@
  */
 public class TaskbarManager {
 
+    public static final boolean FLAG_HIDE_NAVBAR_WINDOW =
+            SystemProperties.getBoolean("persist.wm.debug.hide_navbar_window", false);
+
     private static final Uri USER_SETUP_COMPLETE_URI = Settings.Secure.getUriFor(
             Settings.Secure.USER_SETUP_COMPLETE);
 
@@ -78,6 +82,7 @@
     // It's destruction/creation will be managed by the activity.
     private final ScopedUnfoldTransitionProgressProvider mUnfoldProgressProvider =
             new NonDestroyableScopedUnfoldTransitionProgressProvider();
+    private DisplayController.NavigationMode mNavMode;
 
     private TaskbarActivityContext mTaskbarActivityContext;
     private StatefulActivity mActivity;
@@ -128,9 +133,11 @@
                         | ActivityInfo.CONFIG_SCREEN_SIZE;
                 boolean requiresRecreate = (configDiff & configsRequiringRecreate) != 0;
                 if ((configDiff & ActivityInfo.CONFIG_SCREEN_SIZE) != 0
-                        && mTaskbarActivityContext != null && dp != null) {
+                        && mTaskbarActivityContext != null && dp != null
+                        && !isPhoneMode(dp)) {
                     // Additional check since this callback gets fired multiple times w/o
                     // screen size changing, or when simply rotating the device.
+                    // In the case of phone device rotation, we do want to call recreateTaskbar()
                     DeviceProfile oldDp = mTaskbarActivityContext.getDeviceProfile();
                     boolean isOrientationChange =
                             (configDiff & ActivityInfo.CONFIG_ORIENTATION) != 0;
@@ -147,8 +154,8 @@
                 } else {
                     // Config change might be handled without re-creating the taskbar
                     if (mTaskbarActivityContext != null) {
-                        if (dp != null && dp.isTaskbarPresent) {
-                            mTaskbarActivityContext.updateDeviceProfile(dp);
+                        if (dp != null && isTaskbarPresent(dp)) {
+                            mTaskbarActivityContext.updateDeviceProfile(dp, mNavMode);
                         }
                         mTaskbarActivityContext.onConfigurationChanged(configDiff);
                     }
@@ -159,12 +166,15 @@
             @Override
             public void onLowMemory() { }
         };
-        mShutdownReceiver = new SimpleBroadcastReceiver(i -> destroyExistingTaskbar());
+        mShutdownReceiver = new SimpleBroadcastReceiver(i ->
+                destroyExistingTaskbar());
         mDispInfoChangeListener = (context, info, flags) -> {
             if ((flags & CHANGE_FLAGS) != 0) {
+                mNavMode = info.navigationMode;
                 recreateTaskbar();
             }
         };
+        mNavMode = mDisplayController.getInfo().navigationMode;
         mDisplayController.addChangeListener(mDispInfoChangeListener);
         SettingsCache.INSTANCE.get(mContext).register(USER_SETUP_COMPLETE_URI,
                 mUserSetupCompleteListener);
@@ -179,7 +189,9 @@
     private void destroyExistingTaskbar() {
         if (mTaskbarActivityContext != null) {
             mTaskbarActivityContext.onDestroy();
-            mTaskbarActivityContext = null;
+            if (!FLAG_HIDE_NAVBAR_WINDOW) {
+                mTaskbarActivityContext = null;
+            }
         }
     }
 
@@ -260,24 +272,32 @@
         }
     }
 
+    /**
+     * This method is called multiple times (ex. initial init, then when user unlocks) in which case
+     * we fully want to destroy an existing taskbar and create a new one.
+     * In other case (folding/unfolding) we don't need to remove and add window.
+     */
     private void recreateTaskbar() {
+        DeviceProfile dp = mUserUnlocked ?
+                LauncherAppState.getIDP(mContext).getDeviceProfile(mContext) : null;
+
         destroyExistingTaskbar();
 
-        DeviceProfile dp =
-                mUserUnlocked ? LauncherAppState.getIDP(mContext).getDeviceProfile(mContext) : null;
-
-        boolean isTaskBarEnabled = dp != null && dp.isTaskbarPresent;
-
+        boolean isTaskBarEnabled = dp != null && isTaskbarPresent(dp);
         if (!isTaskBarEnabled) {
             SystemUiProxy.INSTANCE.get(mContext)
                     .notifyTaskbarStatus(/* visible */ false, /* stashed */ false);
             return;
         }
 
-        mTaskbarActivityContext = new TaskbarActivityContext(mContext, dp, mNavButtonController,
-                mUnfoldProgressProvider);
-
+        if (mTaskbarActivityContext == null) {
+            mTaskbarActivityContext = new TaskbarActivityContext(mContext, dp, mNavButtonController,
+                    mUnfoldProgressProvider);
+        } else {
+            mTaskbarActivityContext.updateDeviceProfile(dp, mNavMode);
+        }
         mTaskbarActivityContext.init(mSharedState);
+
         if (mActivity != null) {
             mTaskbarActivityContext.setUIController(
                     createTaskbarUIControllerForActivity(mActivity));
@@ -301,6 +321,26 @@
         }
     }
 
+    /**
+     * @return {@code true} if provided device profile isn't a large screen profile
+     *                      and we are using a single window for taskbar and navbar.
+     */
+    public static boolean isPhoneMode(DeviceProfile deviceProfile) {
+        return TaskbarManager.FLAG_HIDE_NAVBAR_WINDOW && deviceProfile.isPhone;
+    }
+
+    /**
+     * @return {@code true} if {@link #isPhoneMode(DeviceProfile)} is true and we're using
+     *                      3 button-nav
+     */
+    public static boolean isPhoneButtonNavMode(TaskbarActivityContext context) {
+        return isPhoneMode(context.getDeviceProfile()) && context.isThreeButtonNav();
+    }
+
+    private boolean isTaskbarPresent(DeviceProfile deviceProfile) {
+        return FLAG_HIDE_NAVBAR_WINDOW || deviceProfile.isTaskbarPresent;
+    }
+
     public void onRotationProposal(int rotation, boolean isValid) {
         if (mTaskbarActivityContext != null) {
             mTaskbarActivityContext.onRotationProposal(rotation, isValid);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 8533145..3ea9173 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -30,6 +30,7 @@
 import android.animation.AnimatorSet;
 import android.annotation.Nullable;
 import android.content.SharedPreferences;
+import android.content.res.Resources;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewConfiguration;
@@ -38,6 +39,7 @@
 
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.AnimatorListeners;
 import com.android.launcher3.testing.shared.TestProtocol;
@@ -69,6 +71,7 @@
     public static final int FLAG_IN_STASHED_LAUNCHER_STATE = 1 << 6;
     public static final int FLAG_STASHED_IN_APP_ALL_APPS = 1 << 7; // All apps is visible.
     public static final int FLAG_IN_SETUP = 1 << 8; // In the Setup Wizard
+    public static final int FLAG_STASHED_SMALL_SCREEN = 1 << 9; // phone screen gesture nav, stashed
 
     // If any of these flags are enabled, isInApp should return true.
     private static final int FLAGS_IN_APP = FLAG_IN_APP | FLAG_IN_SETUP;
@@ -76,7 +79,8 @@
     // If we're in an app and any of these flags are enabled, taskbar should be stashed.
     private static final int FLAGS_STASHED_IN_APP = FLAG_STASHED_IN_APP_MANUAL
             | FLAG_STASHED_IN_APP_PINNED | FLAG_STASHED_IN_APP_EMPTY | FLAG_STASHED_IN_APP_SETUP
-            | FLAG_STASHED_IN_APP_IME | FLAG_STASHED_IN_APP_ALL_APPS;
+            | FLAG_STASHED_IN_APP_IME | FLAG_STASHED_IN_APP_ALL_APPS |
+            FLAG_STASHED_SMALL_SCREEN;
 
     private static final int FLAGS_STASHED_IN_APP_IGNORING_IME =
             FLAGS_STASHED_IN_APP & ~FLAG_STASHED_IN_APP_IME;
@@ -166,15 +170,25 @@
                 boolean inApp = hasAnyFlag(flags, FLAGS_IN_APP);
                 boolean stashedInApp = hasAnyFlag(flags, FLAGS_STASHED_IN_APP);
                 boolean stashedLauncherState = hasAnyFlag(flags, FLAG_IN_STASHED_LAUNCHER_STATE);
-                return (inApp && stashedInApp) || (!inApp && stashedLauncherState);
+                boolean stashedForSmallScreen = hasAnyFlag(flags, FLAG_STASHED_SMALL_SCREEN);
+                return (inApp && stashedInApp) || (!inApp && stashedLauncherState)
+                        || stashedForSmallScreen;
             });
 
     public TaskbarStashController(TaskbarActivityContext activity) {
         mActivity = activity;
         mPrefs = Utilities.getPrefs(mActivity);
         mSystemUiProxy = SystemUiProxy.INSTANCE.get(activity);
-        mUnstashedHeight = mActivity.getDeviceProfile().taskbarSize;
-        mStashedHeight = mActivity.getDeviceProfile().stashedTaskbarSize;
+        if (isPhoneMode()) {
+            // DeviceProfile's taskbar vars aren't initialized w/ the flag off
+            Resources resources = mActivity.getResources();
+            mUnstashedHeight = resources.getDimensionPixelSize(R.dimen.taskbar_size);
+            mStashedHeight = resources.getDimensionPixelOffset(R.dimen.taskbar_stashed_size);
+        } else {
+            mUnstashedHeight = mActivity.getDeviceProfile().taskbarSize;
+            mStashedHeight = mActivity.getDeviceProfile().stashedTaskbarSize;
+        }
+
     }
 
     public void init(TaskbarControllers controllers, boolean setupUIVisible) {
@@ -202,6 +216,8 @@
         updateStateForFlag(FLAG_STASHED_IN_APP_MANUAL, isManuallyStashedInApp);
         updateStateForFlag(FLAG_STASHED_IN_APP_SETUP, isInSetup);
         updateStateForFlag(FLAG_IN_SETUP, isInSetup);
+        updateStateForFlag(FLAG_STASHED_SMALL_SCREEN, isPhoneMode()
+                && !mActivity.isThreeButtonNav());
         applyState();
 
         notifyStashChange(/* visible */ false, /* stashed */ isStashedInApp());
@@ -212,7 +228,8 @@
      * state.
      */
     public boolean supportsVisualStashing() {
-        return mControllers.uiController.supportsVisualStashing();
+        return mControllers.uiController.supportsVisualStashing() ||
+                (isPhoneMode() && !mActivity.isThreeButtonNav());
     }
 
     /**
@@ -266,7 +283,14 @@
      * Returns whether the taskbar should be stashed in the current LauncherState.
      */
     public boolean isInStashedLauncherState() {
-        return hasAnyFlag(FLAG_IN_STASHED_LAUNCHER_STATE) && supportsVisualStashing();
+        return (hasAnyFlag(FLAG_IN_STASHED_LAUNCHER_STATE) && supportsVisualStashing());
+    }
+
+    /**
+     * @return {@code true} if we're not on a large screen AND using gesture nav
+     */
+    private boolean isPhoneMode() {
+        return TaskbarManager.isPhoneMode(mActivity.getDeviceProfile());
     }
 
     private boolean hasAnyFlag(int flagMask) {
@@ -295,6 +319,10 @@
      * @see WindowInsets.Type#systemBars()
      */
     public int getContentHeightToReportToApps() {
+        if (isPhoneMode() && !mActivity.isThreeButtonNav()) {
+            return getStashedHeight();
+        }
+
         if (supportsVisualStashing() && hasAnyFlag(FLAGS_REPORT_STASHED_INSETS_TO_APP)) {
             DeviceProfile dp = mActivity.getDeviceProfile();
             if (hasAnyFlag(FLAG_STASHED_IN_APP_SETUP) && dp.isTaskbarPresent && !dp.isLandscape) {
@@ -410,11 +438,18 @@
         }
         mAnimator = new AnimatorSet();
         addJankMonitorListener(mAnimator, /* appearing= */ !mIsStashed);
+        final float stashTranslation = isPhoneMode() ? 0 :
+                (mUnstashedHeight - mStashedHeight) / 2f;
 
         if (!supportsVisualStashing()) {
             // Just hide/show the icons and background instead of stashing into a handle.
             mAnimator.play(mIconAlphaForStash.animateToValue(isStashed ? 0 : 1)
                     .setDuration(duration));
+            mAnimator.playTogether(mTaskbarBackgroundOffset.animateToValue(isStashed ? 1 : 0)
+                    .setDuration(duration));
+            mAnimator.playTogether(mIconTranslationYForStash.animateToValue(isStashed ?
+                            stashTranslation : 0)
+                    .setDuration(duration));
             mAnimator.play(mTaskbarImeBgAlpha.animateToValue(
                     hasAnyFlag(FLAG_STASHED_IN_APP_IME) ? 0 : 1).setDuration(duration));
             mAnimator.setStartDelay(startDelay);
@@ -438,7 +473,6 @@
         if (isStashed) {
             firstHalfDurationScale = 0.75f;
             secondHalfDurationScale = 0.5f;
-            final float stashTranslation = (mUnstashedHeight - mStashedHeight) / 2f;
 
             fullLengthAnimatorSet.play(mIconTranslationYForStash.animateToValue(stashTranslation));
             if (animateBg) {
@@ -450,7 +484,8 @@
 
             firstHalfAnimatorSet.playTogether(
                     mIconAlphaForStash.animateToValue(0),
-                    mIconScaleForStash.animateToValue(STASHED_TASKBAR_SCALE)
+                    mIconScaleForStash.animateToValue(isPhoneMode() ?
+                            0 : STASHED_TASKBAR_SCALE)
             );
             secondHalfAnimatorSet.playTogether(
                     mTaskbarStashedHandleAlpha.animateToValue(1)
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index ea15acb..dbf9759 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -314,10 +314,10 @@
                 int qsbEnd;
                 if (layoutRtl) {
                     qsbStart = iconEnd + mItemMarginLeftRight;
-                    qsbEnd = qsbStart + deviceProfile.qsbWidth;
+                    qsbEnd = qsbStart + deviceProfile.hotseatQsbWidth;
                 } else {
                     qsbEnd = iconEnd - mItemMarginLeftRight;
-                    qsbStart = qsbEnd - deviceProfile.qsbWidth;
+                    qsbStart = qsbEnd - deviceProfile.hotseatQsbWidth;
                 }
                 int qsbTop = (bottom - top - deviceProfile.hotseatQsbHeight) / 2;
                 int qsbBottom = qsbTop + deviceProfile.hotseatQsbHeight;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index 077172d..992aa4b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -20,6 +20,7 @@
 import static com.android.launcher3.Utilities.squaredHypot;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_ALLAPPS_BUTTON_TAP;
+import static com.android.launcher3.taskbar.TaskbarManager.isPhoneMode;
 import static com.android.quickstep.AnimatedFloat.VALUE;
 
 import android.annotation.NonNull;
@@ -35,6 +36,7 @@
 import com.android.launcher3.BubbleTextView;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.AlphaUpdateListener;
 import com.android.launcher3.anim.AnimatorPlaybackController;
@@ -69,7 +71,8 @@
     public static final int ALPHA_INDEX_NOTIFICATION_EXPANDED = 4;
     public static final int ALPHA_INDEX_ASSISTANT_INVOKED = 5;
     public static final int ALPHA_INDEX_IME_BUTTON_NAV = 6;
-    private static final int NUM_ALPHA_CHANNELS = 7;
+    public static final int ALPHA_INDEX_SMALL_SCREEN = 7;
+    private static final int NUM_ALPHA_CHANNELS = 8;
 
     private final TaskbarActivityContext mActivity;
     private final TaskbarView mTaskbarView;
@@ -108,7 +111,9 @@
     public void init(TaskbarControllers controllers) {
         mControllers = controllers;
         mTaskbarView.init(new TaskbarViewCallbacks());
-        mTaskbarView.getLayoutParams().height = mActivity.getDeviceProfile().taskbarSize;
+        mTaskbarView.getLayoutParams().height = isPhoneMode(mActivity.getDeviceProfile())
+                ? mActivity.getResources().getDimensionPixelSize(R.dimen.taskbar_size)
+                : mActivity.getDeviceProfile().taskbarSize;
         mThemeIconsColor = ThemedIconDrawable.getColors(mTaskbarView.getContext())[0];
 
         mTaskbarIconScaleForStash.updateValue(1f);
@@ -291,10 +296,11 @@
                 boolean isRtl = Utilities.isRtl(child.getResources());
                 float hotseatIconCenter = isRtl
                         ? launcherDp.widthPx - hotseatPadding.right + borderSpacing
-                        + launcherDp.qsbWidth / 2f
-                        : hotseatPadding.left - borderSpacing - launcherDp.qsbWidth / 2f;
+                        + launcherDp.hotseatQsbWidth / 2f
+                        : hotseatPadding.left - borderSpacing - launcherDp.hotseatQsbWidth / 2f;
                 float childCenter = (child.getLeft() + child.getRight()) / 2f;
-                float halfQsbIconWidthDiff = (launcherDp.qsbWidth - taskbarDp.iconSizePx) / 2f;
+                float halfQsbIconWidthDiff =
+                        (launcherDp.hotseatQsbWidth - taskbarDp.iconSizePx) / 2f;
                 setter.addFloat(child, ICON_TRANSLATE_X,
                         isRtl ? -halfQsbIconWidthDiff : halfQsbIconWidthDiff,
                         hotseatIconCenter - childCenter, LINEAR);
@@ -308,7 +314,7 @@
                                 : Interpolators.clampToProgress(LINEAR, 0.84f, 1f));
                 setter.addOnFrameListener(animator -> AlphaUpdateListener.updateVisibility(child));
 
-                float qsbInsetFraction = halfQsbIconWidthDiff / launcherDp.qsbWidth;
+                float qsbInsetFraction = halfQsbIconWidthDiff / launcherDp.hotseatQsbWidth;
                 if (child instanceof  HorizontalInsettableView) {
                     setter.addFloat((HorizontalInsettableView) child,
                             HorizontalInsettableView.HORIZONTAL_INSETS, qsbInsetFraction, 0,
@@ -385,7 +391,8 @@
                 "ALPHA_INDEX_RECENTS_DISABLED",
                 "ALPHA_INDEX_NOTIFICATION_EXPANDED",
                 "ALPHA_INDEX_ASSISTANT_INVOKED",
-                "ALPHA_INDEX_IME_BUTTON_NAV");
+                "ALPHA_INDEX_IME_BUTTON_NAV",
+                "ALPHA_INDEX_SMALL_SCREEN");
 
         mModelCallbacks.dumpLogs(prefix + "\t", pw);
     }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
index f220509..ea0972f 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
@@ -28,7 +28,6 @@
 import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
 import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
 import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
-import static com.android.launcher3.testing.shared.TestProtocol.BAD_STATE;
 import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
 import static com.android.quickstep.views.RecentsView.FIRST_FLOATING_TASK_TRANSLATE_OFFSCREEN;
 import static com.android.quickstep.views.RecentsView.OVERVIEW_PROGRESS;
@@ -40,7 +39,6 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.util.FloatProperty;
-import android.util.Log;
 
 import androidx.annotation.NonNull;
 
@@ -77,10 +75,7 @@
         ADJACENT_PAGE_HORIZONTAL_OFFSET.set(mRecentsView, scaleAndOffset[1]);
         TASK_SECONDARY_TRANSLATION.set(mRecentsView, 0f);
 
-        float recentsAlpha = state.overviewUi ? 1f : 0;
-        Log.d(BAD_STATE, "BaseRecentsViewStateController setState state=" + state
-                + ", alpha=" + recentsAlpha);
-        getContentAlphaProperty().set(mRecentsView, recentsAlpha);
+        getContentAlphaProperty().set(mRecentsView, state.overviewUi ? 1f : 0);
         getTaskModalnessProperty().set(mRecentsView, state.getOverviewModalness());
         RECENTS_GRID_PROGRESS.set(mRecentsView,
                 state.displayOverviewTasksAsGrid(mLauncher.getDeviceProfile()) ? 1f : 0f);
@@ -90,8 +85,6 @@
     @Override
     public void setStateWithAnimation(LauncherState toState, StateAnimationConfig config,
             PendingAnimation builder) {
-        Log.d(BAD_STATE, "BaseRecentsViewStateController setStateWithAnimation state=" + toState
-                + ", config.skipOverview=" + config.hasAnimationFlag(SKIP_OVERVIEW));
         if (config.hasAnimationFlag(SKIP_OVERVIEW)) {
             return;
         }
@@ -158,10 +151,7 @@
             }
         }
 
-        float recentsAlpha = toState.overviewUi ? 1 : 0;
-        Log.d(BAD_STATE, "BaseRecentsViewStateController setStateWithAnimationInternal toState="
-                + toState + ", alpha=" + recentsAlpha);
-        setter.setFloat(mRecentsView, getContentAlphaProperty(), recentsAlpha,
+        setter.setFloat(mRecentsView, getContentAlphaProperty(), toState.overviewUi ? 1 : 0,
                 config.getInterpolator(ANIM_OVERVIEW_FADE, AGGRESSIVE_EASE_IN_OUT));
 
         setter.setFloat(
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index 4092a73..bc76487 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -39,7 +39,6 @@
 import static com.android.launcher3.states.StateAnimationConfig.SKIP_ALL_ANIMATIONS;
 import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
 import static com.android.launcher3.states.StateAnimationConfig.SKIP_SCRIM;
-import static com.android.launcher3.testing.shared.TestProtocol.BAD_STATE;
 import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_RIGHT;
 import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_UP;
 import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
@@ -56,7 +55,6 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
 import android.graphics.PointF;
-import android.util.Log;
 import android.view.MotionEvent;
 import android.view.animation.Interpolator;
 
@@ -227,7 +225,6 @@
         // Set RecentView's initial properties.
         RECENTS_SCALE_PROPERTY.set(mRecentsView, fromState.getOverviewScaleAndOffset(mLauncher)[0]);
         ADJACENT_PAGE_HORIZONTAL_OFFSET.set(mRecentsView, 1f);
-        Log.d(BAD_STATE, "NBQSTC setupOverviewAnimators setContentAlpha=1");
         mRecentsView.setContentAlpha(1);
         mRecentsView.setFullscreenProgress(fromState.getOverviewFullscreenProgress());
         mLauncher.getActionsView().getVisibilityAlpha().setValue(
@@ -247,24 +244,6 @@
                 QUICK_SWITCH.getWorkspaceScrimColor(mLauncher), LINEAR);
         if (mRecentsView.getTaskViewCount() == 0) {
             xAnim.addFloat(mRecentsView, CONTENT_ALPHA, 0f, 1f, LINEAR);
-            Log.d(BAD_STATE, "NBQSTC setupOverviewAnimators from: 0 to: 1");
-            xAnim.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationStart(Animator animation) {
-                    Log.d(BAD_STATE, "NBQSTC setupOverviewAnimators onStart");
-                }
-
-                @Override
-                public void onAnimationCancel(Animator animation) {
-                    float alpha = mRecentsView == null ? -1 : CONTENT_ALPHA.get(mRecentsView);
-                    Log.d(BAD_STATE, "NBQSTC setupOverviewAnimators onCancel, alpha=" + alpha);
-                }
-
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    Log.d(BAD_STATE, "NBQSTC setupOverviewAnimators onEnd");
-                }
-            });
         }
         mXOverviewAnim = xAnim.createPlaybackController();
         mXOverviewAnim.dispatchOnStart();
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
index f607aa3..e5cd53a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
@@ -29,7 +29,6 @@
 import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
 import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
 import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
-import static com.android.launcher3.testing.shared.TestProtocol.BAD_STATE;
 import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK;
 import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
 import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
@@ -37,7 +36,6 @@
 import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
 
-import android.util.Log;
 import android.view.MotionEvent;
 
 import com.android.launcher3.Launcher;
@@ -114,7 +112,6 @@
         RECENTS_SCALE_PROPERTY.set(mOverviewPanel,
                 QUICK_SWITCH.getOverviewScaleAndOffset(mLauncher)[0] * 0.85f);
         ADJACENT_PAGE_HORIZONTAL_OFFSET.set(mOverviewPanel, 1f);
-        Log.d(BAD_STATE, "QuickSwitchTouchController initCurrentAnimation setContentAlpha=1");
         mOverviewPanel.setContentAlpha(1);
 
         mCurrentAnimation = mLauncher.getStateManager()
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 8f1872b..8dee10a 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -1330,7 +1330,8 @@
                 if (windowAnimation == null) {
                     continue;
                 }
-                windowAnimation.start(mContext, velocityPxPerMs);
+                DeviceProfile dp = mActivity == null ? null : mActivity.getDeviceProfile();
+                windowAnimation.start(mContext, dp, velocityPxPerMs);
                 mRunningWindowAnim[i] = RunningWindowAnim.wrap(windowAnimation);
             }
             homeAnimFactory.setSwipeVelocity(velocityPxPerMs.y);
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index 98824eb..3e3a431 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -15,15 +15,11 @@
  */
 package com.android.quickstep;
 
-import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
-import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
-
 import static com.android.launcher3.QuickstepTransitionManager.RECENTS_LAUNCH_DURATION;
 import static com.android.launcher3.QuickstepTransitionManager.STATUS_BAR_TRANSITION_DURATION;
 import static com.android.launcher3.QuickstepTransitionManager.STATUS_BAR_TRANSITION_PRE_DELAY;
 import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
 import static com.android.launcher3.graphics.SysUiScrim.SYSUI_PROGRESS;
-import static com.android.launcher3.testing.shared.TestProtocol.BAD_STATE;
 import static com.android.launcher3.testing.shared.TestProtocol.OVERVIEW_STATE_ORDINAL;
 import static com.android.quickstep.OverviewComponentObserver.startHomeIntentSafely;
 import static com.android.quickstep.TaskUtils.taskIsATargetWithMode;
@@ -39,7 +35,6 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
-import android.util.Log;
 import android.view.Display;
 import android.view.SurfaceControl.Transaction;
 import android.view.View;
@@ -112,8 +107,6 @@
     private @Nullable TaskbarManager mTaskbarManager;
     private @Nullable FallbackTaskbarUIController mTaskbarUIController;
 
-    private Configuration mOldConfig;
-
     private StateManager<RecentsState> mStateManager;
 
     // Strong refs to runners which are cleared when the activity is destroyed
@@ -165,7 +158,7 @@
 
     @Override
     public void onMultiWindowModeChanged(boolean isInMultiWindowMode, Configuration newConfig) {
-        onHandleConfigChanged();
+        onHandleConfigurationChanged();
         super.onMultiWindowModeChanged(isInMultiWindowMode, newConfig);
     }
 
@@ -175,11 +168,8 @@
         ACTIVITY_TRACKER.handleNewIntent(this);
     }
 
-    /**
-         * Logic for when device configuration changes (rotation, screen size change, multi-window,
-         * etc.)
-         */
-    protected void onHandleConfigChanged() {
+    @Override
+    protected void onHandleConfigurationChanged() {
         initDeviceProfile();
 
         AbstractFloatingView.closeOpenViews(this, true,
@@ -314,7 +304,6 @@
     protected void onStart() {
         // Set the alpha to 1 before calling super, as it may get set back to 0 due to
         // onActivityStart callback.
-        Log.d(BAD_STATE, "RecentsActivity onStart mFallbackRecentsView.setContentAlpha(1)");
         mFallbackRecentsView.setContentAlpha(1);
         super.onStart();
         mFallbackRecentsView.updateLocusId();
@@ -341,7 +330,6 @@
 
         mStateManager = new StateManager<>(this, RecentsState.BG_LAUNCHER);
 
-        mOldConfig = new Configuration(getResources().getConfiguration());
         initDeviceProfile();
         setupViews();
 
@@ -351,16 +339,6 @@
     }
 
     @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        int diff = newConfig.diff(mOldConfig);
-        if ((diff & (CONFIG_ORIENTATION | CONFIG_SCREEN_SIZE)) != 0) {
-            onHandleConfigChanged();
-        }
-        mOldConfig.setTo(newConfig);
-        super.onConfigurationChanged(newConfig);
-    }
-
-    @Override
     public void onStateSetEnd(RecentsState state) {
         super.onStateSetEnd(state);
 
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
index 51ae56b..c602324 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
@@ -16,7 +16,6 @@
 package com.android.quickstep;
 
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME;
 
 import android.graphics.Rect;
 import android.util.ArraySet;
@@ -97,18 +96,6 @@
             RemoteAnimationTargetCompat[] appTargets,
             RemoteAnimationTargetCompat[] wallpaperTargets,
             Rect homeContentInsets, Rect minimizedHomeBounds) {
-        // Convert appTargets to type RemoteAnimationTarget for all apps except Home app
-        RemoteAnimationTarget[] nonHomeApps = Arrays.stream(appTargets)
-                .filter(remoteAnimationTarget ->
-                        remoteAnimationTarget.activityType != ACTIVITY_TYPE_HOME)
-                .map(RemoteAnimationTargetCompat::unwrap)
-                .toArray(RemoteAnimationTarget[]::new);
-
-        RemoteAnimationTarget[] nonAppTargets = mSystemUiProxy.onGoingToRecentsLegacy(nonHomeApps);
-
-        RecentsAnimationTargets targets = new RecentsAnimationTargets(appTargets,
-                wallpaperTargets, RemoteAnimationTargetCompat.wrap(nonAppTargets),
-                homeContentInsets, minimizedHomeBounds);
         mController = new RecentsAnimationController(animationController,
                 mAllowMinimizeSplitScreen, this::onAnimationFinished);
 
@@ -116,6 +103,13 @@
             Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(),
                     mController::finishAnimationToApp);
         } else {
+            final RemoteAnimationTarget[] nonAppTargets = mSystemUiProxy.onGoingToRecentsLegacy(
+                    Arrays.stream(appTargets).map(RemoteAnimationTargetCompat::unwrap)
+                            .toArray(RemoteAnimationTarget[]::new));
+            final RecentsAnimationTargets targets = new RecentsAnimationTargets(appTargets,
+                    wallpaperTargets, RemoteAnimationTargetCompat.wrap(nonAppTargets),
+                    homeContentInsets, minimizedHomeBounds);
+
             Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
                 for (RecentsAnimationListener listener : getListeners()) {
                     listener.onRecentsAnimationStart(mController, targets);
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index fd7e367..0314761 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -45,7 +45,7 @@
 import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.shared.system.TaskStackChangeListeners;
 
-import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 
 public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAnimationListener {
@@ -156,30 +156,21 @@
             public void onTasksAppeared(RemoteAnimationTargetCompat[] appearedTaskTargets) {
                 RemoteAnimationTargetCompat appearedTaskTarget = appearedTaskTargets[0];
                 BaseActivityInterface activityInterface = mLastGestureState.getActivityInterface();
-                // Convert appTargets to type RemoteAnimationTarget for all apps except Home app
-                final ArrayList<RemoteAnimationTargetCompat> tmpNonHomeApps = new ArrayList<>();
-                final ArrayList<RemoteAnimationTargetCompat> tmpHomeApps = new ArrayList<>();
+
                 for (RemoteAnimationTargetCompat compat : appearedTaskTargets) {
-                    if (compat.activityType != ACTIVITY_TYPE_HOME) {
-                        tmpNonHomeApps.add(compat);
-                    } else {
-                        tmpHomeApps.add(compat);
+                    if (compat.activityType == ACTIVITY_TYPE_HOME
+                            && activityInterface.getCreatedActivity() instanceof RecentsActivity) {
+                        // When receive opening home activity while recents is running, enter home
+                        // and dismiss recents.
+                        ((RecentsActivity) activityInterface.getCreatedActivity()).startHome();
+                        return;
                     }
                 }
-                RemoteAnimationTarget[] nonHomeApps = tmpNonHomeApps.stream()
-                        .map(RemoteAnimationTargetCompat::unwrap)
-                        .toArray(RemoteAnimationTarget[]::new);
-                RemoteAnimationTarget[] homeApps = tmpHomeApps.stream()
-                        .map(RemoteAnimationTargetCompat::unwrap)
-                        .toArray(RemoteAnimationTarget[]::new);
-                if (homeApps.length > 0
-                        && activityInterface.getCreatedActivity() instanceof RecentsActivity) {
-                    ((RecentsActivity) activityInterface.getCreatedActivity()).startHome();
-                    return;
-                }
 
-                RemoteAnimationTarget[] nonAppTargets =
-                        SystemUiProxy.INSTANCE.getNoCreate().onStartingSplitLegacy(nonHomeApps);
+                RemoteAnimationTarget[] nonAppTargets = SystemUiProxy.INSTANCE.getNoCreate()
+                        .onStartingSplitLegacy(Arrays.stream(appearedTaskTargets)
+                                .map(RemoteAnimationTargetCompat::unwrap)
+                                .toArray(RemoteAnimationTarget[]::new));
 
                 if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityInterface.isInLiveTileMode()
                         && activityInterface.getCreatedActivity() != null) {
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 c28fc9d..a809c9c 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -37,7 +37,6 @@
 import static com.android.launcher3.anim.Interpolators.clampToProgress;
 import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
 import static com.android.launcher3.statehandlers.DepthController.DEPTH;
-import static com.android.launcher3.testing.shared.TestProtocol.BAD_STATE;
 import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
 import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
 
@@ -55,7 +54,6 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.os.Build;
-import android.util.Log;
 import android.view.SurfaceControl;
 import android.view.View;
 import android.window.TransitionInfo;
@@ -391,10 +389,39 @@
      * device is considered in multiWindowMode and things like insets and stuff change
      * and calculations have to be adjusted in the animations for that
      */
-    public static void composeRecentsSplitLaunchAnimator(int initialTaskId,
-            @Nullable PendingIntent initialTaskPendingIntent, int secondTaskId,
+    public static void composeRecentsSplitLaunchAnimator(GroupedTaskView launchingTaskView,
+            @NonNull StateManager stateManager, @Nullable DepthController depthController,
+            int initialTaskId, @Nullable PendingIntent initialTaskPendingIntent, int secondTaskId,
             @NonNull TransitionInfo transitionInfo, SurfaceControl.Transaction t,
             @NonNull Runnable finishCallback) {
+        if (launchingTaskView != null) {
+            AnimatorSet animatorSet = new AnimatorSet();
+            animatorSet.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    finishCallback.run();
+                }
+            });
+
+            final RemoteAnimationTargetCompat[] appTargets =
+                    RemoteAnimationTargetCompat.wrapApps(transitionInfo, t, null /* leashMap */);
+            final RemoteAnimationTargetCompat[] wallpaperTargets =
+                    RemoteAnimationTargetCompat.wrapNonApps(
+                            transitionInfo, true /* wallpapers */, t, null /* leashMap */);
+            final RemoteAnimationTargetCompat[] nonAppTargets =
+                    RemoteAnimationTargetCompat.wrapNonApps(
+                            transitionInfo, false /* wallpapers */, t, null /* leashMap */);
+            final RecentsView recentsView = launchingTaskView.getRecentsView();
+            composeRecentsLaunchAnimator(animatorSet, launchingTaskView,
+                    appTargets, wallpaperTargets, nonAppTargets,
+                    true, stateManager,
+                    recentsView, depthController);
+
+            t.apply();
+            animatorSet.start();
+            return;
+        }
+
         // TODO: consider initialTaskPendingIntent
         TransitionInfo.Change splitRoot1 = null;
         TransitionInfo.Change splitRoot2 = null;
@@ -566,34 +593,20 @@
         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
                     ? ObjectAnimator.ofFloat(recentsView, RecentsView.CONTENT_ALPHA, 0)
                     : recentsView.createAdjacentPageAnimForTaskLaunch(taskView);
-            if (dp.isTablet) {
-                Log.d(BAD_STATE, "TVU composeRecentsLaunchAnimator alpha=" + 0);
-                launcherAnim.addListener(new AnimatorListenerAdapter() {
-                    @Override
-                    public void onAnimationStart(Animator animation) {
-                        Log.d(BAD_STATE, "TVU composeRecentsLaunchAnimator onStart");
-                    }
-
-                    @Override
-                    public void onAnimationCancel(Animator animation) {
-                        float alpha = recentsView == null
-                                ? -1
-                                : RecentsView.CONTENT_ALPHA.get(recentsView);
-                        Log.d(BAD_STATE, "TVU composeRecentsLaunchAnimator onCancel, alpha="
-                                + alpha);
-                    }
-
-                    @Override
-                    public void onAnimationEnd(Animator animation) {
-                        Log.d(BAD_STATE, "TVU composeRecentsLaunchAnimator onEnd");
-                    }
-                });
-            }
             launcherAnim.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR);
             launcherAnim.setDuration(RECENTS_LAUNCH_DURATION);
 
@@ -682,6 +695,7 @@
             public void onAnimationStart(Animator animation) {
                 if (shown) {
                     for (SurfaceControl leash : auxiliarySurfaces) {
+                        t.setLayer(leash, Integer.MAX_VALUE);
                         t.setAlpha(leash, 0);
                         t.show(leash);
                     }
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 52a37c5..c46926e 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -270,6 +270,18 @@
             MAIN_EXECUTOR.execute(ProxyScreenStatusProvider.INSTANCE::onScreenTurnedOn);
         }
 
+        @BinderThread
+        @Override
+        public void onScreenTurningOn() {
+            MAIN_EXECUTOR.execute(ProxyScreenStatusProvider.INSTANCE::onScreenTurningOn);
+        }
+
+        @BinderThread
+        @Override
+        public void onScreenTurningOff() {
+            MAIN_EXECUTOR.execute(ProxyScreenStatusProvider.INSTANCE::onScreenTurningOff);
+        }
+
         /**
          * Preloads the Overview activity.
          *
diff --git a/quickstep/src/com/android/quickstep/ViewUtils.java b/quickstep/src/com/android/quickstep/ViewUtils.java
index 1fef544..1bb95b9 100644
--- a/quickstep/src/com/android/quickstep/ViewUtils.java
+++ b/quickstep/src/com/android/quickstep/ViewUtils.java
@@ -17,6 +17,7 @@
 
 import android.graphics.HardwareRenderer;
 import android.os.Handler;
+import android.view.SurfaceControl;
 import android.view.View;
 import android.view.ViewRootImpl;
 
@@ -45,23 +46,43 @@
         return new FrameHandler(view, onFinishRunnable, canceled).schedule();
     }
 
-    private static class FrameHandler implements HardwareRenderer.FrameDrawingCallback {
+    private static class FrameHandler implements HardwareRenderer.FrameDrawingCallback,
+            ViewRootImpl.SurfaceChangedCallback {
 
         final ViewRootImpl mViewRoot;
         final Runnable mFinishCallback;
         final BooleanSupplier mCancelled;
         final Handler mHandler;
+        boolean mFinished;
 
         int mDeferFrameCount = 1;
 
         FrameHandler(View view, Runnable finishCallback, BooleanSupplier cancelled) {
             mViewRoot = view.getViewRootImpl();
+            mViewRoot.addSurfaceChangedCallback(this);
             mFinishCallback = finishCallback;
             mCancelled = cancelled;
             mHandler = new Handler();
         }
 
         @Override
+        public void surfaceCreated(SurfaceControl.Transaction t) {
+            // Do nothing
+        }
+
+        @Override
+        public void surfaceReplaced(SurfaceControl.Transaction t) {
+            // Do nothing
+        }
+
+        @Override
+        public void surfaceDestroyed() {
+            // If the root view is detached, then the app won't get any scheduled frames so we need
+            // to force-run any pending callbacks
+            finish();
+        }
+
+        @Override
         public void onFrameDraw(long frame) {
             Utilities.postAsyncCallback(mHandler, this::onFrame);
         }
@@ -77,9 +98,7 @@
                 return;
             }
 
-            if (mFinishCallback != null) {
-                mFinishCallback.run();
-            }
+            finish();
         }
 
         private boolean schedule() {
@@ -90,5 +109,17 @@
             }
             return false;
         }
+
+        private void finish() {
+            if (mFinished) {
+                return;
+            }
+            mFinished = true;
+            mDeferFrameCount = 0;
+            if (mFinishCallback != null) {
+                mFinishCallback.run();
+            }
+            mViewRoot.removeSurfaceChangedCallback(this);
+        }
     }
 }
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 3734f11..eb739a6 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -15,7 +15,6 @@
  */
 package com.android.quickstep.fallback;
 
-import static com.android.launcher3.testing.shared.TestProtocol.BAD_STATE;
 import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
 import static com.android.quickstep.fallback.RecentsState.DEFAULT;
 import static com.android.quickstep.fallback.RecentsState.HOME;
@@ -27,7 +26,6 @@
 import android.content.Context;
 import android.os.Build;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.MotionEvent;
 
 import androidx.annotation.Nullable;
@@ -225,7 +223,6 @@
         if (toState == MODAL_TASK) {
             setOverviewSelectEnabled(true);
         }
-        Log.d(BAD_STATE, "FRV onStateTransitionStart setFreezeVisibility=true, toState=" + toState);
         setFreezeViewVisibility(true);
     }
 
@@ -237,8 +234,6 @@
         }
         boolean isOverlayEnabled = finalState == DEFAULT || finalState == MODAL_TASK;
         setOverlayEnabled(isOverlayEnabled);
-        Log.d(BAD_STATE, "FRV onStateTransitionComplete setFreezeVisibility=false, finalState="
-                + finalState);
         setFreezeViewVisibility(false);
         if (finalState != MODAL_TASK) {
             setOverviewSelectEnabled(false);
diff --git a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
index b70c411..fa7bc04 100644
--- a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
@@ -358,7 +358,7 @@
             };
             RectFSpringAnim windowAnim = createWindowAnimationToHome(startShift,
                     homeAnimFactory)[0];
-            windowAnim.start(mContext, velocityPxPerMs);
+            windowAnim.start(mContext, mDp, velocityPxPerMs);
             return windowAnim;
         }
     }
diff --git a/quickstep/src/com/android/quickstep/util/BaseDepthController.java b/quickstep/src/com/android/quickstep/util/BaseDepthController.java
new file mode 100644
index 0000000..4030630
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/BaseDepthController.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util;
+
+import android.app.WallpaperManager;
+import android.os.IBinder;
+import android.util.FloatProperty;
+import android.view.AttachedSurfaceControl;
+import android.view.SurfaceControl;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.systemui.shared.system.BlurUtils;
+
+/**
+ * Utility class for applying depth effect
+ */
+public class BaseDepthController {
+
+    public static final FloatProperty<BaseDepthController> DEPTH =
+            new FloatProperty<BaseDepthController>("depth") {
+                @Override
+                public void setValue(BaseDepthController depthController, float depth) {
+                    depthController.setDepth(depth);
+                }
+
+                @Override
+                public Float get(BaseDepthController depthController) {
+                    return depthController.mDepth;
+                }
+            };
+
+    protected final Launcher mLauncher;
+
+    /**
+     * Blur radius when completely zoomed out, in pixels.
+     */
+    protected final int mMaxBlurRadius;
+    protected final WallpaperManager mWallpaperManager;
+    protected boolean mCrossWindowBlursEnabled;
+
+    /**
+     * Ratio from 0 to 1, where 0 is fully zoomed out, and 1 is zoomed in.
+     * @see android.service.wallpaper.WallpaperService.Engine#onZoomChanged(float)
+     */
+    protected float mDepth;
+
+    protected SurfaceControl mSurface;
+
+    // Hints that there is potentially content behind Launcher and that we shouldn't optimize by
+    // marking the launcher surface as opaque.  Only used in certain Launcher states.
+    private boolean mHasContentBehindLauncher;
+    /**
+     * Last blur value, in pixels, that was applied.
+     * For debugging purposes.
+     */
+    protected int mCurrentBlur;
+    /**
+     * If we requested early wake-up offsets to SurfaceFlinger.
+     */
+    protected boolean mInEarlyWakeUp;
+
+    public BaseDepthController(Launcher activity) {
+        mLauncher = activity;
+        mMaxBlurRadius = activity.getResources().getInteger(R.integer.max_depth_blur_radius);
+        mWallpaperManager = activity.getSystemService(WallpaperManager.class);
+    }
+
+    protected void setCrossWindowBlursEnabled(boolean isEnabled) {
+        mCrossWindowBlursEnabled = isEnabled;
+        applyDepthAndBlur();
+    }
+
+    public void setHasContentBehindLauncher(boolean hasContentBehindLauncher) {
+        mHasContentBehindLauncher = hasContentBehindLauncher;
+    }
+
+    protected void applyDepthAndBlur() {
+        float depth = mDepth;
+        IBinder windowToken = mLauncher.getRootView().getWindowToken();
+        if (windowToken != null) {
+            mWallpaperManager.setWallpaperZoomOut(windowToken, depth);
+        }
+
+        if (!BlurUtils.supportsBlursOnWindows()) {
+            return;
+        }
+        if (mSurface == null || !mSurface.isValid()) {
+            return;
+        }
+        boolean hasOpaqueBg = mLauncher.getScrimView().isFullyOpaque();
+        boolean isSurfaceOpaque = !mHasContentBehindLauncher && hasOpaqueBg;
+
+        mCurrentBlur = !mCrossWindowBlursEnabled || hasOpaqueBg
+                ? 0 : (int) (depth * mMaxBlurRadius);
+        SurfaceControl.Transaction transaction = new SurfaceControl.Transaction()
+                .setBackgroundBlurRadius(mSurface, mCurrentBlur)
+                .setOpaque(mSurface, isSurfaceOpaque);
+
+        // Set early wake-up flags when we know we're executing an expensive operation, this way
+        // SurfaceFlinger will adjust its internal offsets to avoid jank.
+        boolean wantsEarlyWakeUp = depth > 0 && depth < 1;
+        if (wantsEarlyWakeUp && !mInEarlyWakeUp) {
+            transaction.setEarlyWakeupStart();
+            mInEarlyWakeUp = true;
+        } else if (!wantsEarlyWakeUp && mInEarlyWakeUp) {
+            transaction.setEarlyWakeupEnd();
+            mInEarlyWakeUp = false;
+        }
+
+        AttachedSurfaceControl rootSurfaceControl =
+                mLauncher.getRootView().getRootSurfaceControl();
+        if (rootSurfaceControl != null) {
+            rootSurfaceControl.applyTransactionOnDraw(transaction);
+        }
+    }
+
+    protected void setDepth(float depth) {
+        depth = Utilities.boundToRange(depth, 0, 1);
+        // Round out the depth to dedupe frequent, non-perceptable updates
+        int depthI = (int) (depth * 256);
+        float depthF = depthI / 256f;
+        if (Float.compare(mDepth, depthF) == 0) {
+            return;
+        }
+        mDepth = depthF;
+        applyDepthAndBlur();
+    }
+
+    /**
+     * Sets the specified app target surface to apply the blur to.
+     */
+    protected void setSurface(SurfaceControl surface) {
+        if (mSurface != surface) {
+            mSurface = surface;
+            applyDepthAndBlur();
+        }
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/util/ProxyScreenStatusProvider.java b/quickstep/src/com/android/quickstep/util/ProxyScreenStatusProvider.java
index 3777c65..8f79ccf 100644
--- a/quickstep/src/com/android/quickstep/util/ProxyScreenStatusProvider.java
+++ b/quickstep/src/com/android/quickstep/util/ProxyScreenStatusProvider.java
@@ -39,6 +39,16 @@
         mListeners.forEach(ScreenListener::onScreenTurnedOn);
     }
 
+    /** Called when the screen is starting to turn on. */
+    public void onScreenTurningOn() {
+        mListeners.forEach(ScreenListener::onScreenTurningOn);
+    }
+
+    /** Called when the screen is starting to turn off. */
+    public void onScreenTurningOff() {
+        mListeners.forEach(ScreenListener::onScreenTurningOff);
+    }
+
     @Override
     public void addCallback(@NonNull ScreenListener listener) {
         mListeners.add(listener);
diff --git a/quickstep/src/com/android/quickstep/util/RecentsAtomicAnimationFactory.java b/quickstep/src/com/android/quickstep/util/RecentsAtomicAnimationFactory.java
index ac77c67..1d008da 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsAtomicAnimationFactory.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsAtomicAnimationFactory.java
@@ -15,13 +15,10 @@
  */
 package com.android.quickstep.util;
 
-import static com.android.launcher3.testing.shared.TestProtocol.BAD_STATE;
 import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
 
 import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
-import android.util.Log;
 
 import androidx.dynamicanimation.animation.DynamicAnimation;
 
@@ -30,8 +27,6 @@
 import com.android.launcher3.statemanager.StatefulActivity;
 import com.android.quickstep.views.RecentsView;
 
-import java.util.Arrays;
-
 public class RecentsAtomicAnimationFactory<ACTIVITY_TYPE extends StatefulActivity, STATE_TYPE>
         extends AtomicAnimationFactory<STATE_TYPE> {
 
@@ -53,27 +48,6 @@
             case INDEX_RECENTS_FADE_ANIM:
                 ObjectAnimator alpha = ObjectAnimator.ofFloat(mActivity.getOverviewPanel(),
                         RecentsView.CONTENT_ALPHA, values);
-                Log.d(BAD_STATE, "RAAF createStateElementAnimation alpha="
-                        + Arrays.toString(values));
-                alpha.addListener(new AnimatorListenerAdapter() {
-                    @Override
-                    public void onAnimationStart(Animator animation) {
-                        Log.d(BAD_STATE, "RAAF createStateElementAnimation onStart");
-                    }
-
-                    @Override
-                    public void onAnimationCancel(Animator animation) {
-                        RecentsView recent = mActivity.getOverviewPanel();
-                        float alpha = recent == null ? -1 : RecentsView.CONTENT_ALPHA.get(recent);
-                        Log.d(BAD_STATE, "RAAF createStateElementAnimation onCancel, alpha="
-                                + alpha);
-                    }
-
-                    @Override
-                    public void onAnimationEnd(Animator animation) {
-                        Log.d(BAD_STATE, "RAAF createStateElementAnimation onEnd");
-                    }
-                });
                 return alpha;
             case INDEX_RECENTS_TRANSLATE_X_ANIM: {
                 RecentsView rv = mActivity.getOverviewPanel();
diff --git a/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java b/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java
index c4909de..68739ba 100644
--- a/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java
+++ b/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java
@@ -214,7 +214,7 @@
      * @param context The activity context.
      * @param velocityPxPerMs Velocity of swipe in px/ms.
      */
-    public void start(Context context, PointF velocityPxPerMs) {
+    public void start(Context context, @Nullable DeviceProfile profile, PointF velocityPxPerMs) {
         // Only tell caller that we ended if both x and y animations have ended.
         OnAnimationEndListener onXEndListener = ((animation, canceled, centerX, velocityX) -> {
             mRectXAnimEnded = true;
@@ -252,7 +252,13 @@
         float minVisibleChange = Math.abs(1f / mStartRect.height());
         ResourceProvider rp = DynamicResource.provider(context);
         float damping = rp.getFloat(R.dimen.swipe_up_rect_scale_damping_ratio);
-        float stiffness = rp.getFloat(R.dimen.swipe_up_rect_scale_stiffness);
+
+        // Increase the stiffness for devices where we want the window size to transform quicker.
+        boolean shouldUseHigherStiffness = profile != null
+                && (profile.isLandscape || profile.isTablet);
+        float stiffness = shouldUseHigherStiffness
+                ? rp.getFloat(R.dimen.swipe_up_rect_scale_higher_stiffness)
+                : rp.getFloat(R.dimen.swipe_up_rect_scale_stiffness);
 
         mRectScaleAnim = new SpringAnimation(this, RECT_SCALE_PROGRESS)
                 .setSpring(new SpringForce(1f)
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index d2a2f36..0ca5574 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -242,8 +242,9 @@
         @Override
         public void startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
                 @NonNull SurfaceControl.Transaction t, @NonNull Runnable finishCallback) {
-            TaskViewUtils.composeRecentsSplitLaunchAnimator(mInitialTaskId,
-                    mInitialTaskPendingIntent, mSecondTaskId, info, t, () -> {
+            TaskViewUtils.composeRecentsSplitLaunchAnimator(mLaunchingTaskView, mStateManager,
+                    mDepthController, mInitialTaskId, mInitialTaskPendingIntent, mSecondTaskId,
+                    info, t, () -> {
                     finishCallback.run();
                     if (mSuccessCallback != null) {
                         mSuccessCallback.accept(true);
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 8b8558a..3c5a626 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -21,13 +21,11 @@
 import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK;
 import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT;
 import static com.android.launcher3.LauncherState.SPRING_LOADED;
-import static com.android.launcher3.testing.shared.TestProtocol.BAD_STATE;
 
 import android.annotation.TargetApi;
 import android.content.Context;
 import android.os.Build;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.MotionEvent;
 import android.view.Surface;
 
@@ -68,7 +66,6 @@
     public void init(OverviewActionsView actionsView,
             SplitSelectStateController splitPlaceholderView) {
         super.init(actionsView, splitPlaceholderView);
-        Log.d(BAD_STATE, "LauncherRecentsView init setContentAlpha=0");
         setContentAlpha(0);
     }
 
@@ -119,7 +116,6 @@
         if (toState == OVERVIEW_MODAL_TASK) {
             setOverviewSelectEnabled(true);
         }
-        Log.d(BAD_STATE, "LRV onStateTransitionStart setFreezeVisibility=true, toState=" + toState);
         setFreezeViewVisibility(true);
     }
 
@@ -131,8 +127,6 @@
         }
         boolean isOverlayEnabled = finalState == OVERVIEW || finalState == OVERVIEW_MODAL_TASK;
         setOverlayEnabled(isOverlayEnabled);
-        Log.d(BAD_STATE, "LRV onStateTransitionComplete setFreezeVisibility=false, finalState="
-                + finalState);
         setFreezeViewVisibility(false);
         if (finalState != OVERVIEW_MODAL_TASK) {
             setOverviewSelectEnabled(false);
diff --git a/quickstep/tests/src/com/android/quickstep/DeviceProfileTest.kt b/quickstep/tests/src/com/android/quickstep/DeviceProfileTest.kt
index 1208a2a..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" +
@@ -110,7 +111,7 @@
                 "\tnumShownHotseatIcons: 4\n" +
                 "\thotseatBorderSpace: 95.0px (36.190475dp)\n" +
                 "\tisQsbInline: false\n" +
-                "\tqsbWidth: 913.0px (347.8095dp)\n" +
+                "\thotseatQsbWidth: 913.0px (347.8095dp)\n" +
                 "\tisTaskbarPresent:false\n" +
                 "\tisTaskbarPresentInApps:false\n" +
                 "\ttaskbarSize: 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" +
@@ -229,7 +231,7 @@
                 "\tnumShownHotseatIcons: 4\n" +
                 "\thotseatBorderSpace: 95.0px (36.190475dp)\n" +
                 "\tisQsbInline: false\n" +
-                "\tqsbWidth: 913.0px (347.8095dp)\n" +
+                "\thotseatQsbWidth: 913.0px (347.8095dp)\n" +
                 "\tisTaskbarPresent:false\n" +
                 "\tisTaskbarPresentInApps:false\n" +
                 "\ttaskbarSize: 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" +
@@ -338,18 +341,18 @@
                 "\thotseatBarBottomSpacePx: 80.0px (40.0dp)\n" +
                 "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
                 "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
-                "\thotseatBarEndOffset: 597.0px (298.5dp)\n" +
+                "\thotseatBarEndOffset: 705.0px (352.5dp)\n" +
                 "\thotseatQsbSpace: 64.0px (32.0dp)\n" +
                 "\thotseatQsbHeight: 126.0px (63.0dp)\n" +
                 "\tspringLoadedHotseatBarTopMarginPx: 128.0px (64.0dp)\n" +
                 "\tgetHotseatLayoutPadding(context).top: -8.0px (-4.0dp)\n" +
                 "\tgetHotseatLayoutPadding(context).bottom: 73.0px (36.5dp)\n" +
-                "\tgetHotseatLayoutPadding(context).left: 959.0px (479.5dp)\n" +
-                "\tgetHotseatLayoutPadding(context).right: 597.0px (298.5dp)\n" +
-                "\tnumShownHotseatIcons: 5\n" +
-                "\thotseatBorderSpace: 101.0px (50.5dp)\n" +
+                "\tgetHotseatLayoutPadding(context).left: 954.0px (477.0dp)\n" +
+                "\tgetHotseatLayoutPadding(context).right: 705.0px (352.5dp)\n" +
+                "\tnumShownHotseatIcons: 6\n" +
+                "\thotseatBorderSpace: 36.0px (18.0dp)\n" +
                 "\tisQsbInline: true\n" +
-                "\tqsbWidth: 855.0px (427.5dp)\n" +
+                "\thotseatQsbWidth: 619.0px (309.5dp)\n" +
                 "\tisTaskbarPresent:true\n" +
                 "\tisTaskbarPresentInApps:true\n" +
                 "\ttaskbarSize: 120.0px (60.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" +
@@ -469,7 +473,7 @@
                 "\tnumShownHotseatIcons: 6\n" +
                 "\thotseatBorderSpace: 100.0px (50.0dp)\n" +
                 "\tisQsbInline: true\n" +
-                "\tqsbWidth: 640.0px (320.0dp)\n" +
+                "\thotseatQsbWidth: 640.0px (320.0dp)\n" +
                 "\tisTaskbarPresent:true\n" +
                 "\tisTaskbarPresentInApps:true\n" +
                 "\ttaskbarSize: 120.0px (60.0dp)\n" +
@@ -551,17 +555,18 @@
                 "\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: 1856.0px (928.0dp)\n" +
-                "\tallAppsTopPadding: 704.0px (352.0dp)\n" +
+                "\tallAppsShiftRange: 1936.0px (968.0dp)\n" +
+                "\tallAppsTopPadding: 624.0px (312.0dp)\n" +
                 "\tallAppsIconSizePx: 120.0px (60.0dp)\n" +
                 "\tallAppsIconTextSizePx: 28.0px (14.0dp)\n" +
                 "\tallAppsIconDrawablePaddingPx: 14.0px (7.0dp)\n" +
@@ -578,18 +583,18 @@
                 "\thotseatBarBottomSpacePx: 72.0px (36.0dp)\n" +
                 "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
                 "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
-                "\thotseatBarEndOffset: 460.0px (230.0dp)\n" +
+                "\thotseatBarEndOffset: 558.0px (279.0dp)\n" +
                 "\thotseatQsbSpace: 64.0px (32.0dp)\n" +
                 "\thotseatQsbHeight: 126.0px (63.0dp)\n" +
                 "\tspringLoadedHotseatBarTopMarginPx: 216.0px (108.0dp)\n" +
                 "\tgetHotseatLayoutPadding(context).top: 158.0px (79.0dp)\n" +
                 "\tgetHotseatLayoutPadding(context).bottom: 65.0px (32.5dp)\n" +
-                "\tgetHotseatLayoutPadding(context).left: 76.0px (38.0dp)\n" +
-                "\tgetHotseatLayoutPadding(context).right: 460.0px (230.0dp)\n" +
+                "\tgetHotseatLayoutPadding(context).left: 150.0px (75.0dp)\n" +
+                "\tgetHotseatLayoutPadding(context).right: 558.0px (279.0dp)\n" +
                 "\tnumShownHotseatIcons: 5\n" +
-                "\thotseatBorderSpace: 116.0px (58.0dp)\n" +
+                "\thotseatBorderSpace: 73.0px (36.5dp)\n" +
                 "\tisQsbInline: false\n" +
-                "\tqsbWidth: 1300.0px (650.0dp)\n" +
+                "\thotseatQsbWidth: 1300.0px (650.0dp)\n" +
                 "\tisTaskbarPresent:true\n" +
                 "\tisTaskbarPresentInApps:true\n" +
                 "\ttaskbarSize: 120.0px (60.0dp)\n" +
@@ -671,17 +676,18 @@
                 "\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: 1856.0px (928.0dp)\n" +
-                "\tallAppsTopPadding: 704.0px (352.0dp)\n" +
+                "\tallAppsShiftRange: 1936.0px (968.0dp)\n" +
+                "\tallAppsTopPadding: 624.0px (312.0dp)\n" +
                 "\tallAppsIconSizePx: 120.0px (60.0dp)\n" +
                 "\tallAppsIconTextSizePx: 28.0px (14.0dp)\n" +
                 "\tallAppsIconDrawablePaddingPx: 14.0px (7.0dp)\n" +
@@ -709,7 +715,7 @@
                 "\tnumShownHotseatIcons: 6\n" +
                 "\thotseatBorderSpace: 116.0px (58.0dp)\n" +
                 "\tisQsbInline: false\n" +
-                "\tqsbWidth: 1300.0px (650.0dp)\n" +
+                "\thotseatQsbWidth: 1300.0px (650.0dp)\n" +
                 "\tisTaskbarPresent:true\n" +
                 "\tisTaskbarPresentInApps:true\n" +
                 "\ttaskbarSize: 120.0px (60.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" +
@@ -824,12 +831,12 @@
                 "\tspringLoadedHotseatBarTopMarginPx: 116.0px (44.190475dp)\n" +
                 "\tgetHotseatLayoutPadding(context).top: 197.0px (75.04762dp)\n" +
                 "\tgetHotseatLayoutPadding(context).bottom: 43.0px (16.380953dp)\n" +
-                "\tgetHotseatLayoutPadding(context).left: 216.0px (82.28571dp)\n" +
+                "\tgetHotseatLayoutPadding(context).left: 106.0px (40.38095dp)\n" +
                 "\tgetHotseatLayoutPadding(context).right: 744.0px (283.42856dp)\n" +
                 "\tnumShownHotseatIcons: 6\n" +
-                "\thotseatBorderSpace: 61.0px (23.238094dp)\n" +
+                "\thotseatBorderSpace: 83.0px (31.619047dp)\n" +
                 "\tisQsbInline: false\n" +
-                "\tqsbWidth: 1467.0px (558.8571dp)\n" +
+                "\thotseatQsbWidth: 1467.0px (558.8571dp)\n" +
                 "\tisTaskbarPresent:true\n" +
                 "\tisTaskbarPresentInApps:true\n" +
                 "\ttaskbarSize: 158.0px (60.190475dp)\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" +
@@ -949,7 +957,7 @@
                 "\tnumShownHotseatIcons: 6\n" +
                 "\thotseatBorderSpace: 105.0px (40.0dp)\n" +
                 "\tisQsbInline: false\n" +
-                "\tqsbWidth: 1467.0px (558.8571dp)\n" +
+                "\thotseatQsbWidth: 1467.0px (558.8571dp)\n" +
                 "\tisTaskbarPresent:true\n" +
                 "\tisTaskbarPresentInApps:true\n" +
                 "\ttaskbarSize: 158.0px (60.190475dp)\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" +
@@ -1064,12 +1073,12 @@
                 "\tspringLoadedHotseatBarTopMarginPx: 171.0px (65.14286dp)\n" +
                 "\tgetHotseatLayoutPadding(context).top: 219.0px (83.42857dp)\n" +
                 "\tgetHotseatLayoutPadding(context).bottom: 87.0px (33.142857dp)\n" +
-                "\tgetHotseatLayoutPadding(context).left: 128.0px (48.761906dp)\n" +
+                "\tgetHotseatLayoutPadding(context).left: 78.0px (29.714285dp)\n" +
                 "\tgetHotseatLayoutPadding(context).right: 660.0px (251.42857dp)\n" +
                 "\tnumShownHotseatIcons: 6\n" +
-                "\thotseatBorderSpace: 47.0px (17.904762dp)\n" +
+                "\thotseatBorderSpace: 57.0px (21.714285dp)\n" +
                 "\tisQsbInline: false\n" +
-                "\tqsbWidth: 1236.0px (470.85715dp)\n" +
+                "\thotseatQsbWidth: 1236.0px (470.85715dp)\n" +
                 "\tisTaskbarPresent:true\n" +
                 "\tisTaskbarPresentInApps:true\n" +
                 "\ttaskbarSize: 158.0px (60.190475dp)\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" +
@@ -1189,7 +1199,7 @@
                 "\tnumShownHotseatIcons: 6\n" +
                 "\thotseatBorderSpace: 84.0px (32.0dp)\n" +
                 "\tisQsbInline: false\n" +
-                "\tqsbWidth: 1236.0px (470.85715dp)\n" +
+                "\thotseatQsbWidth: 1236.0px (470.85715dp)\n" +
                 "\tisTaskbarPresent:true\n" +
                 "\tisTaskbarPresentInApps:true\n" +
                 "\ttaskbarSize: 158.0px (60.190475dp)\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" +
@@ -1308,7 +1319,7 @@
                 "\tnumShownHotseatIcons: 4\n" +
                 "\thotseatBorderSpace: 0.0px (0.0dp)\n" +
                 "\tisQsbInline: false\n" +
-                "\tqsbWidth: 1525.0px (580.9524dp)\n" +
+                "\thotseatQsbWidth: 1525.0px (580.9524dp)\n" +
                 "\tisTaskbarPresent:false\n" +
                 "\tisTaskbarPresentInApps:false\n" +
                 "\ttaskbarSize: 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" +
@@ -1427,7 +1439,7 @@
                 "\tnumShownHotseatIcons: 4\n" +
                 "\thotseatBorderSpace: 0.0px (0.0dp)\n" +
                 "\tisQsbInline: false\n" +
-                "\tqsbWidth: 1621.0px (617.5238dp)\n" +
+                "\thotseatQsbWidth: 1621.0px (617.5238dp)\n" +
                 "\tisTaskbarPresent:false\n" +
                 "\tisTaskbarPresentInApps:false\n" +
                 "\ttaskbarSize: 0.0px (0.0dp)\n" +
diff --git a/quickstep/tests/src/com/android/quickstep/HotseatWidthCalculationTest.kt b/quickstep/tests/src/com/android/quickstep/HotseatWidthCalculationTest.kt
new file mode 100644
index 0000000..3967f75
--- /dev/null
+++ b/quickstep/tests/src/com/android/quickstep/HotseatWidthCalculationTest.kt
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep
+
+import android.graphics.Rect
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.launcher3.DeviceProfileBaseTest
+import com.android.launcher3.util.WindowBounds
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class HotseatWidthCalculationTest : DeviceProfileBaseTest() {
+
+    /**
+     * This is a case when after setting the hotseat, the space needs to be recalculated
+     * but it doesn't need to change QSB width or remove icons
+     */
+    @Test
+    fun distribute_border_space_when_space_is_enough_portrait() {
+        initializeVarsForTablet(isGestureMode = false)
+        windowBounds = WindowBounds(Rect(0, 0, 1800, 2560), Rect(0, 104, 0, 0))
+        val dp = newDP()
+        dp.isTaskbarPresentInApps = true
+
+        assertThat(dp.hotseatBarEndOffset).isEqualTo(558)
+        assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+        assertThat(dp.hotseatBorderSpace).isEqualTo(69)
+
+        assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(176)
+        assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(558)
+
+        assertThat(dp.isQsbInline).isFalse()
+        assertThat(dp.hotseatQsbWidth).isEqualTo(1445)
+    }
+
+    /**
+     * This is a case when after setting the hotseat, and recalculating spaces
+     * it still needs to remove icons for everything to fit
+     */
+    @Test
+    fun decrease_num_of_icons_when_not_enough_space_portrait() {
+        initializeVarsForTablet(isGestureMode = false)
+        windowBounds = WindowBounds(Rect(0, 0, 1300, 2560), Rect(0, 104, 0, 0))
+        val dp = newDP()
+        dp.isTaskbarPresentInApps = true
+
+        assertThat(dp.hotseatBarEndOffset).isEqualTo(558)
+        assertThat(dp.numShownHotseatIcons).isEqualTo(4)
+        assertThat(dp.hotseatBorderSpace).isEqualTo(76)
+
+        assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(122)
+        assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(558)
+
+        assertThat(dp.isQsbInline).isFalse()
+        assertThat(dp.hotseatQsbWidth).isEqualTo(1058)
+    }
+
+    /**
+     * This is a case when after setting the hotseat, the space needs to be recalculated
+     * but it doesn't need to change QSB width or remove icons
+     */
+    @Test
+    fun distribute_border_space_when_space_is_enough_landscape() {
+        initializeVarsForTwoPanel(isGestureMode = false, isLandscape = true)
+        val dp = newDP()
+        dp.isTaskbarPresentInApps = true
+
+        assertThat(dp.hotseatBarEndOffset).isEqualTo(744)
+        assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+        assertThat(dp.hotseatBorderSpace).isEqualTo(83)
+
+        assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(106)
+        assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(744)
+
+        assertThat(dp.isQsbInline).isFalse()
+        assertThat(dp.hotseatQsbWidth).isEqualTo(1467)
+    }
+
+    /**
+     * This is a case when the hotseat spans a certain amount of columns
+     * and the nav buttons push the hotseat to the side, but not enough to change the border space.
+     */
+    @Test
+    fun nav_buttons_dont_interfere_with_required_hotseat_width() {
+        initializeVarsForTablet(isGestureMode = false, isLandscape = true)
+        inv?.apply {
+            hotseatColumnSpan = IntArray(4) { 4 }
+            inlineQsb = BooleanArray(4) { false }
+        }
+        val dp = newDP()
+        dp.isTaskbarPresentInApps = true
+
+        assertThat(dp.hotseatBarEndOffset).isEqualTo(705)
+        assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+        assertThat(dp.hotseatBorderSpace).isEqualTo(108)
+
+        assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(631)
+        assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(705)
+
+        assertThat(dp.isQsbInline).isFalse()
+        assertThat(dp.hotseatQsbWidth).isEqualTo(1227)
+    }
+
+    /**
+     * This is a case when after setting the hotseat, the QSB width needs to be changed to fit
+     */
+    @Test
+    fun decrease_qsb_when_not_enough_space_landscape() {
+        initializeVarsForTablet(isGestureMode = false, isLandscape = true)
+        windowBounds = WindowBounds(Rect(0, 0, 2460, 1600), Rect(0, 104, 0, 0))
+        val dp = newDP()
+        dp.isTaskbarPresentInApps = true
+
+        assertThat(dp.hotseatBarEndOffset).isEqualTo(705)
+        assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+        assertThat(dp.hotseatBorderSpace).isEqualTo(36)
+
+        assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(884)
+        assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(705)
+
+        assertThat(dp.isQsbInline).isTrue()
+        assertThat(dp.hotseatQsbWidth).isEqualTo(559)
+    }
+
+    /**
+     * This is a case when after setting the hotseat, changing QSB width, and recalculating spaces
+     * it still needs to remove icons for everything to fit
+     */
+    @Test
+    fun decrease_num_of_icons_when_not_enough_space_landscape() {
+        initializeVarsForTablet(isGestureMode = false, isLandscape = true)
+        windowBounds = WindowBounds(Rect(0, 0, 2260, 1600), Rect(0, 104, 0, 0))
+        val dp = newDP()
+        dp.isTaskbarPresentInApps = true
+
+        assertThat(dp.hotseatBarEndOffset).isEqualTo(705)
+        assertThat(dp.numShownHotseatIcons).isEqualTo(5)
+        assertThat(dp.hotseatBorderSpace).isEqualTo(56)
+
+        assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(801)
+        assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(705)
+
+        assertThat(dp.isQsbInline).isTrue()
+        assertThat(dp.hotseatQsbWidth).isEqualTo(480)
+    }
+}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index 4bd627a..159b65f 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -181,6 +181,21 @@
 
     @Test
     @PortraitLandscape
+    public void testSplitFromOverview() {
+        assumeTrue(!mLauncher.isTablet());
+
+        startTestActivity(2);
+        startTestActivity(3);
+
+        mLauncher.goHome().switchToOverview().getCurrentTask()
+                .tapMenu()
+                .tapSplitMenuItem()
+                .getTestActivityTask(2)
+                .open();
+    }
+
+    @Test
+    @PortraitLandscape
     public void testSplitFromOverviewForTablet() {
         assumeTrue(mLauncher.isTablet());
 
diff --git a/res/drawable/ic_block_shadow.xml b/res/drawable/ic_block_shadow.xml
deleted file mode 100644
index 045fe8d..0000000
--- a/res/drawable/ic_block_shadow.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<com.android.launcher3.graphics.ShadowDrawable
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_block_no_shadow"
-    android:elevation="@dimen/drop_target_shadow_elevation" />
diff --git a/res/drawable/ic_remove_shadow.xml b/res/drawable/ic_remove_shadow.xml
deleted file mode 100644
index 48abc10..0000000
--- a/res/drawable/ic_remove_shadow.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<com.android.launcher3.graphics.ShadowDrawable
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_remove_no_shadow"
-    android:elevation="@dimen/drop_target_shadow_elevation" />
diff --git a/res/drawable/ic_setup_shadow.xml b/res/drawable/ic_setup_shadow.xml
deleted file mode 100644
index 10aeee6..0000000
--- a/res/drawable/ic_setup_shadow.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<com.android.launcher3.graphics.ShadowDrawable
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_setting"
-    android:elevation="@dimen/drop_target_shadow_elevation" />
diff --git a/res/drawable/ic_uninstall_shadow.xml b/res/drawable/ic_uninstall_shadow.xml
deleted file mode 100644
index b441b0e..0000000
--- a/res/drawable/ic_uninstall_shadow.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<com.android.launcher3.graphics.ShadowDrawable
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_uninstall_no_shadow"
-    android:elevation="@dimen/drop_target_shadow_elevation" />
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-af/strings.xml b/res/values-af/strings.xml
index 445bfda..a699667 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Deursoek programme"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Laai tans programme …"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Kon geen programme kry wat by \"<xliff:g id="QUERY">%1$s</xliff:g>\" pas nie"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Soek meer programme"</string>
     <string name="label_application" msgid="8531721983832654978">"Program"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Alle programme"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Kennisgewings"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 474cd9f..b7d4a7d 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"መተግበሪያዎችን ፈልግ"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"መተግበሪያዎችን በመጫን ላይ…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"ከ«<xliff:g id="QUERY">%1$s</xliff:g>» ጋር የሚዛመዱ ምንም መተግበሪያዎች አልተገኙም"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"ተጨማሪ መተግበሪያዎች ይፈልጉ"</string>
     <string name="label_application" msgid="8531721983832654978">"መተግበሪያ"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"ሁሉም መተግበሪያዎች"</string>
     <string name="notifications_header" msgid="1404149926117359025">"ማሳወቂያዎች"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index a4f7c03..e075559 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"بحث في التطبيقات"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"جارٍ تحميل التطبيقات…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"لم يتم العثور على أي تطبيقات تتطابق مع \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"البحث عن مزيد من التطبيقات"</string>
     <string name="label_application" msgid="8531721983832654978">"تطبيق"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"جميع التطبيقات"</string>
     <string name="notifications_header" msgid="1404149926117359025">"الإشعارات"</string>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index beb9619..ba14e97 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"এপসমূহ সন্ধান কৰক"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"এপসমূহ ল’ড কৰি থকা হৈছে…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"ৰ সৈতে মিলা কোনো এপ্ বিচাৰি পোৱা নগ\'ল"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"আৰু অধিক এপবোৰ সন্ধান কৰক"</string>
     <string name="label_application" msgid="8531721983832654978">"এপ্"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"আটাইবোৰ এপ্"</string>
     <string name="notifications_header" msgid="1404149926117359025">"জাননীসমূহ"</string>
@@ -73,7 +72,7 @@
     <string name="all_apps_button_work_label" msgid="7270707118948892488">"কৰ্মস্থানৰ এপৰ তালিকা"</string>
     <string name="remove_drop_target_label" msgid="7812859488053230776">"আঁতৰাওক"</string>
     <string name="uninstall_drop_target_label" msgid="4722034217958379417">"আনইনষ্টল কৰক"</string>
-    <string name="app_info_drop_target_label" msgid="692894985365717661">"এপ সম্পৰ্কীয় তথ্য"</string>
+    <string name="app_info_drop_target_label" msgid="692894985365717661">"এপ্‌ সম্পৰ্কীয় তথ্য"</string>
     <string name="install_drop_target_label" msgid="2539096853673231757">"ইনষ্টল কৰক"</string>
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"এপৰ পৰামৰ্শ নিদিব"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"পূৰ্বানুমান কৰা এপ্‌টো পিন কৰক"</string>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index 93e6f08..2e07405 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Tətbiqləri axtarın"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Tətbiqlər yüklənir…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"<xliff:g id="QUERY">%1$s</xliff:g> sorğusuna uyğun tətbiq tapılmadı"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Daha çox tətbiq üçün axtarış edin"</string>
     <string name="label_application" msgid="8531721983832654978">"Tətbiq"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Bütün tətbiqlər"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Bildirişlər"</string>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index ded4dc9..cc6e908 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pretražite aplikacije"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Aplikacije se učitavaju…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nije pronađena nijedna aplikacija za „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Pretraži još aplikacija"</string>
     <string name="label_application" msgid="8531721983832654978">"Aplikacija"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Sve aplikacije"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Obaveštenja"</string>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index 7fa8341..69a16ba 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Пошук праграм"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Праграмы загружаюцца…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Праграм, якія адпавядаюць запыту \"<xliff:g id="QUERY">%1$s</xliff:g>\", не знойдзена"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Шукаць іншыя праграмы"</string>
     <string name="label_application" msgid="8531721983832654978">"Праграма"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Усе праграмы"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Апавяшчэнні"</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 62b7796..549c8ea 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Търсене в приложенията"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Приложенията се зареждат…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Няма намерени приложения, съответстващи на „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Търсене на още приложения"</string>
     <string name="label_application" msgid="8531721983832654978">"Приложение"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Всички приложения"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Известия"</string>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index 1be272b..9683182 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"অ্যাপ খুঁজুন"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"অ্যাপ লোড হচ্ছে…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" এর সাথে মেলে এমন কোনো অ্যাপ পাওয়া যায়নি"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"আরও অ্যাপ্লিকেশানের জন্য খুঁজুন"</string>
     <string name="label_application" msgid="8531721983832654978">"অ্যাপ"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"সব অ্যাপ"</string>
     <string name="notifications_header" msgid="1404149926117359025">"বিজ্ঞপ্তি"</string>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 639b6b3..f99525f 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pretražite aplikacije"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Aplikacije se učitavaju…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nije pronađena nijedna aplikacija za upit \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Pretraži više aplikacija"</string>
     <string name="label_application" msgid="8531721983832654978">"Aplikacija"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Sve aplikacije"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Obavještenja"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index ee35fd3..d8ede15 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Cerca aplicacions"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"S\'estan carregant les aplicacions…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"No s\'ha trobat cap aplicació que coincideixi amb \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Cerca més aplicacions"</string>
     <string name="label_application" msgid="8531721983832654978">"Aplicació"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Totes les aplicacions"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notificacions"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 1b418c6..e4d46e4 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Hledat v aplikacích"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Načítání aplikací…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Dotazu „<xliff:g id="QUERY">%1$s</xliff:g>“ neodpovídají žádné aplikace"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Vyhledat další aplikace"</string>
     <string name="label_application" msgid="8531721983832654978">"Aplikace"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Všechny aplikace"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Oznámení"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 5cdadcd..4da7b84 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Søg efter apps"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Indlæser apps…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Der blev ikke fundet nogen apps, som matcher \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Søg efter flere apps"</string>
     <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Alle apps"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifikationer"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index b75ef9d..3c2514f 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Apps finden"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Apps werden geladen…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Keine Apps für \"<xliff:g id="QUERY">%1$s</xliff:g>\" gefunden"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Weitere Apps suchen"</string>
     <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Alle Apps"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Benachrichtigungen"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 99c9e23..ae9a8fd 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Αναζήτηση εφαρμογών"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Φόρτωση εφαρμογών…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Δεν βρέθηκαν εφαρμογές αντιστοίχισης για \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Αναζήτηση περισσότερων εφαρμογών"</string>
     <string name="label_application" msgid="8531721983832654978">"Εφαρμογή"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Όλες οι εφαρμογές"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Ειδοποιήσεις"</string>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index 97f0528..4f15eb5 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Search apps"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Loading apps…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string>
     <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"All apps"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index 97f0528..4f15eb5 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Search apps"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Loading apps…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string>
     <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"All apps"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 97f0528..4f15eb5 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Search apps"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Loading apps…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string>
     <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"All apps"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 97f0528..4f15eb5 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Search apps"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Loading apps…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string>
     <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"All apps"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
index 4977beb..e644c23 100644
--- a/res/values-en-rXC/strings.xml
+++ b/res/values-en-rXC/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‎‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‎‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‏‏‎‏‎‎‎‎‏‎‎‏‏‏‎‎Search apps‎‏‎‎‏‎"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‎‏‏‏‏‎‏‎‏‏‏‎‏‎‎‏‎‎‎‎‏‏‎‏‎‏‎‏‏‏‎‏‏‏‏‏‎‎‎‏‎‏‏‏‏‏‏‎‏‎‏‎‎‎Loading apps…‎‏‎‎‏‎"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‎‏‎‎‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎‏‏‏‏‏‎‎‎‏‏‎‎‏‎‏‎‏‏‏‏‎‏‎‏‎‎‎‎‎‎‏‎‏‎‎No apps found matching \"‎‏‎‎‏‏‎<xliff:g id="QUERY">%1$s</xliff:g>‎‏‎‎‏‏‏‎\"‎‏‎‎‏‎"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‏‎‏‎‏‏‏‏‏‎‎‎‏‎‏‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‎‏‎‏‏‏‏‎‎‏‏‎‎‏‏‎‏‎‎‎‎Search for more apps‎‏‎‎‏‎"</string>
     <string name="label_application" msgid="8531721983832654978">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‎‏‏‎‎‎‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‎‏‏‏‏‎‎‏‎‎‎‎‏‎‎‏‎‎‎‎‎‏‎‎App‎‏‎‎‏‎"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‎‏‏‎‏‏‏‎‏‎‎‏‎‏‏‎‏‏‏‏‏‎‎‎‏‏‏‏‏‏‎‎‎‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‎‎‎‏‏‏‎All apps‎‏‎‎‏‎"</string>
     <string name="notifications_header" msgid="1404149926117359025">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‏‎‏‎‏‏‎‎‎‏‎‏‎‏‏‎‎‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎Notifications‎‏‎‎‏‎"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 3ed312b..0bc8f4f 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Buscar apps"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Cargando apps…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"No hay apps que coincidan con \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Buscar más apps"</string>
     <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Todas las apps"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notificaciones"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 567ff0d..4045ad3 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Buscar aplicaciones"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Cargando aplicaciones…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"No se han encontrado aplicaciones que contengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Buscar más aplicaciones"</string>
     <string name="label_application" msgid="8531721983832654978">"Aplicación"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Todas las aplicaciones"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notificaciones"</string>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index c34a003..effd140 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Otsige rakendusi"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Rakenduste laadimine …"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Päringule „<xliff:g id="QUERY">%1$s</xliff:g>” ei vastanud ükski rakendus"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Otsi rohkem rakendusi"</string>
     <string name="label_application" msgid="8531721983832654978">"Rakendus"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Kõik rakendused"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Märguanded"</string>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index 55e0c3c..9e2d9a4 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Bilatu aplikazioetan"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Aplikazioak kargatzen…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Ez da aurkitu \"<xliff:g id="QUERY">%1$s</xliff:g>\" bilaketaren emaitzarik"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Bilatu aplikazio gehiago"</string>
     <string name="label_application" msgid="8531721983832654978">"Aplikazioa"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Aplikazio guztiak"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Jakinarazpenak"</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 12db5bd..a1acda0 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"جستجوی برنامه‌ها"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"درحال بارگیری برنامه‌‌ها…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"هیچ برنامه‌ای در مطابقت با «<xliff:g id="QUERY">%1$s</xliff:g>» پیدا نشد"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"جستجوی برنامه‌های بیشتر"</string>
     <string name="label_application" msgid="8531721983832654978">"برنامه"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"همه برنامه‌ها"</string>
     <string name="notifications_header" msgid="1404149926117359025">"اعلان‌ها"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 135c452..89e4106 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Hae sovelluksia"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Ladataan sovelluksia…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"<xliff:g id="QUERY">%1$s</xliff:g> ei palauttanut sovelluksia."</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Hae lisää sovelluksia"</string>
     <string name="label_application" msgid="8531721983832654978">"Sovellus"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Kaikki sovellukset"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Ilmoitukset"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 446a507..448569d 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Rechercher dans les applications"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Chargement des applications en cours…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Aucune application trouvée correspondant à « <xliff:g id="QUERY">%1$s</xliff:g> »"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Rechercher plus d\'applications"</string>
     <string name="label_application" msgid="8531721983832654978">"Application"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Toutes les applications"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 1d623b1..a6856fc 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Rechercher dans les applications"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Chargement des applications…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Aucune application ne correspond à la requête \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Rechercher plus d\'applications"</string>
     <string name="label_application" msgid="8531721983832654978">"Application"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Toutes les applis"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 256c4d3..045d8d7 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Buscar aplicacións"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Cargando aplicacións…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Non se atoparon aplicacións que coincidan con \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Buscar máis aplicacións"</string>
     <string name="label_application" msgid="8531721983832654978">"Aplicación"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Todas as aplicacións"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notificacións"</string>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index f1e1996..7288570 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"શોધ ઍપ્લિકેશનો"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"ઍપ્લિકેશનો લોડ કરી રહ્યું છે…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"થી મેળ ખાતી કોઈ ઍપ્લિકેશનો મળી નથી"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"વધુ ઍપ્લિકેશનો શોધો"</string>
     <string name="label_application" msgid="8531721983832654978">"ઍપ"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"બધી ઍપ"</string>
     <string name="notifications_header" msgid="1404149926117359025">"નોટિફિકેશન"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 1b05040..5e71f33 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ऐप सर्च करें"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"ऐप्लिकेशन लोड हो रहे हैं…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" से मिलता-जुलता कोई ऐप्लिकेशन नहीं मिला"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"और ऐप सर्च करें"</string>
     <string name="label_application" msgid="8531721983832654978">"ऐप्लिकेशन"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"सभी ऐप्लिकेशन"</string>
     <string name="notifications_header" msgid="1404149926117359025">"सूचनाएं"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 4a0fbe8..a1369e8 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pretraži aplikacije"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Učitavanje aplikacija…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nema aplikacija podudarnih s upitom \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Traži više aplikacija"</string>
     <string name="label_application" msgid="8531721983832654978">"Aplikacija"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Sve aplikacije"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Obavijesti"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index c1e527d..a5d4835 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Alkalmazások keresése"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Alkalmazások betöltése…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nem található alkalmazás a(z) „<xliff:g id="QUERY">%1$s</xliff:g>” lekérdezésre"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"További alkalmazások keresése"</string>
     <string name="label_application" msgid="8531721983832654978">"Alkalmazás"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Összes alkalmazás"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Értesítések"</string>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index f0d01f1..44c3a96 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Որոնել հավելվածներ"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Հավելվածների բեռնում…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"«<xliff:g id="QUERY">%1$s</xliff:g>» հարցմանը համապատասխանող հավելվածներ չեն գտնվել"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Որոնել այլ հավելվածներ"</string>
     <string name="label_application" msgid="8531721983832654978">"Հավելված"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Բոլոր հավելվածները"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Ծանուցումներ"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 1a97a45..e46026e 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Telusuri aplikasi"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Memuat aplikasi…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Tidak ditemukan aplikasi yang cocok dengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Telusuri aplikasi lainnya"</string>
     <string name="label_application" msgid="8531721983832654978">"Aplikasi"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Semua aplikasi"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifikasi"</string>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index a1959f8..92be25b 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Leita í forritum"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Hleður forrit…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Ekki fundust forrit sem samsvara „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Leita að fleiri forritum"</string>
     <string name="label_application" msgid="8531721983832654978">"Forrit"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Öll forrit"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Tilkynningar"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 302efcb..b5b7add 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Cerca nelle app"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Caricamento delle app…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nessuna app trovata corrispondente a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Cerca altre app"</string>
     <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Tutte le app"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifiche"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 15e200f..6b4d129 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"חיפוש אפליקציות"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"טעינת אפליקציות מתבצעת…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"לא נמצאו אפליקציות התואמות ל-\"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"חיפוש אפליקציות נוספות"</string>
     <string name="label_application" msgid="8531721983832654978">"אפליקציה"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"כל האפליקציות"</string>
     <string name="notifications_header" msgid="1404149926117359025">"התראות"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 2fd3ab5..484be1f 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"アプリを検索"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"アプリを読み込んでいます…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"「<xliff:g id="QUERY">%1$s</xliff:g>」に一致するアプリは見つかりませんでした"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"他のアプリを検索"</string>
     <string name="label_application" msgid="8531721983832654978">"アプリ"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"すべてのアプリ"</string>
     <string name="notifications_header" msgid="1404149926117359025">"通知"</string>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index 24f95dd..8437dd8 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"აპების ძიება"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"აპები იტვირთება…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"„<xliff:g id="QUERY">%1$s</xliff:g>“-ის თანხვედრი აპები არ მოიძებნა"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"მეტი აპის პოვნა"</string>
     <string name="label_application" msgid="8531721983832654978">"აპი"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"ყველა აპი"</string>
     <string name="notifications_header" msgid="1404149926117359025">"შეტყობინებები"</string>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index 8ed7ec5..ec3ee18 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Қолданбаларды іздеу"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Қолданбалар жүктелуде…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" сұрауына сәйкес келетін қолданбалар жоқ"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Қосымша қолданбалар іздеу"</string>
     <string name="label_application" msgid="8531721983832654978">"Қолданба"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Барлық қолданба"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Хабарландырулар"</string>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index 306449c..f1c1d08 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ស្វែងរក​កម្មវិធី"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"កំពុងផ្ទុកកម្មវិធី…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"រកមិនឃើញកម្មវិធី​ដែលត្រូវគ្នាជាមួយ \"<xliff:g id="QUERY">%1$s</xliff:g>\" ទេ"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"ស្វែងរកកម្មវិធីច្រើនទៀត"</string>
     <string name="label_application" msgid="8531721983832654978">"កម្មវិធី"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"កម្មវិធី​ទាំងអស់"</string>
     <string name="notifications_header" msgid="1404149926117359025">"ការ​ជូនដំណឹង"</string>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index a9b89b5..72eaeac 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಹುಡುಕಿ"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ಹೊಂದಿಕೆಯ ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಕಂಡುಬಂದಿಲ್ಲ"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"ಮತ್ತಷ್ಟು ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಹುಡುಕಿ"</string>
     <string name="label_application" msgid="8531721983832654978">"ಆ್ಯಪ್"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳು"</string>
     <string name="notifications_header" msgid="1404149926117359025">"ಅಧಿಸೂಚನೆಗಳು"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 0935aa1..f6b8ff7 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"앱 검색"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"앱 로드 중…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\'<xliff:g id="QUERY">%1$s</xliff:g>\'과(와) 일치하는 앱이 없습니다."</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"더 많은 앱 검색"</string>
     <string name="label_application" msgid="8531721983832654978">"앱"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"모든 앱"</string>
     <string name="notifications_header" msgid="1404149926117359025">"알림"</string>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 755e274..84b7993 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Колдонмолорду издөө"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Колдонмолор жүктөлүүдө…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" сурамына дал келген колдонмолор табылган жок"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Көбүрөөк колдонмолорду издөө"</string>
     <string name="label_application" msgid="8531721983832654978">"Колдонмо"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Бардык колдонмолор"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Билдирмелер"</string>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index 9e75492..d8b55f8 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ຊອກຫາແອັບ"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"ກໍາລັງໂຫຼດແອັບ…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"ບໍ່ພົບແອັບທີ່ກົງກັບ \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"ຊອກຫາແອັບເພີ່ມເຕີມ"</string>
     <string name="label_application" msgid="8531721983832654978">"ແອັບ"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"ແອັບທັງໝົດ"</string>
     <string name="notifications_header" msgid="1404149926117359025">"ການແຈ້ງເຕືອນ"</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index bbe0cfa..e68362d 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Paieškos programos"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Įkeliamos programos…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nerasta jokių užklausą „<xliff:g id="QUERY">%1$s</xliff:g>“ atitinkančių programų"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Ieškoti daugiau programų"</string>
     <string name="label_application" msgid="8531721983832654978">"Programa"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Visos programos"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Pranešimai"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index b5836ef..75f6d1a 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Meklēt lietotnes"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Notiek lietotņu ielāde…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Vaicājumam “<xliff:g id="QUERY">%1$s</xliff:g>” neatbilda neviena lietotne"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Meklēt citas lietotnes"</string>
     <string name="label_application" msgid="8531721983832654978">"Lietotne"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Visas lietotnes"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Paziņojumi"</string>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index d452eba..fef9bbe 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Пребарувајте апликации"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Се вчитуваат апликации…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Не се најдени апликации што одговараат на „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Пребарај други апликации"</string>
     <string name="label_application" msgid="8531721983832654978">"Апликација"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Сите апликации"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Известувања"</string>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index df532c0..802ea81 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ആപ്പുകൾ തിരയുക"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"ആപ്പുകൾ ലോഡുചെയ്യുന്നു..."</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" എന്നതുമായി പൊരുത്തപ്പെടുന്ന ആപ്പുകളൊന്നും കണ്ടെത്തിയില്ല"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"കൂടുതൽ ആപ്പുകൾക്ക് തിരയുക"</string>
     <string name="label_application" msgid="8531721983832654978">"ആപ്പ്"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"എല്ലാ ആപ്പുകളും"</string>
     <string name="notifications_header" msgid="1404149926117359025">"അറിയിപ്പുകൾ"</string>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index c71aaff..f091cb8 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Апп хайх"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Аппыг ачаалж байна..."</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"-д тохирох апп олдсонгүй"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Бусад апп-г хайх"</string>
     <string name="label_application" msgid="8531721983832654978">"Апп"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Бүх апп"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Мэдэгдэл"</string>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index e871073..d6535ce 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"अ‍ॅप्स शोधा"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"अ‍ॅप्स लोड करत आहे…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" शी जुळणारे कोणतेही अ‍ॅप्स आढळले नाहीत"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"अधिक अ‍ॅप्स शोधा"</string>
     <string name="label_application" msgid="8531721983832654978">"ॲप"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"सर्व अ‍ॅप्स"</string>
     <string name="notifications_header" msgid="1404149926117359025">"सूचना"</string>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index cbfb551..edd0530 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Cari apl"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Memuatkan apl…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Tiada apl yang ditemui sepadan dengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Cari lagi apl"</string>
     <string name="label_application" msgid="8531721983832654978">"Apl"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Semua apl"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Pemberitahuan"</string>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index 984ec4c..bf66399 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ရှာဖွေမှု အက်ပ်များ"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"အက်ပ်များကို ဖွင့်နေသည်…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" နှင့်ကိုက်ညီသည့် အပ်ပ်များကို မတွေ့ပါ"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"နောက်ထပ် အက်ပ်များကို ရှာပါ"</string>
     <string name="label_application" msgid="8531721983832654978">"အက်ပ်"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"အက်ပ်အားလုံး"</string>
     <string name="notifications_header" msgid="1404149926117359025">"အကြောင်းကြားချက်များ"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index b29ee77..3e08d10 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Søk etter apper"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Laster inn appene …"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Fant ingen apper som samsvarer med «<xliff:g id="QUERY">%1$s</xliff:g>»"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Søk etter flere apper"</string>
     <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Alle apper"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Varsler"</string>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index fcc1ece..8cef63d 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"खोजसम्बन्धी एपहरू"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"एपहरू लोड गर्दै…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" सँग मिल्दो कुनै एप भेटिएन"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"थप एपहरू खोज्नुहोस्"</string>
     <string name="label_application" msgid="8531721983832654978">"एप"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"सबै एप"</string>
     <string name="notifications_header" msgid="1404149926117359025">"सूचनाहरू"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index bd41952..4b203b7 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Apps zoeken"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Apps laden…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Er zijn geen apps gevonden die overeenkomen met \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Zoeken naar meer apps"</string>
     <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Alle apps"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Meldingen"</string>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index 95fa000..dd5561d 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -38,7 +38,7 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ଓସାର ଓ %2$d ଉଚ୍ଚ"</string>
     <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ୱିଜେଟ୍"</string>
     <string name="add_item_request_drag_hint" msgid="8730547755622776606">"ମୂଳସ୍କ୍ରିନର ଆଖପାଖରେ ୱିଜେଟକୁ ମୁଭ କରିବା ପାଇଁ ଏହାକୁ ସ୍ପର୍ଶ କରି ଧରି ରଖନ୍ତୁ"</string>
-    <string name="add_to_home_screen" msgid="9168649446635919791">"ମୂଳସ୍କ୍ରିନରେ ଯୋଗ କରନ୍ତୁ"</string>
+    <string name="add_to_home_screen" msgid="9168649446635919791">"ହୋମ ସ୍କ୍ରିନରେ ଯୋଗ କରନ୍ତୁ"</string>
     <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g>ର ୱିଜେଟ୍ ମୂଳସ୍କ୍ରିନରେ ଯୋଡ଼ାଗଲା"</string>
     <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{#ଟି ୱିଜେଟ୍}other{#ଟି ୱିଜେଟ୍}}"</string>
     <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{#ଟି ସର୍ଟକଟ୍}other{#ଟି ସର୍ଟକଟ୍}}"</string>
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ଆପ୍‌ ଖୋଜନ୍ତୁ"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"ଆପ୍‌ ଲୋଡ୍‌ ହେଉଛି..."</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ସହିତ ମେଳ ହେଉଥିବା କୌଣସି ଆପ୍‌ ମିଳିଲା ନାହିଁ"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"ଅଧିକ ଆପ୍‌ ଖୋଜନ୍ତୁ"</string>
     <string name="label_application" msgid="8531721983832654978">"ଆପ୍"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"ସବୁ ଆପ"</string>
     <string name="notifications_header" msgid="1404149926117359025">"ବିଜ୍ଞପ୍ତି"</string>
@@ -131,7 +130,7 @@
     <string name="dialog_remove" msgid="6510806469849709407">"କାଢ଼ି ଦିଅନ୍ତୁ"</string>
     <string name="widgets_list" msgid="796804551140113767">"ୱିଜେଟ୍ ତାଲିକା"</string>
     <string name="widgets_list_closed" msgid="6141506579418771922">"ୱିଜେଟ୍ ତାଲିକା ବନ୍ଦ ହୋଇଛି"</string>
-    <string name="action_add_to_workspace" msgid="215894119683164916">"ମୂଳସ୍କ୍ରିନରେ ଯୋଗ କରନ୍ତୁ"</string>
+    <string name="action_add_to_workspace" msgid="215894119683164916">"ହୋମ ସ୍କ୍ରିନରେ ଯୋଗ କରନ୍ତୁ"</string>
     <string name="action_move_here" msgid="2170188780612570250">"ଆଇଟମ୍‌କୁ ଏଠାକୁ ଘୁଞ୍ଚାନ୍ତୁ"</string>
     <string name="item_added_to_workspace" msgid="4211073925752213539">"ହୋମ୍‌ ସ୍କ୍ରୀନରେ ଆଇଟମ୍‌ ଯୋଡ଼ାଗଲା"</string>
     <string name="item_removed" msgid="851119963877842327">"ଆଇଟମକୁ କାଢ଼ି ଦିଆଯାଇଛି"</string>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index 01fbee0..a291a92 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ਐਪਾਂ ਖੋਜੋ"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"ਐਪਾਂ ਨੂੰ ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ..."</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ਨਾਲ ਮੇਲ ਖਾਂਦੀਆਂ ਕੋਈ ਐਪਾਂ ਨਹੀਂ ਮਿਲੀਆਂ"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"ਹੋਰ ਐਪਾਂ ਖੋਜੋ"</string>
     <string name="label_application" msgid="8531721983832654978">"ਐਪ"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"ਸਾਰੀਆਂ ਐਪਾਂ"</string>
     <string name="notifications_header" msgid="1404149926117359025">"ਸੂਚਨਾਵਾਂ"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 4b46f0b..448a56b 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Wyszukaj aplikacje"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Ładuję aplikacje…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nie znaleziono aplikacji pasujących do zapytania „<xliff:g id="QUERY">%1$s</xliff:g>”"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Wyszukaj więcej aplikacji"</string>
     <string name="label_application" msgid="8531721983832654978">"Aplikacja"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Wszystkie aplikacje"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Powiadomienia"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index dbfa0cb..e2d8c9d 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pesquisar aplicações"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"A carregar aplicações…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nenhuma app correspondente a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Pesquisar mais aplicações"</string>
     <string name="label_application" msgid="8531721983832654978">"Aplicação"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Todas as apps"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notificações"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 3a5ed5b..98e8607 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pesquisar apps"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Carregando apps…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nenhum app encontrado que corresponda a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Pesquisar mais apps"</string>
     <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Todos os apps"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notificações"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 6061ea5..794609e 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Caută aplicații"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Se încarcă aplicații…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nu s-a găsit nicio aplicație pentru „<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Caută mai multe aplicații"</string>
     <string name="label_application" msgid="8531721983832654978">"Aplicație"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Toate aplicațiile"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notificări"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 0ad12bd..5987321 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Поиск приложений"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Загрузка приложений…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"По запросу \"<xliff:g id="QUERY">%1$s</xliff:g>\" ничего не найдено"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Искать другие приложения"</string>
     <string name="label_application" msgid="8531721983832654978">"Приложение"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Все приложения"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Уведомления"</string>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index cf3dc64..e030432 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"යෙදුම් සොයන්න"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"යෙදුම් පූරණය වෙමින්…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" සමග ගැළපෙන යෙදුම් හමු නොවිණි"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"තව යෙදුම් සඳහා සොයන්න"</string>
     <string name="label_application" msgid="8531721983832654978">"යෙදුම"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"සියලු යෙදුම්"</string>
     <string name="notifications_header" msgid="1404149926117359025">"දැනුම්දීම්"</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index e3bcc52..ff2c226 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Hľadať aplikácie"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Načítavajú sa aplikácie…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nenašli sa žiadne aplikácie zodpovedajúce dopytu <xliff:g id="QUERY">%1$s</xliff:g>"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Hľadať ďalšie aplikácie"</string>
     <string name="label_application" msgid="8531721983832654978">"Aplikácia"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Všetky aplikácie"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Upozornenia"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 5f952cf..b1f93e8 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Iskanje programov"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Nalaganje aplikacij …"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Ni aplikacij, ki bi ustrezale poizvedbi »<xliff:g id="QUERY">%1$s</xliff:g>«"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Iskanje več aplikacij"</string>
     <string name="label_application" msgid="8531721983832654978">"Aplikacija"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Vse aplikacije"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Obvestila"</string>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index 9f29a87..99bcbaa 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Kërko për aplikacione"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Po ngarkon aplikacionet..."</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nuk u gjet asnjë aplikacion që përputhet me \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Kërko për më shumë aplikacione"</string>
     <string name="label_application" msgid="8531721983832654978">"Aplikacioni"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Të gjitha aplikacionet"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Njoftimet"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 948d9b6..460a73e 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Претражите апликације"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Апликације се учитавају…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Није пронађена ниједна апликација за „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Претражи још апликација"</string>
     <string name="label_application" msgid="8531721983832654978">"Апликација"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Све апликације"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Обавештења"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index c35adb0..6ec274b 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Sök efter appar"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Läser in appar …"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Inga appar som matchar <xliff:g id="QUERY">%1$s</xliff:g> hittades"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Sök efter fler appar"</string>
     <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Alla appar"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Aviseringar"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index c233cc4..147c6e1 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Tafuta programu"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Inapakia programu..."</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Haikupata programu zozote zinazolingana na \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Tafuta programu zaidi"</string>
     <string name="label_application" msgid="8531721983832654978">"Programu"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Programu zote"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Arifa"</string>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index bfec460..d8eacf5 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ஆப்ஸில் தேடுக"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"ஆப்ஸை ஏற்றுகிறது…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" உடன் பொருந்தும் ஆப்ஸ் இல்லை"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"கூடுதல் பயன்பாடுகளைத் தேடு"</string>
     <string name="label_application" msgid="8531721983832654978">"ஆப்ஸ்"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"அனைத்து ஆப்ஸும்"</string>
     <string name="notifications_header" msgid="1404149926117359025">"அறிவிப்புகள்"</string>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index 1d25371..08bccad 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"యాప్‌ల కోసం సెర్చ్ చేయండి"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"అప్లికేషన్‌లను లోడ్ చేస్తోంది…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"కి సరిపోలే అప్లికేషన్‌లేవీ కనుగొనబడలేదు"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"మరిన్ని యాప్‌ల కోసం సెర్చ్ చేయండి"</string>
     <string name="label_application" msgid="8531721983832654978">"యాప్"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"అన్ని యాప్‌లు"</string>
     <string name="notifications_header" msgid="1404149926117359025">"నోటిఫికేషన్‌లు"</string>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index f633b5f..deb4834 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ค้นหาแอป"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"กำลังโหลดแอป…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"ไม่พบแอปที่ตรงกับ \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"ค้นหาแอปเพิ่มเติม"</string>
     <string name="label_application" msgid="8531721983832654978">"แอป"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"แอปทั้งหมด"</string>
     <string name="notifications_header" msgid="1404149926117359025">"การแจ้งเตือน"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index de4f952..a4cd808 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Maghanap ng mga app"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Naglo-load ng mga app…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Walang nahanap na app na tumutugma sa \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Maghanap ng higit pang mga app"</string>
     <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Lahat ng app"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Mga Notification"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index f41284b..c30c2e5 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Uygulamalarda ara"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Uygulamalar yükleniyor…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ile eşleşen uygulama bulunamadı"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Başka uygulamalar ara"</string>
     <string name="label_application" msgid="8531721983832654978">"Uygulama"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Tüm uygulamalar"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Bildirimler"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 360950e..70f8e95 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Пошук додатків"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Завантаження додатків…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Немає додатків для запиту \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Шукати ще додатки"</string>
     <string name="label_application" msgid="8531721983832654978">"Додаток"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Усі додатки"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Сповіщення"</string>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index e68e43e..3d90187 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ایپس تلاش کریں"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"ایپس لوڈ کی جا رہی ہیں…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" سے مماثل کوئی ایپس نہیں ملیں"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"مزید ایپس تلاش کریں"</string>
     <string name="label_application" msgid="8531721983832654978">"ایپ"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"سبھی ایپس"</string>
     <string name="notifications_header" msgid="1404149926117359025">"اطلاعات"</string>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index 9c7ed56..04d07ec 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Ilovalarni qidirish"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Ilovalar yuklanmoqda…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"“<xliff:g id="QUERY">%1$s</xliff:g>” bilan mos hech qanday ilova topilmadi"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Boshqa ilovalarni qidirish"</string>
     <string name="label_application" msgid="8531721983832654978">"Ilova"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Barcha ilovalar"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Bildirishnomalar"</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 30167fa..2329992 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Tìm kiếm ứng dụng"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Đang tải ứng dụng…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Không tìm thấy ứng dụng nào phù hợp với \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Tìm kiếm thêm ứng dụng"</string>
     <string name="label_application" msgid="8531721983832654978">"Ứng dụng"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Tất cả ứng dụng"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Thông báo"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 141d165..929cffa 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"搜索应用"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"正在加载应用…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"未找到与“<xliff:g id="QUERY">%1$s</xliff:g>”相符的应用"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"搜索更多应用"</string>
     <string name="label_application" msgid="8531721983832654978">"应用"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"所有应用"</string>
     <string name="notifications_header" msgid="1404149926117359025">"通知"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 2ff233b..1aea757 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"搜尋應用程式"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"正在載入應用程式…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"找不到與「<xliff:g id="QUERY">%1$s</xliff:g>」相符的應用程式"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"搜尋更多應用程式"</string>
     <string name="label_application" msgid="8531721983832654978">"應用程式"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"所有應用程式"</string>
     <string name="notifications_header" msgid="1404149926117359025">"通知"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 91cfd82..25a7d21 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"搜尋應用程式"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"正在載入應用程式…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"找不到與「<xliff:g id="QUERY">%1$s</xliff:g>」相符的應用程式"</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"搜尋更多應用程式"</string>
     <string name="label_application" msgid="8531721983832654978">"應用程式"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"所有應用程式"</string>
     <string name="notifications_header" msgid="1404149926117359025">"通知"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 12e8568..151ce27 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -59,7 +59,6 @@
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Sesha izinhlelo zokusebenza"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Ilayisha izinhlelo zokusebenza..."</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Azikho izinhlelo zokusebenza ezitholiwe ezifana ne-\"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
-    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Sesha izinhlelo zokusebenza eziningi"</string>
     <string name="label_application" msgid="8531721983832654978">"Uhlelo lokusebenza"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"Zonke izinhlelo zokusebenza"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Izaziso"</string>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 3b71585..8623414 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -158,9 +158,6 @@
 
         <!-- numHotseatIcons defaults to numColumns, if not specified -->
         <attr name="numHotseatIcons" format="integer" />
-        <!-- Number of icons to use when shrinking the hotseat size,
-         defaults to numHotseatIcons / 2 -->
-        <attr name="numShrunkenHotseatIcons" format="integer" />
         <!-- Number of icons to use when extending the hotseat size,
          defaults to 2 * numHotseatIcons -->
         <attr name="numExtendedHotseatIcons" format="integer" />
@@ -187,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 -->
@@ -196,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">
@@ -284,6 +293,8 @@
         <!-- defaults to iconImageSize, if not specified -->
         <attr name="allAppsIconSize" format="float" />
         <!-- defaults to allAppsIconSize, if not specified -->
+        <attr name="allAppsIconSizeLandscape" format="float" />
+        <!-- defaults to allAppsIconSize, if not specified -->
         <attr name="allAppsIconSizeTwoPanelPortrait" format="float" />
         <!-- defaults to allAppsIconSize, if not specified -->
         <attr name="allAppsIconSizeTwoPanelLandscape" format="float" />
@@ -328,14 +339,18 @@
         if not specified -->
         <attr name="allAppsBorderSpaceTwoPanelLandscapeVertical" format="float" />
 
-        <!-- defaults to borderSpaceDps, if not specified -->
-        <attr name="hotseatBorderSpace" format="float" />
-        <!-- defaults to hotseatBorderSpace, if not specified -->
-        <attr name="hotseatBorderSpaceLandscape" format="float" />
-        <!-- defaults to hotseatBorderSpace, if not specified -->
-        <attr name="hotseatBorderSpaceTwoPanelLandscape" format="float" />
-        <!-- defaults to hotseatBorderSpace, if not specified -->
-        <attr name="hotseatBorderSpaceTwoPanelPortrait" 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" />
@@ -383,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/config.xml b/res/values/config.xml
index 3f94c34..1415ed0 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -156,6 +156,7 @@
 
     <item name="swipe_up_rect_scale_damping_ratio" type="dimen" format="float">0.75</item>
     <item name="swipe_up_rect_scale_stiffness" type="dimen" format="float">200</item>
+    <item name="swipe_up_rect_scale_higher_stiffness" type="dimen" format="float">400</item>
 
     <item name="swipe_up_rect_xy_fling_friction" type="dimen" format="float">1.5</item>
 
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index c8554ec..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>
@@ -354,6 +354,8 @@
     <dimen name="taskbar_stashed_size">0dp</dimen>
     <dimen name="qsb_widget_height">0dp</dimen>
     <dimen name="qsb_shadow_height">0dp</dimen>
+    <dimen name="min_hotseat_icon_space">18dp</dimen>
+    <dimen name="min_hotseat_qsb_width">0dp</dimen>
     <dimen name="taskbar_icon_size">44dp</dimen>
     <!-- Note that this applies to both sides of all icons, so visible space is double this. -->
     <dimen name="taskbar_icon_spacing">8dp</dimen>
diff --git a/res/xml/device_profiles.xml b/res/xml/device_profiles.xml
index 0238e7d..407f217 100644
--- a/res/xml/device_profiles.xml
+++ b/res/xml/device_profiles.xml
@@ -200,8 +200,6 @@
             launcher:allAppsBorderSpaceHorizontal="8"
             launcher:allAppsBorderSpaceVertical="16"
             launcher:allAppsBorderSpaceLandscape="16"
-            launcher:hotseatBorderSpace="58"
-            launcher:hotseatBorderSpaceLandscape="50.4"
             launcher:hotseatBarBottomSpace="76"
             launcher:hotseatBarBottomSpaceLandscape="40"
             launcher:canBeDefault="true" />
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 52960a9..9f3e1fa 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -496,8 +496,8 @@
 
                     // Draw reorder drag target.
                     debugPaint.setColor(Color.RED);
-                    canvas.drawCircle(cellCenter[0], cellCenter[1], getReorderRadius(targetCell),
-                            debugPaint);
+                    canvas.drawCircle(cellCenter[0], cellCenter[1],
+                            getReorderRadius(targetCell, 1, 1), debugPaint);
 
                     // Draw folder creation drag target.
                     if (canCreateFolder) {
@@ -912,18 +912,18 @@
         DeviceProfile grid = mActivity.getDeviceProfile();
         float iconVisibleRadius = ICON_VISIBLE_AREA_FACTOR * grid.iconSizePx / 2;
         // Halfway between reorder radius and icon.
-        return (getReorderRadius(targetCell) + iconVisibleRadius) / 2;
+        return (getReorderRadius(targetCell, 1, 1) + iconVisibleRadius) / 2;
     }
 
     /**
      * Returns the max distance from the center of a cell that will start to reorder on drag over.
      */
-    public float getReorderRadius(int[] targetCell) {
+    public float getReorderRadius(int[] targetCell, int spanX, int spanY) {
         int[] centerPoint = mTmpPoint;
         getWorkspaceCellVisualCenter(targetCell[0], targetCell[1], centerPoint);
 
         Rect cellBoundsWithSpacing = mTempRect;
-        cellToRect(targetCell[0], targetCell[1], 1, 1, cellBoundsWithSpacing);
+        cellToRect(targetCell[0], targetCell[1], spanX, spanY, cellBoundsWithSpacing);
         cellBoundsWithSpacing.inset(-mBorderSpace.x / 2, -mBorderSpace.y / 2);
 
         if (canCreateFolder(getChildAt(targetCell[0], targetCell[1]))) {
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 0faa75d..14a467a 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -23,24 +23,28 @@
 import static com.android.launcher3.Utilities.dpiFromPx;
 import static com.android.launcher3.Utilities.pxFromSp;
 import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ICON_OVERLAP_FACTOR;
+import static com.android.launcher3.icons.GraphicsUtils.getShapePath;
 import static com.android.launcher3.testing.shared.ResourceUtils.pxFromDp;
 
 import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.graphics.Path;
 import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.util.DisplayMetrics;
+import android.util.SparseArray;
 import android.view.Surface;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
 import com.android.launcher3.CellLayout.ContainerType;
 import com.android.launcher3.DevicePaddings.DevicePadding;
 import com.android.launcher3.icons.DotRenderer;
-import com.android.launcher3.icons.GraphicsUtils;
 import com.android.launcher3.icons.IconNormalizer;
+import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.uioverrides.ApiWrapper;
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.DisplayController.Info;
@@ -53,6 +57,11 @@
 public class DeviceProfile {
 
     private static final int DEFAULT_DOT_SIZE = 100;
+    private static final float ALL_APPS_TABLET_MAX_ROWS = 5.5f;
+
+    public static final PointF DEFAULT_SCALE = new PointF(1.0f, 1.0f);
+    public static final ViewScaleProvider DEFAULT_PROVIDER = itemInfo -> DEFAULT_SCALE;
+
     // Ratio of empty space, qsb should take up to appear visually centered.
     private final float mQsbCenterFactor;
 
@@ -140,7 +149,6 @@
 
     // Folder content
     public Point folderCellLayoutBorderSpacePx;
-    public int folderCellLayoutBorderSpaceOriginalPx;
     public int folderContentPaddingLeftRight;
     public int folderContentPaddingTop;
 
@@ -154,7 +162,7 @@
     public int folderChildDrawablePaddingPx;
 
     // Hotseat
-    public final int numShownHotseatIcons;
+    public int numShownHotseatIcons;
     public int hotseatCellHeightPx;
     public final boolean areNavButtonsInline;
     // In portrait: size = height, in landscape: size = width
@@ -166,13 +174,12 @@
     // Start is the side next to the nav bar, end is the side next to the workspace
     public final int hotseatBarSidePaddingStartPx;
     public final int hotseatBarSidePaddingEndPx;
+    public int hotseatQsbWidth; // only used when isQsbInline
     public final int hotseatQsbHeight;
     public final int hotseatQsbVisualHeight;
     private final int hotseatQsbShadowHeight;
     public int hotseatBorderSpace;
 
-    public int qsbWidth; // only used when isQsbInline
-
     // All apps
     public Point allAppsBorderSpacePx;
     public int allAppsShiftRange;
@@ -201,7 +208,7 @@
     public int overviewGridSideMargin;
 
     // Widgets
-    public final PointF appWidgetScale = new PointF(1.0f, 1.0f);
+    private final ViewScaleProvider mViewScaleProvider;
 
     // Drop Target
     public int dropTargetBarSizePx;
@@ -221,8 +228,8 @@
     private boolean mIsSeascape;
 
     // Notification dots
-    public DotRenderer mDotRendererWorkSpace;
-    public DotRenderer mDotRendererAllApps;
+    public final DotRenderer mDotRendererWorkSpace;
+    public final DotRenderer mDotRendererAllApps;
 
     // Taskbar
     public boolean isTaskbarPresent;
@@ -236,8 +243,9 @@
 
     /** TODO: Once we fully migrate to staged split, remove "isMultiWindowMode" */
     DeviceProfile(Context context, InvariantDeviceProfile inv, Info info, WindowBounds windowBounds,
-            boolean isMultiWindowMode, boolean transposeLayoutWithOrientation,
-            boolean useTwoPanels, boolean isGestureMode) {
+            SparseArray<DotRenderer> dotRendererCache, boolean isMultiWindowMode,
+            boolean transposeLayoutWithOrientation, boolean useTwoPanels, boolean isGestureMode,
+            @NonNull final ViewScaleProvider viewScaleProvider) {
 
         this.inv = inv;
         this.isLandscape = windowBounds.isLandscape();
@@ -308,10 +316,6 @@
                 + res.getDimensionPixelSize(R.dimen.bottom_sheet_extra_top_padding)
                 + (isTablet ? 0 : edgeMarginPx); // phones need edgeMarginPx additional padding
 
-        allAppsTopPadding = isTablet ? bottomSheetTopPadding : 0;
-        allAppsShiftRange = isTablet
-                ? heightPx - allAppsTopPadding
-                : res.getDimensionPixelSize(R.dimen.all_apps_starting_vertical_translate);
         folderLabelTextScale = res.getFloat(R.dimen.folder_label_text_scale);
         folderContentPaddingLeftRight =
                 res.getDimensionPixelSize(R.dimen.folder_content_padding_left_right);
@@ -322,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);
@@ -363,15 +366,9 @@
                 && hotseatQsbHeight > 0;
         isQsbInline = inv.inlineQsb[mTypeIndex] && canQsbInline;
 
-        // We shrink hotseat sizes regardless of orientation, if nav buttons are inline and QSB
-        // might be inline in either orientations, to keep hotseat size consistent across rotation.
         areNavButtonsInline = isTaskbarPresent && !isGestureMode;
-        if (areNavButtonsInline && canQsbInline) {
-            numShownHotseatIcons = inv.numShrunkenHotseatIcons;
-        } else {
-            numShownHotseatIcons =
-                    isTwoPanels ? inv.numDatabaseHotseatIcons : inv.numShownHotseatIcons;
-        }
+        numShownHotseatIcons =
+                isTwoPanels ? inv.numDatabaseHotseatIcons : inv.numShownHotseatIcons;
 
         numShownAllAppsColumns =
                 isTwoPanels ? inv.numDatabaseAllAppsColumns : inv.numAllAppsColumns;
@@ -406,7 +403,7 @@
         // Add a bit of space between nav bar and hotseat in vertical bar layout.
         hotseatBarSidePaddingStartPx = isVerticalBarLayout() ? workspacePageIndicatorHeight : 0;
         updateHotseatSizes(pxFromDp(inv.iconSize[INDEX_DEFAULT], mMetrics));
-        if (areNavButtonsInline) {
+        if (areNavButtonsInline && !isPhone) {
             /*
              * 3 nav buttons +
              * Spacing between nav buttons +
@@ -461,24 +458,47 @@
         updateWorkspacePadding();
 
         // Hotseat and QSB width depends on updated cellSize and workspace padding
-        hotseatBorderSpace = calculateHotseatBorderSpace();
-        qsbWidth = calculateQsbWidth();
+        recalculateHotseatWidthAndBorderSpace(res);
+
+        // AllApps height calculation depends on updated cellSize
+        if (isTablet) {
+            int collapseHandleHeight =
+                    res.getDimensionPixelOffset(R.dimen.bottom_sheet_handle_area_height);
+            int contentHeight = heightPx - collapseHandleHeight - hotseatQsbHeight;
+            int targetContentHeight = (int) (allAppsCellHeightPx * ALL_APPS_TABLET_MAX_ROWS);
+            allAppsTopPadding = Math.max(mInsets.top, contentHeight - targetContentHeight);
+            allAppsShiftRange = heightPx - allAppsTopPadding;
+        } else {
+            allAppsTopPadding = 0;
+            allAppsShiftRange =
+                    res.getDimensionPixelSize(R.dimen.all_apps_starting_vertical_translate);
+        }
 
         flingToDeleteThresholdVelocity = res.getDimensionPixelSize(
                 R.dimen.drag_flingToDeleteMinVelocity);
 
+        mViewScaleProvider = viewScaleProvider;
+
         // This is done last, after iconSizePx is calculated above.
-        Path dotPath = GraphicsUtils.getShapePath(DEFAULT_DOT_SIZE);
-        mDotRendererWorkSpace = new DotRenderer(iconSizePx, dotPath, DEFAULT_DOT_SIZE);
-        mDotRendererAllApps = iconSizePx == allAppsIconSizePx ? mDotRendererWorkSpace :
-                new DotRenderer(allAppsIconSizePx, dotPath, DEFAULT_DOT_SIZE);
+        mDotRendererWorkSpace = createDotRenderer(iconSizePx, dotRendererCache);
+        mDotRendererAllApps = createDotRenderer(allAppsIconSizePx, dotRendererCache);
+    }
+
+    private static DotRenderer createDotRenderer(
+            int size, @NonNull SparseArray<DotRenderer> cache) {
+        DotRenderer renderer = cache.get(size);
+        if (renderer == null) {
+            renderer = new DotRenderer(size, getShapePath(DEFAULT_DOT_SIZE), DEFAULT_DOT_SIZE);
+            cache.put(size, renderer);
+        }
+        return renderer;
     }
 
     /**
      * QSB width is always calculated because when in 3 button nav the width doesn't follow the
      * width of the hotseat.
      */
-    private int calculateQsbWidth() {
+    private int calculateQsbWidth(int hotseatBorderSpace) {
         if (isQsbInline) {
             int columns = getPanelCount() * inv.numColumns;
             return getIconToIconWidthForColumns(columns)
@@ -525,6 +545,70 @@
         }
     }
 
+    private void recalculateHotseatWidthAndBorderSpace(Resources res) {
+        hotseatBorderSpace = calculateHotseatBorderSpace();
+        hotseatQsbWidth = calculateQsbWidth(hotseatBorderSpace);
+        // Spaces should be correct when there nav buttons are not inline
+        if (!areNavButtonsInline) {
+            return;
+        }
+
+        // Get the maximum width that the hotseat can be
+        int columns = getPanelCount() * inv.numColumns;
+        int maxHotseatWidth = getIconToIconWidthForColumns(columns);
+        int sideSpace = (availableWidthPx - maxHotseatWidth) / 2;
+        int inlineButtonsOverlap = Math.max(0, hotseatBarEndOffset - sideSpace);
+        // decrease how much the nav buttons go "inside" the hotseat
+        maxHotseatWidth -= inlineButtonsOverlap;
+
+        // Get how much space is required to show the hotseat with QSB
+        int requiredWidth = getHotseatRequiredWidth();
+
+        // If spaces are fine, use them
+        if (requiredWidth <= maxHotseatWidth) {
+            return;
+        }
+
+        // Calculate the difference of widths and remove a little from each space between icons
+        // and QSB if it's inline
+        int spaceDiff = requiredWidth - maxHotseatWidth;
+        int numOfSpaces = numShownHotseatIcons - (isQsbInline ? 0 : 1);
+        hotseatBorderSpace -= (spaceDiff / numOfSpaces);
+
+        int minHotseatIconSpaceDp = res.getDimensionPixelSize(R.dimen.min_hotseat_icon_space);
+        int minHotseatQsbWidthDp = res.getDimensionPixelSize(R.dimen.min_hotseat_qsb_width);
+
+        if (hotseatBorderSpace >= minHotseatIconSpaceDp) {
+            return;
+        }
+
+        // Border space can't be less than the minimum
+        hotseatBorderSpace = minHotseatIconSpaceDp;
+        requiredWidth = getHotseatRequiredWidth();
+
+        // If there is an inline qsb, change its size
+        if (isQsbInline) {
+            hotseatQsbWidth -= requiredWidth - maxHotseatWidth;
+            if (hotseatQsbWidth >= minHotseatQsbWidthDp) {
+                return;
+            }
+
+            // QSB can't be less than the minimum
+            hotseatQsbWidth = minHotseatQsbWidthDp;
+        }
+
+        // If it still doesn't fit, start removing icons
+        do {
+            numShownHotseatIcons--;
+            requiredWidth = getHotseatRequiredWidth();
+        } while (requiredWidth > maxHotseatWidth && numShownHotseatIcons > 1);
+
+        // Add back some space between the icons
+        spaceDiff = maxHotseatWidth - requiredWidth;
+        numOfSpaces = numShownHotseatIcons - (isQsbInline ? 0 : 1);
+        hotseatBorderSpace += (spaceDiff / numOfSpaces);
+    }
+
     private Point getCellLayoutBorderSpace(InvariantDeviceProfile idp) {
         return getCellLayoutBorderSpace(idp, 1f);
     }
@@ -565,10 +649,16 @@
                 widthPx, heightPx, availableWidthPx, availableHeightPx, rotationHint);
         bounds.bounds.offsetTo(windowX, windowY);
         bounds.insets.set(mInsets);
+
+        SparseArray<DotRenderer> dotRendererCache = new SparseArray<>();
+        dotRendererCache.put(iconSizePx, mDotRendererWorkSpace);
+        dotRendererCache.put(allAppsIconSizePx, mDotRendererAllApps);
+
         return new Builder(context, inv, mInfo)
                 .setWindowBounds(bounds)
                 .setUseTwoPanels(isTwoPanels)
                 .setMultiWindowMode(isMultiWindowMode)
+                .setDotRendererCache(dotRendererCache)
                 .setGestureMode(isGestureMode);
     }
 
@@ -585,13 +675,18 @@
                 .setMultiWindowMode(true)
                 .build();
 
-        profile.hideWorkspaceLabelsIfNotEnoughSpace();
-
         // We use these scales to measure and layout the widgets using their full invariant profile
         // sizes and then draw them scaled and centered to fit in their multi-window mode cellspans.
         float appWidgetScaleX = (float) profile.getCellSize().x / getCellSize().x;
         float appWidgetScaleY = (float) profile.getCellSize().y / getCellSize().y;
-        profile.appWidgetScale.set(appWidgetScaleX, appWidgetScaleY);
+        if (appWidgetScaleX != 1 || appWidgetScaleY != 1) {
+            final PointF p = new PointF(appWidgetScaleX, appWidgetScaleY);
+            profile = profile.toBuilder(context)
+                    .setViewScaleProvider(i -> p)
+                    .build();
+        }
+
+        profile.hideWorkspaceLabelsIfNotEnoughSpace();
 
         return profile;
     }
@@ -751,15 +846,10 @@
      */
     private int calculateHotseatBorderSpace() {
         if (!isScalableGrid) return 0;
-        //TODO(http://b/228998082) remove this when 3 button spaces are fixed
-        if (areNavButtonsInline) {
-            return pxFromDp(inv.hotseatBorderSpaces[mTypeIndex], mMetrics);
-        } else {
-            int columns = inv.hotseatColumnSpan[mTypeIndex];
-            float hotseatWidthPx = getIconToIconWidthForColumns(columns);
-            float hotseatIconsTotalPx = iconSizePx * numShownHotseatIcons;
-            return (int) (hotseatWidthPx - hotseatIconsTotalPx) / (numShownHotseatIcons - 1);
-        }
+        int columns = inv.hotseatColumnSpan[mTypeIndex];
+        float hotseatWidthPx = getIconToIconWidthForColumns(columns);
+        float hotseatIconsTotalPx = iconSizePx * numShownHotseatIcons;
+        return (int) (hotseatWidthPx - hotseatIconsTotalPx) / (numShownHotseatIcons - 1);
     }
 
 
@@ -840,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);
@@ -1051,10 +1139,7 @@
                     hotseatBarSizePx - hotseatBarBottomPadding - hotseatCellHeightPx;
 
             // Push icons to the side
-            int additionalQsbSpace = isQsbInline ? qsbWidth + hotseatBorderSpace : 0;
-            int requiredWidth = iconSizePx * numShownHotseatIcons
-                    + hotseatBorderSpace * (numShownHotseatIcons - 1)
-                    + additionalQsbSpace;
+            int requiredWidth = getHotseatRequiredWidth();
             int hotseatWidth = Math.min(requiredWidth, availableWidthPx - hotseatBarEndOffset);
             int sideSpacing = (availableWidthPx - hotseatWidth) / 2;
 
@@ -1063,9 +1148,9 @@
 
             boolean isRtl = Utilities.isRtl(context.getResources());
             if (isRtl) {
-                hotseatBarPadding.right += additionalQsbSpace;
+                hotseatBarPadding.right += getAdditionalQsbSpace();
             } else {
-                hotseatBarPadding.left += additionalQsbSpace;
+                hotseatBarPadding.left += getAdditionalQsbSpace();
             }
 
             if (hotseatBarEndOffset > sideSpacing) {
@@ -1076,7 +1161,7 @@
                 hotseatBarPadding.right += diff;
             }
         } else if (isScalableGrid) {
-            int sideSpacing = (availableWidthPx - qsbWidth) / 2;
+            int sideSpacing = (availableWidthPx - hotseatQsbWidth) / 2;
             hotseatBarPadding.set(sideSpacing,
                     0,
                     sideSpacing,
@@ -1100,6 +1185,20 @@
         return hotseatBarPadding;
     }
 
+    private int getAdditionalQsbSpace() {
+        return isQsbInline ? hotseatQsbWidth + hotseatBorderSpace : 0;
+    }
+
+    /**
+     * Calculate how much space the hotseat needs to be shown completely
+     */
+    private int getHotseatRequiredWidth() {
+        int additionalQsbSpace = getAdditionalQsbSpace();
+        return iconSizePx * numShownHotseatIcons
+                + hotseatBorderSpace * (numShownHotseatIcons - 1)
+                + additionalQsbSpace;
+    }
+
     /**
      * Returns the number of pixels the QSB is translated from the bottom of the screen.
      */
@@ -1153,6 +1252,19 @@
     }
 
     /**
+     * Takes the View and return the scales of width and height depending on the DeviceProfile
+     * specifications
+     *
+     * @param itemInfo The tag of the widget view
+     * @return A PointF instance with the x set to be the scale of width, and y being the scale of
+     * height
+     */
+    @NonNull
+    public PointF getAppWidgetScale(@Nullable final ItemInfo itemInfo) {
+        return mViewScaleProvider.getScaleFromItemInfo(itemInfo);
+    }
+
+    /**
      * @return the bounds for which the open folders should be contained within
      */
     public Rect getAbsoluteOpenFolderBounds() {
@@ -1301,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));
 
@@ -1349,7 +1462,7 @@
         writer.println(prefix + "\tnumShownHotseatIcons: " + numShownHotseatIcons);
         writer.println(prefix + pxToDpStr("hotseatBorderSpace", hotseatBorderSpace));
         writer.println(prefix + "\tisQsbInline: " + isQsbInline);
-        writer.println(prefix + pxToDpStr("qsbWidth", qsbWidth));
+        writer.println(prefix + pxToDpStr("hotseatQsbWidth", hotseatQsbWidth));
 
         writer.println(prefix + "\tisTaskbarPresent:" + isTaskbarPresent);
         writer.println(prefix + "\tisTaskbarPresentInApps:" + isTaskbarPresentInApps);
@@ -1461,6 +1574,22 @@
         }
     }
 
+    /**
+     * Handler that deals with ItemInfo of the views for the DeviceProfile
+     */
+    @FunctionalInterface
+    public interface ViewScaleProvider {
+        /**
+         * Get the scales from the view
+         *
+         * @param itemInfo The tag of the widget view
+         * @return PointF instance containing the scale information, or null if using the default
+         * app widget scale of this device profile.
+         */
+        @NonNull
+        PointF getScaleFromItemInfo(@Nullable ItemInfo itemInfo);
+    }
+
     public static class Builder {
         private Context mContext;
         private InvariantDeviceProfile mInv;
@@ -1472,6 +1601,9 @@
         private boolean mIsMultiWindowMode = false;
         private Boolean mTransposeLayoutWithOrientation;
         private Boolean mIsGestureMode;
+        private ViewScaleProvider mViewScaleProvider = null;
+
+        private SparseArray<DotRenderer> mDotRendererCache;
 
         public Builder(Context context, InvariantDeviceProfile inv, Info info) {
             mContext = context;
@@ -1489,6 +1621,10 @@
             return this;
         }
 
+        public Builder setDotRendererCache(SparseArray<DotRenderer> dotRendererCache) {
+            mDotRendererCache = dotRendererCache;
+            return this;
+        }
 
         public Builder setWindowBounds(WindowBounds bounds) {
             mWindowBounds = bounds;
@@ -1505,6 +1641,19 @@
             return this;
         }
 
+        /**
+         * Set the viewScaleProvider for the builder
+         *
+         * @param viewScaleProvider The viewScaleProvider to be set for the
+         *                                DeviceProfile
+         * @return This builder
+         */
+        @NonNull
+        public Builder setViewScaleProvider(@Nullable ViewScaleProvider viewScaleProvider) {
+            mViewScaleProvider = viewScaleProvider;
+            return this;
+        }
+
         public DeviceProfile build() {
             if (mWindowBounds == null) {
                 throw new IllegalArgumentException("Window bounds not set");
@@ -1515,8 +1664,15 @@
             if (mIsGestureMode == null) {
                 mIsGestureMode = DisplayController.getNavigationMode(mContext).hasGestures;
             }
-            return new DeviceProfile(mContext, mInv, mInfo, mWindowBounds, mIsMultiWindowMode,
-                    mTransposeLayoutWithOrientation, mUseTwoPanels, mIsGestureMode);
+            if (mDotRendererCache == null) {
+                mDotRendererCache = new SparseArray<>();
+            }
+            if (mViewScaleProvider == null) {
+                mViewScaleProvider = DEFAULT_PROVIDER;
+            }
+            return new DeviceProfile(mContext, mInv, mInfo, mWindowBounds, mDotRendererCache,
+                    mIsMultiWindowMode, mTransposeLayoutWithOrientation, mUseTwoPanels,
+                    mIsGestureMode, mViewScaleProvider);
         }
     }
 
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 05ed319..bf492a9 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -47,7 +47,6 @@
     private Consumer<Boolean> mOnVisibilityAggregatedCallback;
 
     private final View mQsb;
-    private final int mQsbHeight;
 
     public Hotseat(Context context) {
         this(context, null);
@@ -62,8 +61,6 @@
 
         mQsb = LayoutInflater.from(context).inflate(R.layout.search_container_hotseat, this, false);
         addView(mQsb);
-
-        mQsbHeight = getResources().getDimensionPixelSize(R.dimen.qsb_widget_height);
     }
 
     /**
@@ -171,29 +168,29 @@
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 
-        int qsbWidth = mActivity.getDeviceProfile().qsbWidth;
-
-        mQsb.measure(MeasureSpec.makeMeasureSpec(qsbWidth, MeasureSpec.EXACTLY),
-                MeasureSpec.makeMeasureSpec(mQsbHeight, MeasureSpec.EXACTLY));
+        DeviceProfile dp = mActivity.getDeviceProfile();
+        mQsb.measure(MeasureSpec.makeMeasureSpec(dp.hotseatQsbWidth, MeasureSpec.EXACTLY),
+                MeasureSpec.makeMeasureSpec(dp.hotseatQsbHeight, MeasureSpec.EXACTLY));
     }
 
     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         super.onLayout(changed, l, t, r, b);
 
-        int qsbWidth = mQsb.getMeasuredWidth();
+        int qsbMeasuredWidth = mQsb.getMeasuredWidth();
         int left;
-        if (mActivity.getDeviceProfile().isQsbInline) {
-            int qsbSpace = mActivity.getDeviceProfile().hotseatBorderSpace;
+        DeviceProfile dp = mActivity.getDeviceProfile();
+        if (dp.isQsbInline) {
+            int qsbSpace = dp.hotseatBorderSpace;
             left = Utilities.isRtl(getResources()) ? r - getPaddingRight() + qsbSpace
-                    : l + getPaddingLeft() - qsbWidth - qsbSpace;
+                    : l + getPaddingLeft() - qsbMeasuredWidth - qsbSpace;
         } else {
-            left = (r - l - qsbWidth) / 2;
+            left = (r - l - qsbMeasuredWidth) / 2;
         }
-        int right = left + qsbWidth;
+        int right = left + qsbMeasuredWidth;
 
-        int bottom = b - t - mActivity.getDeviceProfile().getQsbOffsetY();
-        int top = bottom - mQsbHeight;
+        int bottom = b - t - dp.getQsbOffsetY();
+        int top = bottom - dp.hotseatQsbHeight;
         mQsb.layout(left, top, right, bottom);
     }
 
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 9b01734..6a262c3 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -48,6 +48,7 @@
 import androidx.annotation.VisibleForTesting;
 import androidx.core.content.res.ResourcesCompat;
 
+import com.android.launcher3.icons.DotRenderer;
 import com.android.launcher3.model.DeviceGridState;
 import com.android.launcher3.provider.RestoreDbTask;
 import com.android.launcher3.testing.shared.ResourceUtils;
@@ -126,10 +127,12 @@
     public PointF[] minCellSize;
 
     public PointF[] borderSpaces;
-    public float folderBorderSpace;
-    public float[] hotseatBorderSpaces;
     public int inlineNavButtonsEndSpacing;
 
+    public PointF folderBorderSpaces;
+    public PointF folderCellSize;
+    public float folderTopPadding;
+
     public float[] horizontalMargin;
 
     public PointF[] allAppsCellSize;
@@ -145,11 +148,6 @@
     public int numShownHotseatIcons;
 
     /**
-     * Number of icons inside the hotseat area when using 3 buttons navigation.
-     */
-    public int numShrunkenHotseatIcons;
-
-    /**
      * Number of icons inside the hotseat area that is stored in the database. This is greater than
      * or equal to numnShownHotseatIcons, allowing for a seamless transition between two hotseat
      * sizes that share the same DB.
@@ -175,7 +173,7 @@
     public String dbFile;
     public int defaultLayoutId;
     int demoModeLayoutId;
-    boolean[] inlineQsb = new boolean[COUNT_SIZES];
+    public boolean[] inlineQsb = new boolean[COUNT_SIZES];
 
     /**
      * An immutable list of supported profiles.
@@ -260,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);
     }
@@ -358,16 +354,17 @@
         minCellSize = displayOption.minCellSize;
 
         borderSpaces = displayOption.borderSpaces;
-        folderBorderSpace = displayOption.folderBorderSpace;
+
+        folderBorderSpaces = displayOption.folderBorderSpaces;
+        folderCellSize = displayOption.folderCellSize;
+        folderTopPadding = displayOption.folderTopPadding;
 
         horizontalMargin = displayOption.horizontalMargin;
 
         numShownHotseatIcons = closestProfile.numHotseatIcons;
-        numShrunkenHotseatIcons = closestProfile.numShrunkenHotseatIcons;
         numDatabaseHotseatIcons = deviceType == TYPE_MULTI_DISPLAY
                 ? closestProfile.numDatabaseHotseatIcons : closestProfile.numHotseatIcons;
         hotseatColumnSpan = closestProfile.hotseatColumnSpan;
-        hotseatBorderSpaces = displayOption.hotseatBorderSpaces;
         hotseatBarBottomSpace = displayOption.hotseatBarBottomSpace;
         hotseatQsbSpace = displayOption.hotseatQsbSpace;
 
@@ -388,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
@@ -396,10 +393,12 @@
 
         final List<DeviceProfile> localSupportedProfiles = new ArrayList<>();
         defaultWallpaperSize = new Point(displayInfo.currentSize);
+        SparseArray<DotRenderer> dotRendererCache = new SparseArray<>();
         for (WindowBounds bounds : displayInfo.supportedBounds) {
             localSupportedProfiles.add(new DeviceProfile.Builder(context, this, displayInfo)
                     .setUseTwoPanels(deviceType == TYPE_MULTI_DISPLAY)
                     .setWindowBounds(bounds)
+                    .setDotRendererCache(dotRendererCache)
                     .build());
 
             // Wallpaper size should be the maximum of the all possible sizes Launcher expects
@@ -722,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;
@@ -734,11 +739,12 @@
         private final int numAllAppsColumns;
         private final int numDatabaseAllAppsColumns;
         private final int numHotseatIcons;
-        private final int numShrunkenHotseatIcons;
         private final int numDatabaseHotseatIcons;
 
         private final int[] hotseatColumnSpan = new int[COUNT_SIZES];
 
+        private final boolean[] inlineQsb = new boolean[COUNT_SIZES];
+
         private int inlineNavButtonsEndSpacing;
         private final String dbFile;
 
@@ -774,8 +780,6 @@
 
             numHotseatIcons = a.getInt(
                     R.styleable.GridDisplayOption_numHotseatIcons, numColumns);
-            numShrunkenHotseatIcons = a.getInt(
-                    R.styleable.GridDisplayOption_numShrunkenHotseatIcons, numHotseatIcons / 2);
             numDatabaseHotseatIcons = a.getInt(
                     R.styleable.GridDisplayOption_numExtendedHotseatIcons, 2 * numHotseatIcons);
 
@@ -813,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));
@@ -821,26 +838,20 @@
 
     @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];
-        //TODO(http://b/228998082) remove this when 3 button spaces are fixed
-        private final float[] hotseatBorderSpaces = new float[COUNT_SIZES];
         private final float[] hotseatBarBottomSpace = new float[COUNT_SIZES];
         private final float[] hotseatQsbSpace = new float[COUNT_SIZES];
 
@@ -862,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;
 
@@ -934,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);
@@ -1014,7 +1025,9 @@
 
             allAppsIconSizes[INDEX_DEFAULT] = a.getFloat(
                     R.styleable.ProfileDisplayOption_allAppsIconSize, iconSizes[INDEX_DEFAULT]);
-            allAppsIconSizes[INDEX_LANDSCAPE] = allAppsIconSizes[INDEX_DEFAULT];
+            allAppsIconSizes[INDEX_LANDSCAPE] = a.getFloat(
+                    R.styleable.ProfileDisplayOption_allAppsIconSizeLandscape,
+                    iconSizes[INDEX_DEFAULT]);
             allAppsIconSizes[INDEX_TWO_PANEL_PORTRAIT] = a.getFloat(
                     R.styleable.ProfileDisplayOption_allAppsIconSizeTwoPanelPortrait,
                     allAppsIconSizes[INDEX_DEFAULT]);
@@ -1056,18 +1069,6 @@
                     R.styleable.ProfileDisplayOption_horizontalMarginTwoPanelPortrait,
                     horizontalMargin[INDEX_DEFAULT]);
 
-            hotseatBorderSpaces[INDEX_DEFAULT] = a.getFloat(
-                    R.styleable.ProfileDisplayOption_hotseatBorderSpace, borderSpace);
-            hotseatBorderSpaces[INDEX_LANDSCAPE] = a.getFloat(
-                    R.styleable.ProfileDisplayOption_hotseatBorderSpaceLandscape,
-                    hotseatBorderSpaces[INDEX_DEFAULT]);
-            hotseatBorderSpaces[INDEX_TWO_PANEL_LANDSCAPE] = a.getFloat(
-                    R.styleable.ProfileDisplayOption_hotseatBorderSpaceTwoPanelLandscape,
-                    hotseatBorderSpaces[INDEX_DEFAULT]);
-            hotseatBorderSpaces[INDEX_TWO_PANEL_PORTRAIT] = a.getFloat(
-                    R.styleable.ProfileDisplayOption_hotseatBorderSpaceTwoPanelPortrait,
-                    hotseatBorderSpaces[INDEX_DEFAULT]);
-
             hotseatBarBottomSpace[INDEX_DEFAULT] = a.getFloat(
                     R.styleable.ProfileDisplayOption_hotseatBarBottomSpace,
                     ResourcesCompat.getFloat(context.getResources(),
@@ -1117,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) {
@@ -1130,7 +1133,6 @@
                 minCellSize[i].x *= w;
                 minCellSize[i].y *= w;
                 horizontalMargin[i] *= w;
-                hotseatBorderSpaces[i] *= w;
                 hotseatBarBottomSpace[i] *= w;
                 hotseatQsbSpace[i] *= w;
                 allAppsCellSize[i].x *= w;
@@ -1140,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;
         }
@@ -1155,7 +1160,6 @@
                 minCellSize[i].x += p.minCellSize[i].x;
                 minCellSize[i].y += p.minCellSize[i].y;
                 horizontalMargin[i] += p.horizontalMargin[i];
-                hotseatBorderSpaces[i] += p.hotseatBorderSpaces[i];
                 hotseatBarBottomSpace[i] += p.hotseatBarBottomSpace[i];
                 hotseatQsbSpace[i] += p.hotseatQsbSpace[i];
                 allAppsCellSize[i].x += p.allAppsCellSize[i].x;
@@ -1164,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/Launcher.java b/src/com/android/launcher3/Launcher.java
index ff9fe90..761f198 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -18,8 +18,6 @@
 
 import static android.app.PendingIntent.FLAG_IMMUTABLE;
 import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
-import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
-import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
 import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
 import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO;
 import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
@@ -60,7 +58,6 @@
 import static com.android.launcher3.popup.SystemShortcut.WIDGETS;
 import static com.android.launcher3.states.RotationHelper.REQUEST_LOCK;
 import static com.android.launcher3.states.RotationHelper.REQUEST_NONE;
-import static com.android.launcher3.testing.shared.TestProtocol.BAD_STATE;
 import static com.android.launcher3.util.ItemInfoMatcher.forFolderMatch;
 
 import android.animation.Animator;
@@ -311,8 +308,6 @@
     private static final FloatProperty<Hotseat> HOTSEAT_WIDGET_SCALE =
             HOTSEAT_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_WIDGET_TRANSITION);
 
-    private Configuration mOldConfig;
-
     @Thunk
     Workspace<?> mWorkspace;
     @Thunk
@@ -467,7 +462,6 @@
         super.onCreate(savedInstanceState);
 
         LauncherAppState app = LauncherAppState.getInstance(this);
-        mOldConfig = new Configuration(getResources().getConfiguration());
         mModel = app.getModel();
 
         mRotationHelper = new RotationHelper(this);
@@ -513,7 +507,6 @@
 
         if (!mModel.addCallbacksAndLoad(this)) {
             if (!internalStateHandled) {
-                Log.d(BAD_STATE, "Launcher onCreate not binding sync, prevent drawing");
                 // If we are not binding synchronously, pause drawing until initial bind complete,
                 // so that the system could continue to show the device loading prompt
                 mOnInitialBindListener = Boolean.FALSE::booleanValue;
@@ -616,17 +609,6 @@
         dispatchDeviceProfileChanged();
     }
 
-    @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        int diff = newConfig.diff(mOldConfig);
-        if ((diff & (CONFIG_ORIENTATION | CONFIG_SCREEN_SIZE)) != 0) {
-            onIdpChanged(false);
-        }
-
-        mOldConfig.setTo(newConfig);
-        super.onConfigurationChanged(newConfig);
-    }
-
     /**
      * Initializes the drag controller.
      */
@@ -636,6 +618,11 @@
 
     @Override
     public void onIdpChanged(boolean modelPropertiesChanged) {
+        onHandleConfigurationChanged();
+    }
+
+    @Override
+    protected void onHandleConfigurationChanged() {
         if (!initDeviceProfile(mDeviceProfile.inv)) {
             return;
         }
@@ -1507,7 +1494,7 @@
                 root.getViewTreeObserver().removeOnDrawListener(mViewCapture);
             }
             mViewCapture = new ViewCapture(root);
-            root.getViewTreeObserver().addOnDrawListener(mViewCapture);
+            mViewCapture.attach();
         }
     }
 
@@ -3029,7 +3016,10 @@
         writer.println(prefix + "\tmAppWidgetHost.isListening: " + mAppWidgetHost.isListening());
 
         if (mViewCapture != null) {
-            writer.println(prefix + "\tmViewCapture: " + mViewCapture.dumpToString());
+            writer.print(prefix + "\tmViewCapture: ");
+            writer.flush();
+            mViewCapture.dump(fd);
+            writer.println();
         }
 
         // Extra logging for general debugging
diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java
index a5c5c02..1592154 100644
--- a/src/com/android/launcher3/LauncherRootView.java
+++ b/src/com/android/launcher3/LauncherRootView.java
@@ -55,6 +55,8 @@
 
     @Override
     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+        mActivity.handleConfigurationChanged(mActivity.getResources().getConfiguration());
+
         insets = WindowManagerProxy.INSTANCE.get(getContext())
                 .normalizeWindowInsets(getContext(), insets, mTempRect);
         handleSystemWindowInsets(mTempRect);
diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
index 5583eae..486a68f 100644
--- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
@@ -25,6 +25,7 @@
 import android.app.WallpaperManager;
 import android.content.Context;
 import android.graphics.Point;
+import android.graphics.PointF;
 import android.graphics.Rect;
 import android.view.MotionEvent;
 import android.view.View;
@@ -32,6 +33,7 @@
 
 import com.android.launcher3.CellLayout.ContainerType;
 import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.views.ActivityContext;
 import com.android.launcher3.widget.NavigableAppWidgetHostView;
 
@@ -109,8 +111,9 @@
         if (child instanceof NavigableAppWidgetHostView) {
             DeviceProfile profile = mActivity.getDeviceProfile();
             ((NavigableAppWidgetHostView) child).getWidgetInset(profile, mTempRect);
+            final PointF appWidgetScale = profile.getAppWidgetScale((ItemInfo) child.getTag());
             lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX, mCountY,
-                    profile.appWidgetScale.x, profile.appWidgetScale.y, mBorderSpace, mTempRect);
+                    appWidgetScale.x, appWidgetScale.y, mBorderSpace, mTempRect);
         } else {
             lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX, mCountY,
                     mBorderSpace, null);
@@ -133,8 +136,9 @@
 
         if (child instanceof NavigableAppWidgetHostView) {
             ((NavigableAppWidgetHostView) child).getWidgetInset(dp, mTempRect);
+            final PointF appWidgetScale = dp.getAppWidgetScale((ItemInfo) child.getTag());
             lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX, mCountY,
-                    dp.appWidgetScale.x, dp.appWidgetScale.y, mBorderSpace, mTempRect);
+                    appWidgetScale.x, appWidgetScale.y, mBorderSpace, mTempRect);
         } else {
             lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX, mCountY,
                     mBorderSpace, null);
@@ -187,8 +191,9 @@
 
             // Scale and center the widget to fit within its cells.
             DeviceProfile profile = mActivity.getDeviceProfile();
-            float scaleX = profile.appWidgetScale.x;
-            float scaleY = profile.appWidgetScale.y;
+            final PointF appWidgetScale = profile.getAppWidgetScale((ItemInfo) child.getTag());
+            float scaleX = appWidgetScale.x;
+            float scaleY = appWidgetScale.y;
 
             nahv.setScaleToFit(Math.min(scaleX, scaleY));
             nahv.setTranslationForCentering(-(lp.width - (lp.width * scaleX)) / 2.0f,
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 196ee34..b49d646 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -30,7 +30,6 @@
 import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SWIPELEFT;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SWIPERIGHT;
-import static com.android.launcher3.testing.shared.TestProtocol.BAD_STATE;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -45,6 +44,7 @@
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Point;
+import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
@@ -366,7 +366,8 @@
             float scale = 1;
             if (isWidget) {
                 DeviceProfile profile = mLauncher.getDeviceProfile();
-                scale = Utilities.shrinkRect(r, profile.appWidgetScale.x, profile.appWidgetScale.y);
+                final PointF appWidgetScale = profile.getAppWidgetScale(null);
+                scale = Utilities.shrinkRect(r, appWidgetScale.x, appWidgetScale.y);
             }
             size[0] = r.width();
             size[1] = r.height();
@@ -1242,7 +1243,6 @@
         // different effects based on device performance. On at least one relatively high-end
         // device I've tried, translating the launcher causes things to get quite laggy.
         mLauncher.getDragLayer().setTranslationX(transX);
-        Log.d(BAD_STATE, "Workspace onOverlayScrollChanged DragLayer ALPHA_INDEX_OVERLAY=" + alpha);
         mLauncher.getDragLayer().getAlphaProperty(ALPHA_INDEX_OVERLAY).setValue(alpha);
     }
 
@@ -2057,20 +2057,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);
@@ -2091,8 +2082,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);
+                    }
                 }
             }
 
@@ -2118,7 +2117,8 @@
                 final ItemInfo info = (ItemInfo) cell.getTag();
                 boolean isWidget = info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET
                         || info.itemType == LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET;
-                if (isWidget) {
+                if (isWidget && dropTargetLayout != null) {
+                    // animate widget to a valid place
                     int animationType = resizeOnDrop ? ANIMATE_INTO_POSITION_AND_RESIZE :
                             ANIMATE_INTO_POSITION_AND_DISAPPEAR;
                     animateWidgetDrop(info, parent, d.dragView, null, animationType, cell, false);
@@ -2144,6 +2144,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)
@@ -2420,7 +2435,8 @@
         } else if ((mDragMode == DRAG_MODE_NONE || mDragMode == DRAG_MODE_REORDER)
                 && !mReorderAlarm.alarmPending()
                 && (mLastReorderX != reorderX || mLastReorderY != reorderY)
-                && targetCellDistance < mDragTargetLayout.getReorderRadius(mTargetCell)) {
+                && targetCellDistance < mDragTargetLayout.getReorderRadius(mTargetCell, item.spanX,
+                item.spanY)) {
 
             int[] resultSpan = new int[2];
             mDragTargetLayout.performReorder((int) mDragViewVisualCenter[0],
@@ -2878,7 +2894,8 @@
                 r.top -= widgetPadding.top;
                 r.bottom += widgetPadding.bottom;
             }
-            Utilities.shrinkRect(r, profile.appWidgetScale.x, profile.appWidgetScale.y);
+            PointF appWidgetScale = profile.getAppWidgetScale(null);
+            Utilities.shrinkRect(r, appWidgetScale.x, appWidgetScale.y);
         }
 
         mTempFXY[0] = r.left;
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index bdab03f..ecc9d7e 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -232,7 +232,15 @@
                 // Reset pull back progress and alpha after switching states.
                 ALL_APPS_PULL_BACK_TRANSLATION.set(this, 0f);
                 ALL_APPS_PULL_BACK_ALPHA.set(this, 1f);
-                mLauncher.getAppsView().getSearchUiManager().getEditText().hideKeyboard();
+
+                // We only want to close the keyboard if the animation has completed successfully.
+                // The reason is that with keyboard sync, if the user swipes down from All Apps with
+                // the keyboard open and then changes their mind and swipes back up, we want the
+                // keyboard to remain open. However an onCancel signal is sent to the listeners
+                // (success = false), so we need to check for that.
+                if (success) {
+                    mLauncher.getAppsView().getSearchUiManager().getEditText().hideKeyboard();
+                }
             });
         }
 
diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkModeSwitch.java
index aee7c4c..fedc91f 100644
--- a/src/com/android/launcher3/allapps/WorkModeSwitch.java
+++ b/src/com/android/launcher3/allapps/WorkModeSwitch.java
@@ -91,12 +91,12 @@
         MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams();
         if (lp != null) {
             int bottomMargin = getResources().getDimensionPixelSize(R.dimen.work_fab_margin_bottom);
+            DeviceProfile dp = ActivityContext.lookupContext(getContext()).getDeviceProfile();
             if (FeatureFlags.ENABLE_FLOATING_SEARCH_BAR.get()) {
                 bottomMargin <<= 1;  // Double margin to add space above search bar.
-                bottomMargin += getResources().getDimensionPixelSize(R.dimen.qsb_widget_height);
+                bottomMargin += dp.hotseatQsbHeight;
             }
 
-            DeviceProfile dp = ActivityContext.lookupContext(getContext()).getDeviceProfile();
             if (!dp.isGestureMode) {
                 if (dp.isTaskbarPresent) {
                     bottomMargin += dp.taskbarSize;
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 2c0934b..dd58e71 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -144,6 +144,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,
@@ -232,6 +239,11 @@
     public static final BooleanFlag ENABLE_ONE_SEARCH_MOTION = new DeviceFlag(
             "ENABLE_ONE_SEARCH_MOTION", true, "Enables animations in OneSearch.");
 
+    public static final BooleanFlag ENABLE_KEYBOARD_TRANSITION_SYNC = new DeviceFlag(
+            "ENABLE_KEYBOARD_TRANSITION_SYNC", IS_STUDIO_BUILD,
+            "Enable option to synchronize the keyboard open and close animations when transitioning"
+                    + " between home and all apps");
+
     public static final BooleanFlag ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS = new DeviceFlag(
             "ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS", true,
             "Enable option to show keyboard when going to all-apps");
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index a8546e8..c1bab54 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -20,6 +20,7 @@
 import static android.view.View.MeasureSpec.makeMeasureSpec;
 import static android.view.View.VISIBLE;
 
+import static com.android.launcher3.DeviceProfile.DEFAULT_SCALE;
 import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
 import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems;
 import static com.android.launcher3.model.ModelUtils.getMissingHotseatRanks;
@@ -36,6 +37,7 @@
 import android.content.Intent;
 import android.content.res.TypedArray;
 import android.graphics.Color;
+import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.drawable.AdaptiveIconDrawable;
 import android.graphics.drawable.ColorDrawable;
@@ -55,6 +57,7 @@
 import android.view.WindowManager;
 import android.widget.TextClock;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.BubbleTextView;
@@ -100,6 +103,7 @@
 import com.android.launcher3.widget.LocalColorExtractor;
 import com.android.launcher3.widget.NavigableAppWidgetHostView;
 import com.android.launcher3.widget.custom.CustomWidgetManager;
+import com.android.launcher3.widget.util.WidgetSizes;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -173,6 +177,7 @@
     private final Context mContext;
     private final InvariantDeviceProfile mIdp;
     private final DeviceProfile mDp;
+    private final DeviceProfile mDpOrig;
     private final Rect mInsets;
     private final WorkspaceItemInfo mWorkspaceItemInfo;
     private final LayoutInflater mHomeElementInflater;
@@ -192,7 +197,16 @@
         mUiHandler = new Handler(Looper.getMainLooper());
         mContext = context;
         mIdp = idp;
-        mDp = idp.getDeviceProfile(context).copy(context);
+        mDp = idp.getDeviceProfile(context).toBuilder(context).setViewScaleProvider(
+                this::getAppWidgetScale).build();
+        if (context instanceof PreviewContext) {
+            Context tempContext = ((PreviewContext) context).getBaseContext();
+            mDpOrig = new InvariantDeviceProfile(tempContext, InvariantDeviceProfile
+                    .getCurrentGridName(tempContext)).getDeviceProfile(tempContext)
+                    .copy(tempContext);
+        } else {
+            mDpOrig = mDp;
+        }
 
         WindowInsets currentWindowInsets = context.getSystemService(WindowManager.class)
                 .getCurrentWindowMetrics().getWindowInsets();
@@ -390,6 +404,41 @@
         addInScreenFromBind(view, info);
     }
 
+    @NonNull
+    private PointF getAppWidgetScale(@Nullable ItemInfo itemInfo) {
+        if (!(itemInfo instanceof LauncherAppWidgetInfo)) {
+            return DEFAULT_SCALE;
+        }
+        LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) itemInfo;
+        final Size launcherWidgetSize = mLauncherWidgetSpanInfo.get(info.appWidgetId);
+        if (launcherWidgetSize == null) {
+            return DEFAULT_SCALE;
+        }
+        final Size origSize = WidgetSizes.getWidgetSizePx(mDpOrig,
+                launcherWidgetSize.getWidth(), launcherWidgetSize.getHeight());
+        final Size newSize = WidgetSizes.getWidgetSizePx(mDp, info.spanX, info.spanY);
+        final Rect previewInset = new Rect();
+        final Rect origInset = new Rect();
+        // When the setup() is called for the LayoutParams, insets are added to the width
+        // and height of the view. This is not accounted for in WidgetSizes and is handled
+        // here.
+        if (mDp.shouldInsetWidgets()) {
+            previewInset.set(mDp.inv.defaultWidgetPadding);
+        } else {
+            previewInset.setEmpty();
+        }
+        if (mDpOrig.shouldInsetWidgets()) {
+            origInset.set(mDpOrig.inv.defaultWidgetPadding);
+        } else {
+            origInset.setEmpty();
+        }
+
+        return new PointF((float) newSize.getWidth() / (origSize.getWidth()
+                + origInset.left + origInset.right),
+                (float) newSize.getHeight() / (origSize.getHeight()
+                + origInset.top + origInset.bottom));
+    }
+
     private void inflateAndAddPredictedIcon(WorkspaceItemInfo info) {
         CellLayout screen = mWorkspaceScreens.get(info.screenId);
         View view = PredictedAppIconInflater.inflate(mHomeElementInflater, screen, info);
diff --git a/src/com/android/launcher3/graphics/ShadowDrawable.java b/src/com/android/launcher3/graphics/ShadowDrawable.java
deleted file mode 100644
index d8a7070..0000000
--- a/src/com/android/launcher3/graphics/ShadowDrawable.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.graphics;
-
-import android.annotation.TargetApi;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Bitmap;
-import android.graphics.BlurMaskFilter;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorFilter;
-import android.graphics.Paint;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
-import android.util.AttributeSet;
-
-import com.android.launcher3.R;
-import com.android.launcher3.icons.BitmapRenderer;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-
-/**
- * A drawable which adds shadow around a child drawable.
- */
-@TargetApi(Build.VERSION_CODES.O)
-public class ShadowDrawable extends Drawable {
-
-    private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
-
-    private final ShadowDrawableState mState;
-
-    @SuppressWarnings("unused")
-    public ShadowDrawable() {
-        this(new ShadowDrawableState());
-    }
-
-    private ShadowDrawable(ShadowDrawableState state) {
-        mState = state;
-    }
-
-    @Override
-    public void draw(Canvas canvas) {
-        Rect bounds = getBounds();
-        if (bounds.isEmpty()) {
-            return;
-        }
-        if (mState.mLastDrawnBitmap == null) {
-            regenerateBitmapCache();
-        }
-        canvas.drawBitmap(mState.mLastDrawnBitmap, null, bounds, mPaint);
-    }
-
-    @Override
-    public void setAlpha(int alpha) {
-        mPaint.setAlpha(alpha);
-        invalidateSelf();
-    }
-
-    @Override
-    public void setColorFilter(ColorFilter colorFilter) {
-        mPaint.setColorFilter(colorFilter);
-        invalidateSelf();
-    }
-
-    @Override
-    public ConstantState getConstantState() {
-        return mState;
-    }
-
-    @Override
-    public int getOpacity() {
-        return PixelFormat.TRANSLUCENT;
-    }
-
-    @Override
-    public int getIntrinsicHeight() {
-        return mState.mIntrinsicHeight;
-    }
-
-    @Override
-    public int getIntrinsicWidth() {
-        return mState.mIntrinsicWidth;
-    }
-
-    @Override
-    public boolean canApplyTheme() {
-        return mState.canApplyTheme();
-    }
-
-    @Override
-    public void applyTheme(Resources.Theme t) {
-        TypedArray ta = t.obtainStyledAttributes(new int[] {R.attr.isWorkspaceDarkText});
-        boolean isDark = ta.getBoolean(0, false);
-        ta.recycle();
-        if (mState.mIsDark != isDark) {
-            mState.mIsDark = isDark;
-            mState.mLastDrawnBitmap = null;
-            invalidateSelf();
-        }
-    }
-
-    private void regenerateBitmapCache() {
-        // Call mutate, so that the pixel allocation by the underlying vector drawable is cleared.
-        Drawable d = mState.mChildState.newDrawable().mutate();
-        d.setBounds(mState.mShadowSize, mState.mShadowSize,
-                mState.mIntrinsicWidth - mState.mShadowSize,
-                mState.mIntrinsicHeight - mState.mShadowSize);
-        d.setTint(mState.mIsDark ? mState.mDarkTintColor : Color.WHITE);
-
-        if (mState.mIsDark) {
-            // Dark text do not have any shadow, but just the bitmap
-            mState.mLastDrawnBitmap = BitmapRenderer.createHardwareBitmap(
-                    mState.mIntrinsicWidth, mState.mIntrinsicHeight, d::draw);
-        } else {
-            Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
-            paint.setMaskFilter(new BlurMaskFilter(mState.mShadowSize, BlurMaskFilter.Blur.NORMAL));
-
-            // Generate the shadow bitmap
-            int[] offset = new int[2];
-            Bitmap shadow = BitmapRenderer.createSoftwareBitmap(
-                    mState.mIntrinsicWidth, mState.mIntrinsicHeight, d::draw)
-                    .extractAlpha(paint, offset);
-
-            paint.setMaskFilter(null);
-            paint.setColor(mState.mShadowColor);
-            mState.mLastDrawnBitmap = BitmapRenderer.createHardwareBitmap(
-                    mState.mIntrinsicWidth, mState.mIntrinsicHeight, c -> {
-                        c.drawBitmap(shadow, offset[0], offset[1], paint);
-                        d.draw(c);
-                    });
-        }
-    }
-
-    @Override
-    public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs,
-            Resources.Theme theme) throws XmlPullParserException, IOException {
-        super.inflate(r, parser, attrs, theme);
-
-        final TypedArray a = theme == null
-                ? r.obtainAttributes(attrs, R.styleable.ShadowDrawable)
-                : theme.obtainStyledAttributes(attrs, R.styleable.ShadowDrawable, 0, 0);
-        try {
-            Drawable d = a.getDrawable(R.styleable.ShadowDrawable_android_src);
-            if (d == null) {
-                throw new XmlPullParserException("missing src attribute");
-            }
-            mState.mShadowColor = a.getColor(
-                    R.styleable.ShadowDrawable_android_shadowColor, Color.BLACK);
-            mState.mShadowSize = a.getDimensionPixelSize(
-                    R.styleable.ShadowDrawable_android_elevation, 0);
-            mState.mDarkTintColor = a.getColor(
-                    R.styleable.ShadowDrawable_darkTintColor, Color.BLACK);
-
-            mState.mIntrinsicHeight = d.getIntrinsicHeight() + 2 * mState.mShadowSize;
-            mState.mIntrinsicWidth = d.getIntrinsicWidth() + 2 * mState.mShadowSize;
-            mState.mChangingConfigurations = d.getChangingConfigurations();
-
-            mState.mChildState = d.getConstantState();
-        } finally {
-            a.recycle();
-        }
-    }
-
-    private static class ShadowDrawableState extends ConstantState {
-
-        int mChangingConfigurations;
-        int mIntrinsicWidth;
-        int mIntrinsicHeight;
-
-        int mShadowColor;
-        int mShadowSize;
-        int mDarkTintColor;
-
-        boolean mIsDark;
-        Bitmap mLastDrawnBitmap;
-        ConstantState mChildState;
-
-        @Override
-        public Drawable newDrawable() {
-            return new ShadowDrawable(this);
-        }
-
-        @Override
-        public int getChangingConfigurations() {
-            return mChangingConfigurations;
-        }
-
-        @Override
-        public boolean canApplyTheme() {
-            return true;
-        }
-    }
-}
diff --git a/src/com/android/launcher3/model/AllAppsList.java b/src/com/android/launcher3/model/AllAppsList.java
index 4875d83..95150dc 100644
--- a/src/com/android/launcher3/model/AllAppsList.java
+++ b/src/com/android/launcher3/model/AllAppsList.java
@@ -18,6 +18,7 @@
 
 import static com.android.launcher3.model.data.AppInfo.COMPONENT_KEY_COMPARATOR;
 import static com.android.launcher3.model.data.AppInfo.EMPTY_ARRAY;
+import static com.android.launcher3.testing.shared.TestProtocol.INCORRECT_INFO_UPDATED;
 
 import android.content.ComponentName;
 import android.content.Context;
@@ -38,6 +39,7 @@
 import com.android.launcher3.model.data.AppInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.pm.PackageInstallInfo;
+import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.util.FlagOp;
 import com.android.launcher3.util.PackageManagerHelper;
 import com.android.launcher3.util.SafeCloseable;
@@ -270,8 +272,14 @@
     }
 
     public void updateIconsAndLabels(HashSet<String> packages, UserHandle user) {
+        if (TestProtocol.sDebugTracing) {
+            Log.i(INCORRECT_INFO_UPDATED, "updateIconsAndLabels: packages=" + packages);
+        }
         for (AppInfo info : data) {
             if (info.user.equals(user) && packages.contains(info.componentName.getPackageName())) {
+                if (TestProtocol.sDebugTracing) {
+                    Log.i(INCORRECT_INFO_UPDATED, "updateIconsAndLabels: updating info=" + info);
+                }
                 mIconCache.updateTitleAndIcon(info);
                 info.sectionName = mIndex.computeSectionName(info.title);
                 mDataChanged = true;
diff --git a/src/com/android/launcher3/statemanager/StatefulActivity.java b/src/com/android/launcher3/statemanager/StatefulActivity.java
index 2158dea..2a890c3 100644
--- a/src/com/android/launcher3/statemanager/StatefulActivity.java
+++ b/src/com/android/launcher3/statemanager/StatefulActivity.java
@@ -15,9 +15,14 @@
  */
 package com.android.launcher3.statemanager;
 
+import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
+import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
+
 import static com.android.launcher3.LauncherState.FLAG_CLOSE_POPUPS;
 import static com.android.launcher3.LauncherState.FLAG_NON_INTERACTIVE;
 
+import android.content.res.Configuration;
+import android.os.Bundle;
 import android.os.Handler;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -30,6 +35,7 @@
 import com.android.launcher3.Utilities;
 import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory;
 import com.android.launcher3.statemanager.StateManager.StateHandler;
+import com.android.launcher3.util.window.WindowManagerProxy;
 import com.android.launcher3.views.BaseDragLayer;
 
 import java.util.List;
@@ -47,6 +53,17 @@
 
     private LauncherRootView mRootView;
 
+    protected Configuration mOldConfig;
+    private int mOldRotation;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mOldConfig = new Configuration(getResources().getConfiguration());
+        mOldRotation = WindowManagerProxy.INSTANCE.get(this).getRotation(this);
+    }
+
     /**
      * Create handlers to control the property changes for this activity
      */
@@ -186,4 +203,32 @@
     public void runOnBindToTouchInteractionService(Runnable r) {
         r.run();
     }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        handleConfigurationChanged(newConfig);
+        super.onConfigurationChanged(newConfig);
+    }
+
+    /**
+     * Handles configuration change when system calls {@link #onConfigurationChanged}, or on other
+     * situations that configuration might change.
+     */
+    public void handleConfigurationChanged(Configuration newConfig) {
+        int diff = newConfig.diff(mOldConfig);
+        int rotation = WindowManagerProxy.INSTANCE.get(this).getRotation(this);
+        if ((diff & (CONFIG_ORIENTATION | CONFIG_SCREEN_SIZE)) != 0
+                || rotation != mOldRotation) {
+            onHandleConfigurationChanged();
+        }
+
+        mOldConfig.setTo(newConfig);
+        mOldRotation = rotation;
+    }
+
+    /**
+     * Logic for when device configuration changes (rotation, screen size change, multi-window,
+     * etc.)
+     */
+    protected abstract void onHandleConfigurationChanged();
 }
diff --git a/src/com/android/launcher3/states/SpringLoadedState.java b/src/com/android/launcher3/states/SpringLoadedState.java
index 3ca8ba2..b63715c 100644
--- a/src/com/android/launcher3/states/SpringLoadedState.java
+++ b/src/com/android/launcher3/states/SpringLoadedState.java
@@ -58,7 +58,7 @@
         float myCenter = ws.getTop() + halfHeight;
         float cellTopFromCenter = halfHeight - ws.getChildAt(0).getTop();
         float actualCellTop = myCenter - cellTopFromCenter * scale;
-        return new ScaleAndTranslation(scale, 0, (shrunkTop - actualCellTop) / scale);
+        return new ScaleAndTranslation(scale, 0, shrunkTop - actualCellTop);
     }
 
     @Override
diff --git a/src/com/android/launcher3/testing/shared/TestProtocol.java b/src/com/android/launcher3/testing/shared/TestProtocol.java
index d872476..67efb58 100644
--- a/src/com/android/launcher3/testing/shared/TestProtocol.java
+++ b/src/com/android/launcher3/testing/shared/TestProtocol.java
@@ -136,8 +136,8 @@
     public static final String NO_DROP_TARGET = "b/195031154";
     public static final String NULL_INT_SET = "b/200572078";
     public static final String MISSING_PROMISE_ICON = "b/202985412";
-    public static final String BAD_STATE = "b/223498680";
     public static final String TASKBAR_IN_APP_STATE = "b/227657604";
+    public static final String INCORRECT_INFO_UPDATED = "b/239465630";
 
     public static final String REQUEST_EMULATE_DISPLAY = "emulate-display";
     public static final String REQUEST_STOP_EMULATE_DISPLAY = "stop-emulate-display";
diff --git a/src/com/android/launcher3/util/ViewCapture.java b/src/com/android/launcher3/util/ViewCapture.java
index 140971b..58c8269 100644
--- a/src/com/android/launcher3/util/ViewCapture.java
+++ b/src/com/android/launcher3/util/ViewCapture.java
@@ -15,24 +15,30 @@
  */
 package com.android.launcher3.util;
 
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+
 import android.content.res.Resources;
 import android.os.Handler;
-import android.os.Looper;
-import android.os.SystemClock;
+import android.os.Message;
 import android.os.Trace;
 import android.util.Base64;
+import android.util.Base64OutputStream;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver.OnDrawListener;
 
 import androidx.annotation.UiThread;
+import androidx.annotation.WorkerThread;
 
 import com.android.launcher3.view.ViewCaptureData.ExportedData;
 import com.android.launcher3.view.ViewCaptureData.FrameData;
 import com.android.launcher3.view.ViewCaptureData.ViewNode;
 
-import java.util.concurrent.FutureTask;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.util.concurrent.Future;
 
 /**
  * Utility class for capturing view data every frame
@@ -41,122 +47,191 @@
 
     private static final String TAG = "ViewCapture";
 
+    // Number of frames to keep in memory
     private static final int MEMORY_SIZE = 2000;
+    // Initial size of the reference pool. This is at least be 5 * total number of views in
+    // Launcher. This allows the first free frames avoid object allocation during view capture.
+    private static final int INIT_POOL_SIZE = 300;
 
     private final View mRoot;
-    private final long[] mFrameTimes = new long[MEMORY_SIZE];
-    private final Node[] mNodes = new Node[MEMORY_SIZE];
+    private final Resources mResources;
 
-    private int mFrameIndex = -1;
+    private final Handler mHandler;
+    private final ViewRef mViewRef = new ViewRef();
+
+    private int mFrameIndexBg = -1;
+    private final long[] mFrameTimesBg = new long[MEMORY_SIZE];
+    private final ViewPropertyRef[] mNodesBg = new ViewPropertyRef[MEMORY_SIZE];
+
+    // Pool used for capturing view tree on the UI thread.
+    private ViewRef mPool = new ViewRef();
 
     /**
      * @param root the root view for the capture data
      */
     public ViewCapture(View root) {
         mRoot = root;
+        mResources = root.getResources();
+        mHandler = new Handler(UI_HELPER_EXECUTOR.getLooper(), this::captureViewPropertiesBg);
+    }
+
+    /**
+     * Attaches the ViewCapture to the root
+     */
+    public void attach() {
+        mHandler.post(this::initPool);
     }
 
     @Override
     public void onDraw() {
         Trace.beginSection("view_capture");
-        long now = SystemClock.elapsedRealtimeNanos();
-
-        mFrameIndex++;
-        if (mFrameIndex >= MEMORY_SIZE) {
-            mFrameIndex = 0;
-        }
-        mFrameTimes[mFrameIndex] = now;
-        mNodes[mFrameIndex] = captureView(mRoot, mNodes[mFrameIndex]);
+        captureViewTree(mRoot, mViewRef);
+        Message m = Message.obtain(mHandler);
+        m.obj = mViewRef.next;
+        mHandler.sendMessage(m);
         Trace.endSection();
     }
 
     /**
+     * Captures the View property on the background thread, and transfer all the ViewRef objects
+     * back to the pool
+     */
+    @WorkerThread
+    private boolean captureViewPropertiesBg(Message msg) {
+        ViewRef start = (ViewRef) msg.obj;
+        long time = msg.getWhen();
+        if (start == null) {
+            return false;
+        }
+        mFrameIndexBg++;
+        if (mFrameIndexBg >= MEMORY_SIZE) {
+            mFrameIndexBg = 0;
+        }
+        mFrameTimesBg[mFrameIndexBg] = time;
+
+        ViewPropertyRef recycle = mNodesBg[mFrameIndexBg];
+
+        ViewPropertyRef result = null;
+        ViewPropertyRef resultEnd = null;
+
+        ViewRef current = start;
+        ViewRef last = start;
+        while (current != null) {
+            ViewPropertyRef propertyRef = recycle;
+            if (propertyRef == null) {
+                propertyRef = new ViewPropertyRef();
+            } else {
+                recycle = recycle.next;
+                propertyRef.next = null;
+            }
+
+            propertyRef.transfer(current);
+            last = current;
+            current = current.next;
+
+            if (result == null) {
+                result = propertyRef;
+                resultEnd = result;
+            } else {
+                resultEnd.next = propertyRef;
+                resultEnd = propertyRef;
+            }
+        }
+        mNodesBg[mFrameIndexBg] = result;
+        ViewRef end = last;
+        Executors.MAIN_EXECUTOR.execute(() -> addToPool(start, end));
+        return true;
+    }
+
+    @UiThread
+    private void addToPool(ViewRef start, ViewRef end) {
+        end.next = mPool;
+        mPool = start;
+    }
+
+    @WorkerThread
+    private void initPool() {
+        ViewRef start = new ViewRef();
+        ViewRef current = start;
+
+        for (int i = 0; i < INIT_POOL_SIZE; i++) {
+            current.next = new ViewRef();
+            current = current.next;
+        }
+
+        ViewRef end = current;
+        Executors.MAIN_EXECUTOR.execute(() ->  {
+            addToPool(start, end);
+            if (mRoot.isAttachedToWindow()) {
+                mRoot.getViewTreeObserver().addOnDrawListener(this);
+            }
+        });
+    }
+
+    /**
      * Creates a proto of all the data captured so far.
      */
-    public String dumpToString() {
-        Handler handler = mRoot.getHandler();
-        if (handler == null) {
-            handler = Executors.MAIN_EXECUTOR.getHandler();
-        }
-        FutureTask<ExportedData> task = new FutureTask<>(this::dumpToProtoUI);
-        if (Looper.myLooper() == handler.getLooper()) {
-            task.run();
-        } else {
-            handler.post(task);
-        }
-        try {
-            return Base64.encodeToString(task.get().toByteArray(),
+    public void dump(FileDescriptor out) {
+        Future<ExportedData> task = UI_HELPER_EXECUTOR.submit(this::dumpToProto);
+        try (OutputStream os = new FileOutputStream(out)) {
+            ExportedData data = task.get();
+            Base64OutputStream encodedOS = new Base64OutputStream(os,
                     Base64.NO_CLOSE | Base64.NO_PADDING | Base64.NO_WRAP);
+            data.writeTo(encodedOS);
+            encodedOS.close();
+            os.flush();
         } catch (Exception e) {
             Log.e(TAG, "Error capturing proto", e);
-            return "--error--";
         }
     }
 
-    @UiThread
-    private ExportedData dumpToProtoUI() {
+    @WorkerThread
+    private ExportedData dumpToProto() {
         ExportedData.Builder dataBuilder = ExportedData.newBuilder();
-        Resources res = mRoot.getResources();
+        Resources res = mResources;
 
-        int size = (mNodes[MEMORY_SIZE - 1] == null) ? mFrameIndex + 1 : MEMORY_SIZE;
+        int size = (mNodesBg[MEMORY_SIZE - 1] == null) ? mFrameIndexBg + 1 : MEMORY_SIZE;
         for (int i = size - 1; i >= 0; i--) {
-            int index = (MEMORY_SIZE + mFrameIndex - i) % MEMORY_SIZE;
+            int index = (MEMORY_SIZE + mFrameIndexBg - i) % MEMORY_SIZE;
+            ViewNode.Builder nodeBuilder = ViewNode.newBuilder();
+            mNodesBg[index].toProto(res, nodeBuilder);
             dataBuilder.addFrameData(FrameData.newBuilder()
-                    .setNode(mNodes[index].toProto(res))
-                    .setTimestamp(mFrameTimes[index]));
+                    .setNode(nodeBuilder)
+                    .setTimestamp(mFrameTimesBg[index]));
         }
         return dataBuilder.build();
     }
 
-    private Node captureView(View view, Node recycle) {
-        Node result = recycle == null ? new Node() : recycle;
-
-        result.clazz = view.getClass();
-        result.hashCode = view.hashCode();
-        result.id = view.getId();
-        result.left = view.getLeft();
-        result.top = view.getTop();
-        result.right = view.getRight();
-        result.bottom = view.getBottom();
-        result.scrollX = view.getScrollX();
-        result.scrollY = view.getScrollY();
-
-        result.translateX = view.getTranslationX();
-        result.translateY = view.getTranslationY();
-        result.scaleX = view.getScaleX();
-        result.scaleY = view.getScaleY();
-        result.alpha = view.getAlpha();
-
-        result.visibility = view.getVisibility();
-        result.willNotDraw = view.willNotDraw();
-
-        if (view instanceof ViewGroup) {
-            ViewGroup parent = (ViewGroup) view;
-            result.clipChildren = parent.getClipChildren();
-            int childCount = parent.getChildCount();
-            if (childCount == 0) {
-                result.children = null;
-            } else {
-                result.children = captureView(parent.getChildAt(0), result.children);
-                Node lastChild = result.children;
-                for (int i = 1; i < childCount; i++) {
-                    lastChild.sibling = captureView(parent.getChildAt(i), lastChild.sibling);
-                    lastChild = lastChild.sibling;
-                }
-                lastChild.sibling = null;
-            }
+    private ViewRef captureViewTree(View view, ViewRef start) {
+        ViewRef ref;
+        if (mPool != null) {
+            ref = mPool;
+            mPool = mPool.next;
+            ref.next = null;
         } else {
-            result.clipChildren = false;
-            result.children = null;
+            ref = new ViewRef();
         }
-        return result;
+        ref.view = view;
+        start.next = ref;
+        if (view instanceof ViewGroup) {
+            ViewRef result = ref;
+            ViewGroup parent = (ViewGroup) view;
+            int childCount = ref.childCount = parent.getChildCount();
+            for (int i = 0; i < childCount; i++) {
+                result = captureViewTree(parent.getChildAt(i), result);
+            }
+            return result;
+        } else {
+            ref.childCount = 0;
+            return ref;
+        }
     }
 
-    private static class Node {
-
+    private static class ViewPropertyRef {
         // We store reference in memory to avoid generating and storing too many strings
         public Class clazz;
         public int hashCode;
+        public int childCount = 0;
 
         public int id;
         public int left, top, right, bottom;
@@ -165,15 +240,48 @@
         public float translateX, translateY;
         public float scaleX, scaleY;
         public float alpha;
+        public float elevation;
 
         public int visibility;
         public boolean willNotDraw;
         public boolean clipChildren;
 
-        public Node sibling;
-        public Node children;
+        public ViewPropertyRef next;
 
-        public ViewNode toProto(Resources res) {
+        public void transfer(ViewRef viewRef) {
+            childCount = viewRef.childCount;
+
+            View view = viewRef.view;
+            viewRef.view = null;
+
+            clazz = view.getClass();
+            hashCode = view.hashCode();
+            id = view.getId();
+            left = view.getLeft();
+            top = view.getTop();
+            right = view.getRight();
+            bottom = view.getBottom();
+            scrollX = view.getScrollX();
+            scrollY = view.getScrollY();
+
+            translateX = view.getTranslationX();
+            translateY = view.getTranslationY();
+            scaleX = view.getScaleX();
+            scaleY = view.getScaleY();
+            alpha = view.getAlpha();
+
+            visibility = view.getVisibility();
+            willNotDraw = view.willNotDraw();
+            elevation = view.getElevation();
+        }
+
+        /**
+         * Converts the data to the proto representation and returns the next property ref
+         * at the end of the iteration.
+         * @param res
+         * @return
+         */
+        public ViewPropertyRef toProto(Resources res, ViewNode.Builder outBuilder) {
             String resolvedId;
             if (id >= 0) {
                 try {
@@ -184,9 +292,7 @@
             } else {
                 resolvedId = "NO_ID";
             }
-
-            ViewNode.Builder result = ViewNode.newBuilder()
-                    .setClassname(clazz.getName() + "@" + hashCode)
+            outBuilder.setClassname(clazz.getName() + "@" + hashCode)
                     .setId(resolvedId)
                     .setLeft(left)
                     .setTop(top)
@@ -199,14 +305,22 @@
                     .setAlpha(alpha)
                     .setVisibility(visibility)
                     .setWillNotDraw(willNotDraw)
+                    .setElevation(elevation)
                     .setClipChildren(clipChildren);
-            Node child = children;
-            while (child != null) {
-                result.addChildren(child.toProto(res));
-                child = child.sibling;
-            }
-            return result.build();
-        }
 
+            ViewPropertyRef result = next;
+            for (int i = 0; (i < childCount) && (result != null); i++) {
+                ViewNode.Builder childBuilder = ViewNode.newBuilder();
+                result = result.toProto(res, childBuilder);
+                outBuilder.addChildren(childBuilder);
+            }
+            return result;
+        }
+    }
+
+    private static class ViewRef {
+        public View view;
+        public int childCount = 0;
+        public ViewRef next;
     }
 }
diff --git a/tests/Android.bp b/tests/Android.bp
index 54cded0..1584308 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -24,6 +24,18 @@
       "src/**/*.java",
       "src/**/*.kt"
     ],
+    exclude_srcs: [
+        ":launcher-non-quickstep-tests-src"
+    ],
+}
+
+// Source code used for non-quickstep tests
+filegroup {
+    name: "launcher-non-quickstep-tests-src",
+    srcs: [
+       "src/com/android/launcher3/nonquickstep/**/*.java",
+       "src/com/android/launcher3/nonquickstep/**/*.kt",
+    ],
 }
 
 // Source code used for oop test helpers
@@ -84,6 +96,7 @@
     name: "Launcher3Tests",
     srcs: [
         ":launcher-tests-src",
+        ":launcher-non-quickstep-tests-src",
     ],
     static_libs: ["Launcher3TestLib"],
     libs: [
diff --git a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
index 4732fc1..2c1cbdf 100644
--- a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
+++ b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
@@ -18,7 +18,9 @@
 import android.content.Context
 import android.graphics.PointF
 import android.graphics.Rect
+import android.util.SparseArray
 import androidx.test.core.app.ApplicationProvider
+import com.android.launcher3.DeviceProfile.DEFAULT_PROVIDER;
 import com.android.launcher3.util.DisplayController.Info
 import com.android.launcher3.util.WindowBounds
 import org.junit.Before
@@ -56,10 +58,12 @@
         inv,
         info,
         windowBounds,
+        SparseArray(),
         isMultiWindowMode,
         transposeLayoutWithOrientation,
         useTwoPanels,
-        isGestureMode
+        isGestureMode,
+        DEFAULT_PROVIDER
     )
 
     protected fun initializeVarsForPhone(isGestureMode: Boolean = true,
@@ -92,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
@@ -111,8 +113,14 @@
                     PointF(16f, 16f),
                     PointF(16f, 16f)
             ).toTypedArray()
-            folderBorderSpace = 16f
-            hotseatBorderSpaces = FloatArray(4) { 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 }
@@ -134,8 +142,6 @@
 
             numShownHotseatIcons = 4
 
-            numShrunkenHotseatIcons = 4
-
             numDatabaseHotseatIcons = 4
 
             hotseatColumnSpan = IntArray(4) { 4 }
@@ -198,7 +204,13 @@
                     PointF(16f, 64f),
                     PointF(16f, 64f)
             ).toTypedArray()
-            hotseatBorderSpaces = floatArrayOf(58f, 50.4f, 58f, 58f)
+
+            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)
@@ -220,8 +232,6 @@
 
             numShownHotseatIcons = 6
 
-            numShrunkenHotseatIcons = 5
-
             numDatabaseHotseatIcons = 6
 
             hotseatColumnSpan = intArrayOf(6, 4, 6, 6)
@@ -275,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
@@ -294,8 +302,13 @@
                     PointF(16f, 20f),
                     PointF(20f, 20f)
             ).toTypedArray()
-            folderBorderSpace = 16f
-            hotseatBorderSpaces = floatArrayOf(36f, 36f, 18f, 23.3f)
+
+            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)
@@ -317,8 +330,6 @@
 
             numShownHotseatIcons = 6
 
-            numShrunkenHotseatIcons = 6
-
             numDatabaseHotseatIcons = 6
 
             hotseatColumnSpan = IntArray(4) { 6 }
diff --git a/tests/src/com/android/launcher3/HotseatShownIconsTest.kt b/tests/src/com/android/launcher3/HotseatShownIconsTest.kt
deleted file mode 100644
index 95651ca..0000000
--- a/tests/src/com/android/launcher3/HotseatShownIconsTest.kt
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3
-
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.launcher3.InvariantDeviceProfile.TYPE_MULTI_DISPLAY
-import com.android.launcher3.InvariantDeviceProfile.TYPE_PHONE
-import com.android.launcher3.InvariantDeviceProfile.TYPE_TABLET
-import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-
-/**
- * Test for [DeviceProfile]
- */
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class HotseatShownIconsTest : DeviceProfileBaseTest() {
-
-    @Test
-    fun hotseat_size_is_shrunk_if_needed_when_large_screen() {
-        initializeVarsForTablet(isLandscape = true)
-        inv = inv!!.apply {
-            deviceType = TYPE_MULTI_DISPLAY
-            inlineQsb = booleanArrayOf(
-                false,
-                false,
-                false,
-                true // two panels landscape
-            )
-        }
-        useTwoPanels = true
-
-        isGestureMode = false
-        val dp = newDP()
-
-        if (dp.hotseatQsbHeight > 0) {
-            assertThat(dp.isQsbInline).isTrue()
-            assertThat(dp.numShownHotseatIcons).isEqualTo(5)
-        } else { // Launcher3 doesn't have QSB height
-            assertThat(dp.isQsbInline).isFalse()
-            assertThat(dp.numShownHotseatIcons).isEqualTo(6)
-        }
-    }
-
-    /**
-     * For consistency, the hotseat should shrink if any orientation on the device type has an
-     * inline qsb
-     */
-    @Test
-    fun hotseat_size_is_shrunk_even_in_portrait_when_large_screen() {
-        initializeVarsForTablet()
-        inv = inv!!.apply {
-            deviceType = TYPE_MULTI_DISPLAY
-            inlineQsb = booleanArrayOf(
-                false,
-                false,
-                false,
-                true // two panels landscape
-            )
-        }
-        useTwoPanels = true
-
-        isGestureMode = false
-        val dp = newDP()
-
-        if (dp.hotseatQsbHeight > 0) {
-            assertThat(dp.isQsbInline).isFalse()
-            assertThat(dp.numShownHotseatIcons).isEqualTo(5)
-        } else { // Launcher3 doesn't have QSB height
-            assertThat(dp.isQsbInline).isFalse()
-            assertThat(dp.numShownHotseatIcons).isEqualTo(6)
-        }
-    }
-
-    @Test
-    fun hotseat_size_is_default_when_small_screen() {
-        initializeVarsForPhone()
-        inv = inv!!.apply {
-            deviceType = TYPE_MULTI_DISPLAY
-        }
-        useTwoPanels = true
-
-        val dp = newDP()
-
-        assertThat(dp.numShownHotseatIcons).isEqualTo(4)
-    }
-
-    @Test
-    fun hotseat_size_is_not_shrunk_on_gesture_tablet() {
-        initializeVarsForTablet(isLandscape = true)
-        inv = inv!!.apply {
-            deviceType = TYPE_TABLET
-            inlineQsb = booleanArrayOf(
-                    false,
-                    true, // landscape
-                    false,
-                    false
-            )
-            numShownHotseatIcons = 6
-        }
-
-        isGestureMode = true
-        val dp = newDP()
-
-        if (dp.hotseatQsbHeight > 0) {
-            assertThat(dp.isQsbInline).isTrue()
-            assertThat(dp.numShownHotseatIcons).isEqualTo(6)
-        } else { // Launcher3 doesn't have QSB height
-            assertThat(dp.isQsbInline).isFalse()
-            assertThat(dp.numShownHotseatIcons).isEqualTo(6)
-        }
-    }
-
-    @Test
-    fun hotseat_size_is_shrunk_if_needed_on_tablet() {
-        initializeVarsForTablet(isLandscape = true)
-        inv = inv!!.apply {
-            deviceType = TYPE_TABLET
-            inlineQsb = booleanArrayOf(
-                false,
-                true, // landscape
-                false,
-                false
-            )
-            numShownHotseatIcons = 6
-        }
-
-        isGestureMode = false
-        val dp = newDP()
-
-        if (dp.hotseatQsbHeight > 0) {
-            assertThat(dp.isQsbInline).isTrue()
-            assertThat(dp.numShownHotseatIcons).isEqualTo(5)
-        } else { // Launcher3 doesn't have QSB height
-            assertThat(dp.isQsbInline).isFalse()
-            assertThat(dp.numShownHotseatIcons).isEqualTo(6)
-        }
-    }
-
-    /**
-     * For consistency, the hotseat should shrink if any orientation on the device type has an
-     * inline qsb
-     */
-    @Test
-    fun hotseat_size_is_shrunk_even_in_portrait_on_tablet() {
-        initializeVarsForTablet()
-        inv = inv!!.apply {
-            deviceType = TYPE_TABLET
-            inlineQsb = booleanArrayOf(
-                false,
-                true, // landscape
-                false,
-                false
-            )
-            numShownHotseatIcons = 6
-        }
-
-        isGestureMode = false
-        val dp = newDP()
-
-        if (dp.hotseatQsbHeight > 0) {
-            assertThat(dp.isQsbInline).isFalse()
-            assertThat(dp.numShownHotseatIcons).isEqualTo(5)
-        } else { // Launcher3 doesn't have QSB height
-            assertThat(dp.isQsbInline).isFalse()
-            assertThat(dp.numShownHotseatIcons).isEqualTo(6)
-        }
-    }
-
-}
\ No newline at end of file
diff --git a/tests/src/com/android/launcher3/celllayout/testcases/FullReorderCase.java b/tests/src/com/android/launcher3/celllayout/testcases/FullReorderCase.java
index ff03a50..1326389 100644
--- a/tests/src/com/android/launcher3/celllayout/testcases/FullReorderCase.java
+++ b/tests/src/com/android/launcher3/celllayout/testcases/FullReorderCase.java
@@ -20,46 +20,65 @@
 import java.util.Map;
 
 public class FullReorderCase {
+
+    /** 5x5 Test
+     **/
     private static final String START_BOARD_STR_5x5 = ""
             + "xxxxx\n"
             + "222mm\n"
             + "222mm\n"
             + "ad111\n"
             + "bc111";
-
     private static final Point MOVE_TO_5x5 = new Point(0, 4);
-
     private static final String END_BOARD_STR_5x5 = ""
             + "xxxxx\n"
             + "222ad\n"
             + "222bc\n"
             + "mm111\n"
             + "mm111";
-
     private static final ReorderTestCase TEST_CASE_5x5 = new ReorderTestCase(START_BOARD_STR_5x5,
             MOVE_TO_5x5,
             END_BOARD_STR_5x5);
 
+    /** 6x5 Test
+     **/
     private static final String START_BOARD_STR_6x5 = ""
             + "xxxxxx\n"
             + "2222mm\n"
             + "2222mm\n"
             + "ad1111\n"
             + "bc1111";
-
     private static final Point MOVE_TO_6x5 = new Point(0, 4);
-
     private static final String END_BOARD_STR_6x5 = ""
             + "xxxxxx\n"
             + "2222ad\n"
             + "2222bc\n"
             + "mm1111\n"
             + "mm1111";
-
     private static final ReorderTestCase TEST_CASE_6x5 = new ReorderTestCase(START_BOARD_STR_6x5,
             MOVE_TO_6x5,
             END_BOARD_STR_6x5);
 
+    /** 4x4 Test
+     **/
+    private static final String START_BOARD_STR_4x4 = ""
+            + "xxxx\n"
+            + "22mm\n"
+            + "admm\n"
+            + "bc11";
+    private static final Point MOVE_TO_4x4 = new Point(0, 3);
+    private static final String END_BOARD_STR_4x4 = ""
+            + "xxxx\n"
+            + "22ad\n"
+            + "mmbc\n"
+            + "mm11";
+
+    private static final ReorderTestCase TEST_CASE_4x4 = new ReorderTestCase(START_BOARD_STR_4x4,
+            MOVE_TO_4x4,
+            END_BOARD_STR_4x4);
+
     public static final Map<Point, ReorderTestCase> TEST_BY_GRID_SIZE =
-            Map.of(new Point(5, 5), TEST_CASE_5x5, new Point(6, 5), TEST_CASE_6x5);
+            Map.of(new Point(5, 5), TEST_CASE_5x5,
+                    new Point(6, 5), TEST_CASE_6x5,
+                    new Point(4, 4), TEST_CASE_4x4);
 }
diff --git a/tests/src/com/android/launcher3/celllayout/testcases/MoveOutReorderCase.java b/tests/src/com/android/launcher3/celllayout/testcases/MoveOutReorderCase.java
index 32bf05a..1701390 100644
--- a/tests/src/com/android/launcher3/celllayout/testcases/MoveOutReorderCase.java
+++ b/tests/src/com/android/launcher3/celllayout/testcases/MoveOutReorderCase.java
@@ -20,47 +20,64 @@
 import java.util.Map;
 
 public class MoveOutReorderCase {
+
+    /** 5x5 Test
+     **/
     private static final String START_BOARD_STR_5x5 = ""
             + "xxxxx\n"
             + "34-m-\n"
             + "35111\n"
             + "32111\n"
             + "32111";
-
     private static final Point MOVE_TO_5x5 = new Point(1, 2);
-
     private static final String END_BOARD_STR_5x5 = ""
             + "xxxxx\n"
             + "345--\n"
             + "3m111\n"
             + "32111\n"
             + "32111";
-
     private static final ReorderTestCase TEST_CASE_5x5 = new ReorderTestCase(START_BOARD_STR_5x5,
             MOVE_TO_5x5,
             END_BOARD_STR_5x5);
 
-
+    /** 6x5 Test
+     **/
     private static final String START_BOARD_STR_6x5 = ""
             + "xxxxxx\n"
             + "34-m--\n"
             + "351111\n"
             + "321111\n"
             + "321111";
-
     private static final Point MOVE_TO_6x5 = new Point(1, 2);
-
     private static final String END_BOARD_STR_6x5 = ""
             + "xxxxxx\n"
             + "345---\n"
             + "3m1111\n"
             + "321111\n"
             + "321111";
-
     private static final ReorderTestCase TEST_CASE_6x5 = new ReorderTestCase(START_BOARD_STR_6x5,
             MOVE_TO_6x5,
             END_BOARD_STR_6x5);
 
+    /** 4x4 Test
+     **/
+    private static final String START_BOARD_STR_4x4 = ""
+            + "xxxx\n"
+            + "34-m\n"
+            + "3511\n"
+            + "3211";
+    private static final Point MOVE_TO_4x4 = new Point(1, 2);
+    private static final String END_BOARD_STR_4x4 = ""
+            + "xxxx\n"
+            + "345-\n"
+            + "3m11\n"
+            + "3211";
+    private static final ReorderTestCase TEST_CASE_4x4 = new ReorderTestCase(START_BOARD_STR_4x4,
+            MOVE_TO_4x4,
+            END_BOARD_STR_4x4);
+
     public static final Map<Point, ReorderTestCase> TEST_BY_GRID_SIZE =
-            Map.of(new Point(5, 5), TEST_CASE_5x5, new Point(6, 5), TEST_CASE_6x5);
+            Map.of(new Point(5, 5), TEST_CASE_5x5,
+                    new Point(6, 5), TEST_CASE_6x5,
+                    new Point(4, 4), TEST_CASE_4x4);
 }
diff --git a/tests/src/com/android/launcher3/celllayout/testcases/PushReorderCase.java b/tests/src/com/android/launcher3/celllayout/testcases/PushReorderCase.java
index b386946..bb8d5e9 100644
--- a/tests/src/com/android/launcher3/celllayout/testcases/PushReorderCase.java
+++ b/tests/src/com/android/launcher3/celllayout/testcases/PushReorderCase.java
@@ -17,60 +17,68 @@
 
 import android.graphics.Point;
 
-import com.android.launcher3.celllayout.CellLayoutBoard;
-
 import java.util.Map;
 
 public class PushReorderCase {
+
+    /** 5x5 Test
+     **/
     private static final String START_BOARD_STR_5x5 = ""
             + "xxxxx\n"
             + "222m-\n"
             + "--111\n"
             + "--333\n"
             + "-----";
-    private static final CellLayoutBoard START_BOARD_5x5 = CellLayoutBoard.boardFromString(
-            START_BOARD_STR_5x5);
-
     private static final Point MOVE_TO_5x5 = new Point(2, 1);
-
     private static final String END_BOARD_STR_5x5 = ""
             + "xxxxx\n"
             + "--m--\n"
             + "222--\n"
             + "--111\n"
             + "--333";
-    private static final CellLayoutBoard END_BOARD_5x5 = CellLayoutBoard.boardFromString(
+    private static final ReorderTestCase TEST_CASE_5x5 = new ReorderTestCase(START_BOARD_STR_5x5,
+            MOVE_TO_5x5,
             END_BOARD_STR_5x5);
 
-    private static final ReorderTestCase TEST_CASE_5x5 = new ReorderTestCase(START_BOARD_5x5,
-            MOVE_TO_5x5,
-            END_BOARD_5x5);
 
-
+    /** 6x5 Test
+     **/
     private static final String START_BOARD_STR_6x5 = ""
             + "xxxxxx\n"
             + "2222m-\n"
             + "--111-\n"
             + "--333-\n"
             + "------";
-    private static final CellLayoutBoard START_BOARD_6x5 = CellLayoutBoard.boardFromString(
-            START_BOARD_STR_6x5);
-
     private static final Point MOVE_TO_6x5 = new Point(2, 1);
-
     private static final String END_BOARD_STR_6x5 = ""
             + "xxxxxx\n"
             + "--m---\n"
             + "2222--\n"
             + "--111-\n"
             + "--333-";
-    private static final CellLayoutBoard END_BOARD_6x5 = CellLayoutBoard.boardFromString(
+    private static final ReorderTestCase TEST_CASE_6x5 = new ReorderTestCase(START_BOARD_STR_6x5,
+            MOVE_TO_6x5,
             END_BOARD_STR_6x5);
 
-    private static final ReorderTestCase TEST_CASE_6x5 = new ReorderTestCase(START_BOARD_6x5,
-            MOVE_TO_6x5,
-            END_BOARD_6x5);
+    /** 4x4 Test
+     **/
+    private static final String START_BOARD_STR_4x4 = ""
+            + "xxxx\n"
+            + "222m\n"
+            + "-111\n"
+            + "----";
+    private static final Point MOVE_TO_4x4 = new Point(2, 1);
+    private static final String END_BOARD_STR_4x4 = ""
+            + "xxxx\n"
+            + "--m-\n"
+            + "222-\n"
+            + "-111";
+    private static final ReorderTestCase TEST_CASE_4x4 = new ReorderTestCase(START_BOARD_STR_4x4,
+            MOVE_TO_4x4,
+            END_BOARD_STR_4x4);
 
     public static final Map<Point, ReorderTestCase> TEST_BY_GRID_SIZE =
-            Map.of(new Point(5, 5), TEST_CASE_5x5, new Point(6, 5), TEST_CASE_6x5);
+            Map.of(new Point(5, 5), TEST_CASE_5x5,
+                    new Point(6, 5), TEST_CASE_6x5,
+                    new Point(4, 4), TEST_CASE_4x4);
 }
diff --git a/tests/src/com/android/launcher3/celllayout/testcases/SimpleReorderCase.java b/tests/src/com/android/launcher3/celllayout/testcases/SimpleReorderCase.java
index 57e1398..30269a0 100644
--- a/tests/src/com/android/launcher3/celllayout/testcases/SimpleReorderCase.java
+++ b/tests/src/com/android/launcher3/celllayout/testcases/SimpleReorderCase.java
@@ -17,35 +17,47 @@
 
 import android.graphics.Point;
 
-import com.android.launcher3.celllayout.CellLayoutBoard;
-
 import java.util.Map;
 
 public class SimpleReorderCase {
-    private static final String START_BOARD_STR = ""
+
+    /** 5x5 Test
+     **/
+    private static final String START_BOARD_STR_5x5 = ""
             + "xxxxx\n"
             + "--mm-\n"
             + "--mm-\n"
             + "-----\n"
             + "-----";
-    private static final CellLayoutBoard START_BOARD_5x5 = CellLayoutBoard.boardFromString(
-            START_BOARD_STR);
-
     private static final Point MOVE_TO_5x5 = new Point(4, 4);
-
     private static final String END_BOARD_STR_5x5 = ""
             + "xxxxx\n"
             + "-----\n"
             + "-----\n"
             + "---mm\n"
             + "---mm";
-    private static final CellLayoutBoard END_BOARD_5x5 = CellLayoutBoard.boardFromString(
+    private static final ReorderTestCase TEST_CASE_5x5 = new ReorderTestCase(START_BOARD_STR_5x5,
+            MOVE_TO_5x5,
             END_BOARD_STR_5x5);
 
-    private static final ReorderTestCase TEST_CASE_5x5 = new ReorderTestCase(START_BOARD_5x5,
-            MOVE_TO_5x5,
-            END_BOARD_5x5);
+    /** 4x4 Test
+     **/
+    private static final String START_BOARD_STR_4x4 = ""
+            + "xxxx\n"
+            + "--mm\n"
+            + "--mm\n"
+            + "----";
+    private static final Point MOVE_TO_4x4 = new Point(3, 3);
+    private static final String END_BOARD_STR_4x4 = ""
+            + "xxxx\n"
+            + "----\n"
+            + "--mm\n"
+            + "--mm";
+    private static final ReorderTestCase TEST_CASE_4x4 = new ReorderTestCase(START_BOARD_STR_4x4,
+            MOVE_TO_4x4,
+            END_BOARD_STR_4x4);
 
     public static final Map<Point, ReorderTestCase> TEST_BY_GRID_SIZE =
-            Map.of(new Point(5, 5), TEST_CASE_5x5);
+            Map.of(new Point(5, 5), TEST_CASE_5x5,
+                    new Point(4, 4), TEST_CASE_4x4);
 }
diff --git a/tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java b/tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java
index dba0a40..960d27d 100644
--- a/tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java
+++ b/tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java
@@ -1,5 +1,7 @@
 package com.android.launcher3.model;
 
+import static com.android.launcher3.testing.shared.TestProtocol.INCORRECT_INFO_UPDATED;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotSame;
@@ -14,6 +16,7 @@
 import android.os.Process;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.util.Log;
 
 import androidx.annotation.NonNull;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -26,6 +29,7 @@
 import com.android.launcher3.model.data.AppInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.util.LauncherModelHelper;
 
 import org.junit.After;
@@ -43,12 +47,15 @@
 @RunWith(AndroidJUnit4.class)
 public class CacheDataUpdatedTaskTest {
 
+    private static final String TAG = "CacheDataUpdatedTaskTest";
+
     private static final String NEW_LABEL_PREFIX = "new-label-";
 
     private LauncherModelHelper mModelHelper;
 
     @Before
     public void setup() throws Exception {
+        TestProtocol.sDebugTracing = true;
         mModelHelper = new LauncherModelHelper();
         mModelHelper.initializeData("cache_data_updated_task_data");
 
@@ -88,6 +95,7 @@
     @After
     public void tearDown() {
         mModelHelper.destroy();
+        TestProtocol.sDebugTracing = false;
     }
 
     private CacheDataUpdatedTask newTask(int op, String... pkg) {
@@ -111,6 +119,7 @@
         // Verify that only app1 var updated in allAppsList
         assertFalse(mModelHelper.getAllAppsList().data.isEmpty());
         for (AppInfo info : mModelHelper.getAllAppsList().data) {
+            Log.i(INCORRECT_INFO_UPDATED, "testCacheUpdate_update_apps: checking info=" + info);
             if (info.componentName.getPackageName().equals("app1")) {
                 assertFalse(info.bitmap.isNullOrLowRes());
             } else {
diff --git a/tests/src/com/android/launcher3/nonquickstep/HotseatWidthCalculationTest.kt b/tests/src/com/android/launcher3/nonquickstep/HotseatWidthCalculationTest.kt
new file mode 100644
index 0000000..55520e8
--- /dev/null
+++ b/tests/src/com/android/launcher3/nonquickstep/HotseatWidthCalculationTest.kt
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.nonquickstep
+
+import android.graphics.Rect
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.launcher3.DeviceProfileBaseTest
+import com.android.launcher3.util.WindowBounds
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class HotseatWidthCalculationTest : DeviceProfileBaseTest() {
+
+    /**
+     * This is a case when after setting the hotseat, the space needs to be recalculated
+     * but it doesn't need to change QSB width or remove icons
+     */
+    @Test
+    fun distribute_border_space_when_space_is_enough_portrait() {
+        initializeVarsForTablet(isGestureMode = false)
+        windowBounds = WindowBounds(Rect(0, 0, 1800, 2560), Rect(0, 104, 0, 0))
+        val dp = newDP()
+        dp.isTaskbarPresentInApps = true
+
+        assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
+        assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+        assertThat(dp.hotseatBorderSpace).isEqualTo(145)
+
+        assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(177)
+        assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(177)
+
+        assertThat(dp.isQsbInline).isFalse()
+        assertThat(dp.hotseatQsbWidth).isEqualTo(1445)
+    }
+
+    /**
+     * This is a case when after setting the hotseat, and recalculating spaces
+     * it still needs to remove icons for everything to fit
+     */
+    @Test
+    fun decrease_num_of_icons_when_not_enough_space_portrait() {
+        initializeVarsForTablet(isGestureMode = false)
+        windowBounds = WindowBounds(Rect(0, 0, 1300, 2560), Rect(0, 104, 0, 0))
+        val dp = newDP()
+        dp.isTaskbarPresentInApps = true
+
+        assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
+        assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+        assertThat(dp.hotseatBorderSpace).isEqualTo(94)
+
+        assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(121)
+        assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(121)
+
+        assertThat(dp.isQsbInline).isFalse()
+        assertThat(dp.hotseatQsbWidth).isEqualTo(1058)
+    }
+
+    /**
+     * This is a case when after setting the hotseat, the space needs to be recalculated
+     * but it doesn't need to change QSB width or remove icons
+     */
+    @Test
+    fun distribute_border_space_when_space_is_enough_landscape() {
+        initializeVarsForTwoPanel(isGestureMode = false, isLandscape = true)
+        val dp = newDP()
+        dp.isTaskbarPresentInApps = true
+
+        assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
+        assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+        assertThat(dp.hotseatBorderSpace).isEqualTo(105)
+
+        assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(370)
+        assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(370)
+
+        assertThat(dp.isQsbInline).isFalse()
+        assertThat(dp.hotseatQsbWidth).isEqualTo(1467)
+    }
+
+    /**
+     * This is a case when the hotseat spans a certain amount of columns
+     * and the nav buttons push the hotseat to the side, but not enough to change the border space.
+     */
+    @Test
+    fun nav_buttons_dont_interfere_with_required_hotseat_width() {
+        initializeVarsForTablet(isGestureMode = false, isLandscape = true)
+        inv?.apply {
+            hotseatColumnSpan = IntArray(4) { 4 }
+            inlineQsb = BooleanArray(4) { false }
+        }
+        val dp = newDP()
+        dp.isTaskbarPresentInApps = true
+
+        assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
+        assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+        assertThat(dp.hotseatBorderSpace).isEqualTo(100)
+
+        assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(668)
+        assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(668)
+
+        assertThat(dp.isQsbInline).isFalse()
+        assertThat(dp.hotseatQsbWidth).isEqualTo(1224)
+    }
+
+    /**
+     * This is a case when after setting the hotseat, the QSB width needs to be changed to fit
+     */
+    @Test
+    fun decrease_qsb_when_not_enough_space_landscape() {
+        initializeVarsForTablet(isGestureMode = false, isLandscape = true)
+        windowBounds = WindowBounds(Rect(0, 0, 2460, 1600), Rect(0, 104, 0, 0))
+        val dp = newDP()
+        dp.isTaskbarPresentInApps = true
+
+        assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
+        assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+        assertThat(dp.hotseatBorderSpace).isEqualTo(96)
+
+        assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(643)
+        assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(643)
+
+        assertThat(dp.isQsbInline).isFalse()
+        assertThat(dp.hotseatQsbWidth).isEqualTo(1174)
+    }
+
+    /**
+     * This is a case when after setting the hotseat, changing QSB width, and recalculating spaces
+     * it still needs to remove icons for everything to fit
+     */
+    @Test
+    fun decrease_num_of_icons_when_not_enough_space_landscape() {
+        initializeVarsForTablet(isGestureMode = false, isLandscape = true)
+        windowBounds = WindowBounds(Rect(0, 0, 2260, 1600), Rect(0, 104, 0, 0))
+        val dp = newDP()
+        dp.isTaskbarPresentInApps = true
+
+        assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
+        assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+        assertThat(dp.hotseatBorderSpace).isEqualTo(89)
+
+        assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(589)
+        assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(589)
+
+        assertThat(dp.isQsbInline).isFalse()
+        assertThat(dp.hotseatQsbWidth).isEqualTo(1081)
+    }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
index 6a11336..f47f710 100644
--- a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
+++ b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
@@ -247,8 +247,16 @@
         return mLauncher.hasLauncherObject(mLauncher.getOverviewObjectSelector("clear_all"));
     }
 
+    protected boolean isActionsViewVisible() {
+        OverviewTask task = mLauncher.isTablet() ? getFocusedTaskForTablet() : getCurrentTask();
+        if (task == null) {
+            return false;
+        }
+        return !task.isTaskSplit();
+    }
+
     private void verifyActionsViewVisibility() {
-        if (!hasTasks()) {
+        if (!hasTasks() || !isActionsViewVisible()) {
             return;
         }
         try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
@@ -265,13 +273,11 @@
      * Returns if focused task is currently snapped task in tablet grid overview.
      */
     private boolean isOverviewSnappedToFocusedTaskForTablet() {
-        UiObject2 focusedTask = getFocusedTaskForTablet();
+        OverviewTask focusedTask = getFocusedTaskForTablet();
         if (focusedTask == null) {
             return false;
         }
-        return Math.abs(
-                focusedTask.getVisibleBounds().exactCenterX() - mLauncher.getExactScreenCenterX())
-                < 1;
+        return Math.abs(focusedTask.getExactCenterX() - mLauncher.getExactScreenCenterX()) < 1;
     }
 
     /**
@@ -279,7 +285,7 @@
      *
      * @throws IllegalStateException if not run on a tablet device.
      */
-    UiObject2 getFocusedTaskForTablet() {
+    OverviewTask getFocusedTaskForTablet() {
         if (!mLauncher.isTablet()) {
             throw new IllegalStateException("Must be run on tablet device.");
         }
@@ -290,9 +296,9 @@
         int focusedTaskHeight = mLauncher.getFocusedTaskHeightForTablet();
         for (UiObject2 task : taskViews) {
             if (task.getVisibleBounds().height() == focusedTaskHeight) {
-                return task;
+                return new OverviewTask(mLauncher, task, this);
             }
         }
         return null;
     }
-}
\ No newline at end of file
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index caaeef8..fa7e8e9 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -169,6 +169,7 @@
     private static final String WIDGETS_RES_ID = "primary_widgets_list_view";
     private static final String CONTEXT_MENU_RES_ID = "popup_container";
     private static final String TASKBAR_RES_ID = "taskbar_view";
+    private static final String SPLIT_PLACEHOLDER_RES_ID = "split_placeholder";
     public static final int WAIT_TIME_MS = 30000;
     private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
     private static final String ANDROID_PACKAGE = "android";
@@ -724,6 +725,7 @@
                     waitUntilLauncherObjectGone(OVERVIEW_RES_ID);
                     waitUntilLauncherObjectGone(WIDGETS_RES_ID);
                     waitUntilLauncherObjectGone(TASKBAR_RES_ID);
+                    waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID);
 
                     return waitForLauncherObject(WORKSPACE_RES_ID);
                 }
@@ -732,6 +734,7 @@
                     waitUntilLauncherObjectGone(APPS_RES_ID);
                     waitUntilLauncherObjectGone(OVERVIEW_RES_ID);
                     waitUntilLauncherObjectGone(TASKBAR_RES_ID);
+                    waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID);
 
                     return waitForLauncherObject(WIDGETS_RES_ID);
                 }
@@ -741,16 +744,26 @@
                     waitUntilLauncherObjectGone(OVERVIEW_RES_ID);
                     waitUntilLauncherObjectGone(WIDGETS_RES_ID);
                     waitUntilLauncherObjectGone(TASKBAR_RES_ID);
+                    waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID);
 
                     return waitForLauncherObject(APPS_RES_ID);
                 }
-                case OVERVIEW:
+                case OVERVIEW: {
+                    waitUntilLauncherObjectGone(APPS_RES_ID);
+                    waitUntilLauncherObjectGone(WORKSPACE_RES_ID);
+                    waitUntilLauncherObjectGone(WIDGETS_RES_ID);
+                    waitUntilLauncherObjectGone(TASKBAR_RES_ID);
+                    waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID);
+
+                    return waitForLauncherObject(OVERVIEW_RES_ID);
+                }
                 case SPLIT_SCREEN_SELECT: {
                     waitUntilLauncherObjectGone(APPS_RES_ID);
                     waitUntilLauncherObjectGone(WORKSPACE_RES_ID);
                     waitUntilLauncherObjectGone(WIDGETS_RES_ID);
                     waitUntilLauncherObjectGone(TASKBAR_RES_ID);
 
+                    waitForLauncherObject(SPLIT_PLACEHOLDER_RES_ID);
                     return waitForLauncherObject(OVERVIEW_RES_ID);
                 }
                 case FALLBACK_OVERVIEW: {
@@ -758,6 +771,7 @@
                     waitUntilLauncherObjectGone(WORKSPACE_RES_ID);
                     waitUntilLauncherObjectGone(WIDGETS_RES_ID);
                     waitUntilLauncherObjectGone(TASKBAR_RES_ID);
+                    waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID);
 
                     return waitForFallbackLauncherObject(OVERVIEW_RES_ID);
                 }
@@ -766,6 +780,7 @@
                     waitUntilLauncherObjectGone(APPS_RES_ID);
                     waitUntilLauncherObjectGone(OVERVIEW_RES_ID);
                     waitUntilLauncherObjectGone(WIDGETS_RES_ID);
+                    waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID);
 
                     if (isTablet() && !isFallbackOverview()) {
                         waitForLauncherObject(TASKBAR_RES_ID);
@@ -1109,6 +1124,16 @@
     }
 
     @Nullable
+    UiObject2 findObjectInContainer(UiObject2 container, String resName) {
+        try {
+            return container.findObject(getLauncherObjectSelector(resName));
+        } catch (StaleObjectException e) {
+            fail("The container disappeared from screen");
+            return null;
+        }
+    }
+
+    @Nullable
     UiObject2 findObjectInContainer(UiObject2 container, BySelector selector) {
         try {
             return container.findObject(selector);
diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
index 72a39df..adc993d 100644
--- a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
+++ b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
@@ -20,6 +20,7 @@
 
 import android.graphics.Rect;
 
+import androidx.annotation.NonNull;
 import androidx.test.uiautomator.By;
 import androidx.test.uiautomator.BySelector;
 import androidx.test.uiautomator.UiObject2;
@@ -67,6 +68,10 @@
         return mTask.getVisibleCenter().x;
     }
 
+    float getExactCenterX() {
+        return mTask.getVisibleBounds().exactCenterX();
+    }
+
     /**
      * Dismisses the task by swiping up.
      */
@@ -159,4 +164,24 @@
             }
         }
     }
+
+    /** Taps the task menu. */
+    @NonNull
+    public OverviewTaskMenu tapMenu() {
+        try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+             LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+                     "want to tap the task menu")) {
+            mLauncher.clickLauncherObject(
+                    mLauncher.waitForObjectInContainer(mTask.getParent(), "icon"));
+
+            try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
+                    "tapped the task menu")) {
+                return new OverviewTaskMenu(mLauncher);
+            }
+        }
+    }
+
+    boolean isTaskSplit() {
+        return mLauncher.findObjectInContainer(mTask.getParent(), "bottomright_snapshot") != null;
+    }
 }
diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenu.java b/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenu.java
new file mode 100644
index 0000000..8cdc8a0
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenu.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.tapl;
+
+import androidx.annotation.NonNull;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiObject2;
+
+/** Represents the menu of an overview task. */
+public class OverviewTaskMenu {
+
+    private final LauncherInstrumentation mLauncher;
+    private final UiObject2 mMenu;
+
+    OverviewTaskMenu(LauncherInstrumentation launcher) {
+        mLauncher = launcher;
+
+        mMenu = mLauncher.waitForLauncherObject("menu_option_layout");
+        mLauncher.assertTrue("The overview task menus is not visible",
+                !mMenu.getVisibleBounds().isEmpty());
+    }
+
+    /** Taps the split menu item from the overview task menu. */
+    @NonNull
+    public SplitScreenSelect tapSplitMenuItem() {
+        try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+             LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+                     "tap split menu item")) {
+            mLauncher.clickLauncherObject(
+                    mLauncher.findObjectInContainer(mMenu, By.textStartsWith("Split")));
+
+            try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
+                    "tapped split menu item")) {
+                return new SplitScreenSelect(mLauncher);
+            }
+        }
+    }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/SplitScreenSelect.java b/tests/tapl/com/android/launcher3/tapl/SplitScreenSelect.java
index 3cf3ed6..9fa74e4 100644
--- a/tests/tapl/com/android/launcher3/tapl/SplitScreenSelect.java
+++ b/tests/tapl/com/android/launcher3/tapl/SplitScreenSelect.java
@@ -32,4 +32,10 @@
     protected ContainerType getContainerType() {
         return ContainerType.SPLIT_SCREEN_SELECT;
     }
+
+    @Override
+    protected boolean isActionsViewVisible() {
+        // We don't show overview actions in split select state.
+        return false;
+    }
 }