Merge "Do not add HOTSEAT_ICONS to visible elements for device type "phone" in ALL_APPS State" into tm-dev
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index f80deeb..81b0dd2 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -109,6 +109,8 @@
     <string name="back_gesture_intro_title">Swipe to go back</string>
     <!-- Introduction subtitle for the Back gesture tutorial. [CHAR LIMIT=200] -->
     <string name="back_gesture_intro_subtitle">To go back to the last screen, swipe from the left or right edge to the middle of the screen.</string>
+    <!-- Introduction subtitle for the Back gesture tutorial that will be spoken by screen readers. [CHAR LIMIT=200] -->
+    <string name="back_gesture_spoken_intro_subtitle">To go back to the last screen, swipe with 2 fingers from the left or right edge to the middle of the screen.</string>
 
     <string name="home_gesture_feedback_swipe_too_far_from_edge">Make sure you swipe up from the bottom edge of the screen.</string>
     <!-- Feedback shown during interactive parts of Home gesture tutorial when the Overview gesture is detected. [CHAR LIMIT=100] -->
@@ -123,6 +125,8 @@
     <string name="home_gesture_intro_title">Swipe to go home</string>
     <!-- Introduction subtitle for the Home gesture tutorial. [CHAR LIMIT=100] -->
     <string name="home_gesture_intro_subtitle">Swipe up from the bottom of your screen. This gesture always takes you to the Home screen.</string>
+    <!-- Introduction subtitle for the Home gesture tutorial that will be spoken by screen readers. [CHAR LIMIT=100] -->
+    <string name="home_gesture_spoken_intro_subtitle">Swipe up with 2 fingers from the bottom of the screen. This gesture always takes you to the Home screen.</string>
 
     <!-- Feedback shown during interactive parts of Overview gesture tutorial when the gesture is started too far from the edge. [CHAR LIMIT=100] -->
     <string name="overview_gesture_feedback_swipe_too_far_from_edge">Make sure you swipe up from the bottom edge of the screen.</string>
@@ -138,6 +142,8 @@
     <string name="overview_gesture_intro_title">Swipe to switch apps</string>
     <!-- Introduction subtitle for the Overview gesture tutorial. [CHAR LIMIT=100] -->
     <string name="overview_gesture_intro_subtitle">To switch between apps, swipe up from the bottom of your screen, hold, then release.</string>
+    <!-- Introduction subtitle for the Overview gesture tutorial that will be spoken by screen readers. [CHAR LIMIT=100] -->
+    <string name="overview_gesture_spoken_intro_subtitle">To switch between apps, swipe up with 2 fingers from the bottom of your screen, hold, then release.</string>
 
     <!-- Title shown during interactive part of Assistant gesture tutorial. [CHAR LIMIT=30] -->
     <string name="assistant_gesture_tutorial_playground_title" translatable="false">Tutorial: Assistant</string>
diff --git a/quickstep/src/com/android/launcher3/search/SearchSessionManager.java b/quickstep/src/com/android/launcher3/search/SearchSessionManager.java
deleted file mode 100644
index da85793..0000000
--- a/quickstep/src/com/android/launcher3/search/SearchSessionManager.java
+++ /dev/null
@@ -1,84 +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.search;
-
-import android.app.search.SearchSession;
-import android.content.Context;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.UiThread;
-
-import com.android.launcher3.R;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.util.ResourceBasedOverride;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.List;
-
-/** Manages an all apps search session. */
-public class SearchSessionManager implements ResourceBasedOverride {
-
-    /** Entry state for the search session (e.g. from all apps). */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = {ZERO_ALLAPPS, ZERO_QSB})
-    public @interface ZeroEntryState {}
-    public static final int ZERO_ALLAPPS = 1;
-    public static final int ZERO_QSB = 2;
-
-    /** Creates a {@link SearchSessionManager} instance. */
-    public static SearchSessionManager newInstance(Context context) {
-        return Overrides.getObject(
-                SearchSessionManager.class, context, R.string.search_session_manager_class);
-    }
-
-    /** The current {@link SearchSession}. */
-    @UiThread
-    public void setSearchSession(SearchSession session) {}
-
-    /** {@code true} if IME is shown. */
-    public void setIsImeShown(boolean value) {}
-
-    /** Returns {@code true} if IME is enabled. */
-    public boolean getIsImeEnabled() {
-        return false;
-    }
-
-    /** The current entry state for search. */
-    public @ZeroEntryState int getEntryState() {
-        return ZERO_ALLAPPS;
-    }
-
-    /**
-     * When user enters all apps surface via tap on home widget, set the state to
-     * {@code #ZERO_QSB}. When user exits, reset to {@code #ZERO_ALLAPPS}
-     */
-    public void setEntryState(@ZeroEntryState int state) {}
-
-    /** This will be called before opening all apps, to prepare zero state suggestions. */
-    public void prepareZeroState() {}
-
-    /** Apply predicted items for the search zero state. */
-    public void setZeroStatePredictedItems(List<ItemInfo> items) {}
-
-    /** Returns {@code true} if the session is valid and should be enabled. */
-    public boolean isValidSession() {
-        return false;
-    }
-
-    /** Called when the search session is destroyed. */
-    public void onDestroy() {}
-}
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index b90e820..5acce89 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -163,7 +163,11 @@
                     if (mActivity != activity) {
                         return;
                     }
+                    if (mTaskAnimationManager != null) {
+                        mTaskAnimationManager.finishRunningRecentsAnimation(true);
+                    }
                     mRecentsView = null;
+                    mActivity.unregisterActivityLifecycleCallbacks(mLifecycleCallbacks);
                     mActivity = null;
                 }
             };
@@ -1571,9 +1575,6 @@
 
     private void reset() {
         mStateCallback.setStateOnUiThread(STATE_HANDLER_INVALIDATED);
-        if (mActivity != null) {
-            mActivity.unregisterActivityLifecycleCallbacks(mLifecycleCallbacks);
-        }
     }
 
     /**
diff --git a/quickstep/src/com/android/quickstep/TaskIconCache.java b/quickstep/src/com/android/quickstep/TaskIconCache.java
index 300f085..3803f03 100644
--- a/quickstep/src/com/android/quickstep/TaskIconCache.java
+++ b/quickstep/src/com/android/quickstep/TaskIconCache.java
@@ -256,7 +256,7 @@
     private BaseIconFactory getIconFactory() {
         if (mIconFactory == null) {
             mIconFactory = new BaseIconFactory(mContext,
-                    DisplayController.INSTANCE.get(mContext).getInfo().densityDpi,
+                    DisplayController.INSTANCE.get(mContext).getInfo().getDensityDpi(),
                     mContext.getResources().getDimensionPixelSize(R.dimen.taskbar_icon_size));
         }
         return mIconFactory;
diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
index d94e5f1..f53491b 100644
--- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
@@ -320,6 +320,10 @@
                     Toast.LENGTH_LONG).show();
         }
 
+        /** Called when the snapshot has updated its full screen drawing parameters. */
+        public void setFullscreenParams(TaskView.FullscreenDrawParams fullscreenParams) {
+        }
+
         private class ScreenshotSystemShortcut extends SystemShortcut {
 
             private final BaseDraggingActivity mActivity;
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
index 9ba5577..35d9f22 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
@@ -33,17 +33,22 @@
     }
 
     @Override
-    public Integer getIntroductionTitle() {
+    public int getIntroductionTitle() {
         return R.string.back_gesture_intro_title;
     }
 
     @Override
-    public Integer getIntroductionSubtitle() {
+    public int getIntroductionSubtitle() {
         return R.string.back_gesture_intro_subtitle;
     }
 
     @Override
-    public Integer getSuccessFeedbackSubtitle() {
+    public int getSpokenIntroductionSubtitle() {
+        return R.string.back_gesture_spoken_intro_subtitle;
+    }
+
+    @Override
+    public int getSuccessFeedbackSubtitle() {
         return mTutorialFragment.isAtFinalStep()
                 ? R.string.back_gesture_feedback_complete_without_follow_up
                 : R.string.back_gesture_feedback_complete_with_overview_follow_up;
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
index 6254313..f519d50 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
@@ -32,17 +32,22 @@
     }
 
     @Override
-    public Integer getIntroductionTitle() {
+    public int getIntroductionTitle() {
         return R.string.home_gesture_intro_title;
     }
 
     @Override
-    public Integer getIntroductionSubtitle() {
+    public int getIntroductionSubtitle() {
         return R.string.home_gesture_intro_subtitle;
     }
 
     @Override
-    public Integer getSuccessFeedbackSubtitle() {
+    public int getSpokenIntroductionSubtitle() {
+        return R.string.home_gesture_spoken_intro_subtitle;
+    }
+
+    @Override
+    public int getSuccessFeedbackSubtitle() {
         return mTutorialFragment.isAtFinalStep()
                 ? R.string.home_gesture_feedback_complete_without_follow_up
                 : R.string.home_gesture_feedback_complete_with_follow_up;
diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
index 09640c6..6b016ce 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
@@ -42,17 +42,22 @@
     }
 
     @Override
-    public Integer getIntroductionTitle() {
+    public int getIntroductionTitle() {
         return R.string.overview_gesture_intro_title;
     }
 
     @Override
-    public Integer getIntroductionSubtitle() {
+    public int getIntroductionSubtitle() {
         return R.string.overview_gesture_intro_subtitle;
     }
 
     @Override
-    public Integer getSuccessFeedbackSubtitle() {
+    public int getSpokenIntroductionSubtitle() {
+        return R.string.overview_gesture_spoken_intro_subtitle;
+    }
+
+    @Override
+    public int getSuccessFeedbackSubtitle() {
         return mTutorialFragment.getNumSteps() > 1 && mTutorialFragment.isAtFinalStep()
                 ? R.string.overview_gesture_feedback_complete_with_follow_up
                 : R.string.overview_gesture_feedback_complete_without_follow_up;
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
index 6a8894e..fa7d848 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
@@ -62,7 +62,7 @@
 abstract class TutorialController implements BackGestureAttemptCallback,
         NavBarGestureAttemptCallback {
 
-    private static final String TAG = "TutorialController";
+    private static final String LOG_TAG = "TutorialController";
 
     private static final float FINGER_DOT_VISIBLE_ALPHA = 0.7f;
     private static final float FINGER_DOT_SMALL_SCALE = 0.7f;
@@ -217,18 +217,23 @@
     }
 
     @StringRes
-    public Integer getIntroductionTitle() {
-        return null;
+    public int getIntroductionTitle() {
+        return NO_ID;
     }
 
     @StringRes
-    public Integer getIntroductionSubtitle() {
-        return null;
+    public int getIntroductionSubtitle() {
+        return NO_ID;
     }
 
     @StringRes
-    public Integer getSuccessFeedbackSubtitle() {
-        return null;
+    public int getSpokenIntroductionSubtitle() {
+        return NO_ID;
+    }
+
+    @StringRes
+    public int getSuccessFeedbackSubtitle() {
+        return NO_ID;
     }
 
     void showFeedback() {
@@ -247,7 +252,16 @@
      * Show feedback reflecting a successful gesture attempt.
      **/
     void showSuccessFeedback() {
-        showFeedback(getSuccessFeedbackSubtitle(), true);
+        int successSubtitleResId = getSuccessFeedbackSubtitle();
+        if (successSubtitleResId == NO_ID) {
+            // Allow crash since this should never be reached with a tutorial controller used in
+            // production.
+            Log.e(LOG_TAG,
+                    "Cannot show success feedback for tutorial step: " + mTutorialType
+                            + ", no success feedback subtitle",
+                    new IllegalStateException());
+        }
+        showFeedback(successSubtitleResId, true);
     }
 
     /**
@@ -269,6 +283,7 @@
                 isGestureSuccessful
                         ? R.string.gesture_tutorial_nice : R.string.gesture_tutorial_try_again,
                 subtitleResId,
+                NO_ID,
                 isGestureSuccessful,
                 false);
     }
@@ -276,6 +291,7 @@
     void showFeedback(
             int titleResId,
             int subtitleResId,
+            int spokenSubtitleResId,
             boolean isGestureSuccessful,
             boolean useGestureAnimationDelay) {
         mFeedbackTitleView.removeCallbacks(mTitleViewCallback);
@@ -287,7 +303,10 @@
         mFeedbackTitleView.setText(titleResId);
         TextView subtitle =
                 mFeedbackView.findViewById(R.id.gesture_tutorial_fragment_feedback_subtitle);
-        subtitle.setText(subtitleResId);
+        subtitle.setText(spokenSubtitleResId == NO_ID
+                ? mContext.getText(subtitleResId)
+                : Utilities.wrapForTts(
+                        mContext.getText(subtitleResId), mContext.getString(spokenSubtitleResId)));
         if (isGestureSuccessful) {
             if (mTutorialFragment.isAtFinalStep()) {
                 showActionButton();
@@ -580,7 +599,7 @@
                         packageManager.getApplicationInfo(
                                 PIXEL_TIPS_APP_PACKAGE_NAME, PackageManager.GET_META_DATA));
             } catch (PackageManager.NameNotFoundException e) {
-                Log.e(TAG,
+                Log.e(LOG_TAG,
                         "Could not find app label for package name: "
                                 + PIXEL_TIPS_APP_PACKAGE_NAME
                                 + ". Defaulting to 'Pixel Tips.'",
@@ -593,7 +612,7 @@
                 subtitleTextView.setText(
                         mContext.getString(R.string.skip_tutorial_dialog_subtitle, tipsAppName));
             } else {
-                Log.w(TAG, "No subtitle view in the skip tutorial dialog to update.");
+                Log.w(LOG_TAG, "No subtitle view in the skip tutorial dialog to update.");
             }
 
             Button cancelButton = (Button) contentView.findViewById(
@@ -602,7 +621,7 @@
                 cancelButton.setOnClickListener(
                         v -> tutorialDialog.dismiss());
             } else {
-                Log.w(TAG, "No cancel button in the skip tutorial dialog to update.");
+                Log.w(LOG_TAG, "No cancel button in the skip tutorial dialog to update.");
             }
 
             Button confirmButton = contentView.findViewById(
@@ -613,7 +632,7 @@
                     tutorialDialog.dismiss();
                 });
             } else {
-                Log.w(TAG, "No confirm button in the skip tutorial dialog to update.");
+                Log.w(LOG_TAG, "No confirm button in the skip tutorial dialog to update.");
             }
 
             tutorialDialog.getWindow().setBackgroundDrawable(
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
index 33e800d..1599c8c 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
@@ -15,6 +15,8 @@
  */
 package com.android.quickstep.interaction;
 
+import static android.view.View.NO_ID;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.app.Activity;
@@ -211,13 +213,31 @@
         if (isGestureComplete()) {
             mTutorialController.showSuccessFeedback();
         } else if (!mIntroductionShown) {
-            Integer introTileStringResId = mTutorialController.getIntroductionTitle();
-            Integer introSubtitleResId = mTutorialController.getIntroductionSubtitle();
-            if (introTileStringResId != null && introSubtitleResId != null) {
-                mTutorialController.showFeedback(
-                        introTileStringResId, introSubtitleResId, false, true);
-                mIntroductionShown = true;
+            int introTitleResId = mTutorialController.getIntroductionTitle();
+            int introSubtitleResId = mTutorialController.getIntroductionSubtitle();
+            if (introTitleResId == NO_ID) {
+                // Allow crash since this should never be reached with a tutorial controller used in
+                // production.
+                Log.e(LOG_TAG,
+                        "Cannot show introduction feedback for tutorial step: " + mTutorialType
+                                + ", no introduction feedback title",
+                        new IllegalStateException());
             }
+            if (introTitleResId == NO_ID) {
+                // Allow crash since this should never be reached with a tutorial controller used in
+                // production.
+                Log.e(LOG_TAG,
+                        "Cannot show introduction feedback for tutorial step: " + mTutorialType
+                                + ", no introduction feedback subtitle",
+                        new IllegalStateException());
+            }
+            mTutorialController.showFeedback(
+                    introTitleResId,
+                    introSubtitleResId,
+                    mTutorialController.getSpokenIntroductionSubtitle(),
+                    false,
+                    true);
+            mIntroductionShown = true;
         }
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
index 49a540f..1c4e497 100644
--- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
@@ -56,7 +56,6 @@
             HIDDEN_NON_ZERO_ROTATION,
             HIDDEN_NO_TASKS,
             HIDDEN_NO_RECENTS,
-            HIDDEN_FOCUSED_SCROLL,
             HIDDEN_SPLIT_SCREEN})
     @Retention(RetentionPolicy.SOURCE)
     public @interface ActionsHiddenFlags { }
@@ -64,8 +63,7 @@
     public static final int HIDDEN_NON_ZERO_ROTATION = 1 << 0;
     public static final int HIDDEN_NO_TASKS = 1 << 1;
     public static final int HIDDEN_NO_RECENTS = 1 << 2;
-    public static final int HIDDEN_FOCUSED_SCROLL = 1 << 3;
-    public static final int HIDDEN_SPLIT_SCREEN = 1 << 4;
+    public static final int HIDDEN_SPLIT_SCREEN = 1 << 3;
 
     @IntDef(flag = true, value = {
             DISABLED_SCROLLING,
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 5d71ebd..71b2cea 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -378,6 +378,8 @@
     // OverScroll constants
     private static final int OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION = 270;
 
+    private static final int DEFAULT_ACTIONS_VIEW_ALPHA_ANIMATION_DURATION = 300;
+
     private static final int DISMISS_TASK_DURATION = 300;
     private static final int ADDITION_TASK_DURATION = 200;
     private static final float INITIAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET = 0.55f;
@@ -652,6 +654,8 @@
     private TaskView mMovingTaskView;
 
     private OverviewActionsView mActionsView;
+    private ObjectAnimator mActionsViewAlphaAnimator;
+    private float mActionsViewAlphaAnimatorFinalValue;
 
     private MultiWindowModeChangedListener mMultiWindowModeChangedListener =
             new MultiWindowModeChangedListener() {
@@ -1145,6 +1149,11 @@
         return getScrollForPage(taskIndex) == getPagedOrientationHandler().getPrimaryScroll(this);
     }
 
+    private boolean isFocusedTaskInExpectedScrollPosition() {
+        TaskView focusedTask = getFocusedTaskView();
+        return focusedTask != null && isTaskInExpectedScrollPosition(indexOfChild(focusedTask));
+    }
+
     /**
      * Returns a {@link TaskView} that has taskId matching {@code taskId} or null if no match.
      */
@@ -1191,13 +1200,15 @@
     @Override
     protected void onPageBeginTransition() {
         super.onPageBeginTransition();
-        mActionsView.updateDisabledFlags(OverviewActionsView.DISABLED_SCROLLING, true);
+        if (!mActivity.getDeviceProfile().isTablet) {
+            mActionsView.updateDisabledFlags(OverviewActionsView.DISABLED_SCROLLING, true);
+        }
     }
 
     @Override
     protected void onPageEndTransition() {
         super.onPageEndTransition();
-        if (isClearAllHidden()) {
+        if (isClearAllHidden() && !mActivity.getDeviceProfile().isTablet) {
             mActionsView.updateDisabledFlags(OverviewActionsView.DISABLED_SCROLLING, false);
         }
         if (getNextPage() > 0) {
@@ -1808,16 +1819,24 @@
     }
 
     private void updateActionsViewFocusedScroll() {
-        boolean hiddenFocusedScroll;
         if (showAsGrid()) {
-            TaskView focusedTaskView = getFocusedTaskView();
-            hiddenFocusedScroll = focusedTaskView == null
-                    || !isTaskInExpectedScrollPosition(indexOfChild(focusedTaskView));
-        } else {
-            hiddenFocusedScroll = false;
+            float actionsViewAlphaValue = isFocusedTaskInExpectedScrollPosition() ? 1 : 0;
+            // If animation is already in progress towards the same end value, do not restart.
+            if (mActionsViewAlphaAnimator == null || !mActionsViewAlphaAnimator.isStarted()
+                    || (mActionsViewAlphaAnimator.isStarted()
+                    && mActionsViewAlphaAnimatorFinalValue != actionsViewAlphaValue)) {
+                animateActionsViewAlpha(actionsViewAlphaValue,
+                        DEFAULT_ACTIONS_VIEW_ALPHA_ANIMATION_DURATION);
+            }
         }
-        mActionsView.updateHiddenFlags(OverviewActionsView.HIDDEN_FOCUSED_SCROLL,
-                hiddenFocusedScroll);
+    }
+
+    private void animateActionsViewAlpha(float alphaValue, long duration) {
+        mActionsViewAlphaAnimator = ObjectAnimator.ofFloat(
+                mActionsView.getVisibilityAlpha(), MultiValueAlpha.VALUE, alphaValue);
+        mActionsViewAlphaAnimatorFinalValue = alphaValue;
+        mActionsViewAlphaAnimator.setDuration(duration);
+        mActionsViewAlphaAnimator.start();
     }
 
     /**
@@ -2346,10 +2365,9 @@
     }
 
     private void animateActionsViewIn() {
-        ObjectAnimator anim = ObjectAnimator.ofFloat(
-                mActionsView.getVisibilityAlpha(), MultiValueAlpha.VALUE, 0, 1);
-        anim.setDuration(TaskView.SCALE_ICON_DURATION);
-        anim.start();
+        if (!showAsGrid() || isFocusedTaskInExpectedScrollPosition()) {
+            animateActionsViewAlpha(1, TaskView.SCALE_ICON_DURATION);
+        }
     }
 
     public void animateUpTaskIconScale() {
@@ -3292,7 +3310,7 @@
                         // Update various scroll-dependent UI.
                         dispatchScrollChanged();
                         updateActionsViewFocusedScroll();
-                        if (isClearAllHidden()) {
+                        if (isClearAllHidden() && !mActivity.getDeviceProfile().isTablet) {
                             mActionsView.updateDisabledFlags(OverviewActionsView.DISABLED_SCROLLING,
                                     false);
                         }
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index bff8651..d8120ff 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -283,6 +283,7 @@
 
     public void setFullscreenParams(TaskView.FullscreenDrawParams fullscreenParams) {
         mFullscreenParams = fullscreenParams;
+        getTaskOverlay().setFullscreenParams(fullscreenParams);
         invalidate();
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 8869ff1..b5971f2 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -1022,7 +1022,7 @@
     }
 
     public float getTaskCornerRadius() {
-        return TaskCornerRadius.get(mActivity);
+        return mCurrentFullscreenParams.mCornerRadius;
     }
 
     @Override
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index dd3e08b..e85969b 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -306,6 +306,17 @@
         if not specified -->
         <attr name="allAppsBorderSpaceTwoPanelLandscapeVertical" format="float" />
 
+        <!-- alignment of hotseat to the grid.
+        Not applicable for 3 button mode when taskbar is enabled -->
+        <!-- defaults to numColumns, if not specified -->
+        <attr name="hotseatColumnSpan" format="integer" />
+        <!-- defaults to numColumns, if not specified -->
+        <attr name="hotseatColumnSpanLandscape" format="integer" />
+        <!-- defaults to numColumns, if not specified -->
+        <attr name="hotseatColumnSpanTwoPanelLandscape" format="integer" />
+        <!-- defaults to numColumns, if not specified -->
+        <attr name="hotseatColumnSpanTwoPanelPortrait" format="integer" />
+
         <!-- defaults to borderSpaceDps, if not specified -->
         <attr name="hotseatBorderSpace" format="float" />
         <!-- defaults to hotseatBorderSpace, if not specified -->
diff --git a/res/xml/device_profiles.xml b/res/xml/device_profiles.xml
index 07ce598..258da80 100644
--- a/res/xml/device_profiles.xml
+++ b/res/xml/device_profiles.xml
@@ -176,6 +176,7 @@
             launcher:allAppsBorderSpaceHorizontal="8"
             launcher:allAppsBorderSpaceVertical="16"
             launcher:allAppsBorderSpaceLandscape="16"
+            launcher:hotseatColumnSpanLandscape="4"
             launcher:hotseatBorderSpace="58"
             launcher:hotseatBorderSpaceLandscape="50.4"
             launcher:canBeDefault="true" />
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 31f1da8..88030ae 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -158,6 +158,7 @@
     public final int numShownHotseatIcons;
     public int hotseatCellHeightPx;
     private final int hotseatExtraVerticalSize;
+    private final boolean areNavButtonsInline;
     // In portrait: size = height, in landscape: size = width
     public int hotseatBarSizePx;
     public int hotseatBarTopPaddingPx;
@@ -358,7 +359,7 @@
 
         // 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.
-        boolean areNavButtonsInline = isTaskbarPresent && !isGestureMode;
+        areNavButtonsInline = isTaskbarPresent && !isGestureMode;
         if (areNavButtonsInline && canQsbInline) {
             numShownHotseatIcons = inv.numShrunkenHotseatIcons;
         } else {
@@ -373,15 +374,14 @@
                 res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_top_padding);
         if (isQsbInline) {
             hotseatBarBottomPaddingPx = res.getDimensionPixelSize(R.dimen.inline_qsb_bottom_margin);
-            qsbWidth = calculateQsbWidth();
         } else {
             hotseatBarBottomPaddingPx = (isTallDevice ? res.getDimensionPixelSize(
                     R.dimen.dynamic_grid_hotseat_bottom_tall_padding)
                     : res.getDimensionPixelSize(
                             R.dimen.dynamic_grid_hotseat_bottom_non_tall_padding))
                     + res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_bottom_padding);
-            qsbWidth = 0;
         }
+
         springLoadedHotseatBarTopMarginPx = res.getDimensionPixelSize(
                 R.dimen.spring_loaded_hotseat_top_margin);
         hotseatBarSidePaddingEndPx =
@@ -390,9 +390,7 @@
         hotseatBarSidePaddingStartPx = isVerticalBarLayout() ? workspacePageIndicatorHeight : 0;
         hotseatExtraVerticalSize =
                 res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_extra_vertical_size);
-        hotseatBorderSpace = pxFromDp(inv.hotseatBorderSpaces[mTypeIndex], mMetrics);
-        updateHotseatIconSize(
-                pxFromDp(inv.iconSize[INDEX_DEFAULT], mMetrics));
+        updateHotseatIconSize(pxFromDp(inv.iconSize[INDEX_DEFAULT], mMetrics));
 
         qsbBottomMarginOriginalPx = isScalableGrid
                 ? res.getDimensionPixelSize(R.dimen.scalable_grid_qsb_bottom_margin)
@@ -483,6 +481,10 @@
                 cellLayoutPadding);
         updateWorkspacePadding();
 
+        // Hotseat and QSB width depends on updated cellSize and workspace padding
+        hotseatBorderSpace = calculateHotseatBorderSpace();
+        qsbWidth = calculateQsbWidth();
+
         flingToDeleteThresholdVelocity = res.getDimensionPixelSize(
                 R.dimen.drag_flingToDeleteMinVelocity);
 
@@ -493,14 +495,26 @@
                 new DotRenderer(allAppsIconSizePx, dotPath, DEFAULT_DOT_SIZE);
     }
 
+    /**
+     * QSB width is always calculated because when in 3 button nav the width doesn't follow the
+     * width of the hotseat.
+     */
     private int calculateQsbWidth() {
-        int columns = isTwoPanels ? inv.numColumns * 2 : inv.numColumns;
+        if (isQsbInline) {
+            int columns = isTwoPanels ? inv.numColumns * 2 : inv.numColumns;
+            return getIconToIconWidthForColumns(columns)
+                    - iconSizePx * numShownHotseatIcons
+                    - hotseatBorderSpace * numShownHotseatIcons;
+        } else {
+            int columns = inv.hotseatColumnSpan[mTypeIndex];
+            return getIconToIconWidthForColumns(columns);
+        }
+    }
 
-        return cellWidthPx * columns
-                + cellLayoutBorderSpacePx.x * (columns - 1)
-                - (cellWidthPx - iconSizePx) // left and right cell space
-                - iconSizePx * numShownHotseatIcons
-                - hotseatBorderSpace * numShownHotseatIcons;
+    private int getIconToIconWidthForColumns(int columns) {
+        return columns * getCellSize().x
+                + (columns - 1) * cellLayoutBorderSpacePx.x
+                - (getCellSize().x - iconSizePx);  // left and right cell space
     }
 
     private int getHorizontalMarginPx(InvariantDeviceProfile idp, Resources res) {
@@ -741,13 +755,6 @@
         // All apps
         updateAllAppsIconSize(scale, res);
 
-        // Hotseat
-        hotseatBorderSpace = pxFromDp(inv.hotseatBorderSpaces[mTypeIndex], mMetrics, scale);
-        if (isQsbInline) {
-            qsbWidth = calculateQsbWidth();
-        } else {
-            qsbWidth = 0;
-        }
         updateHotseatIconSize(iconSizePx);
 
         // Folder icon
@@ -755,6 +762,23 @@
         folderIconOffsetYPx = (iconSizePx - folderIconSizePx) / 2;
     }
 
+    /**
+     * Hotseat width spans a certain number of columns on scalable grids.
+     * This method calculates the space between the icons to achieve that width.
+     */
+    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);
+        }
+    }
+
 
     /**
      * Updates the iconSize for allApps* variants.
@@ -1070,6 +1094,13 @@
                 mHotseatPadding.left -= diff;
                 mHotseatPadding.right += diff;
             }
+        } else if (isScalableGrid) {
+            int sideSpacing = (availableWidthPx - qsbWidth) / 2;
+            mHotseatPadding.set(sideSpacing,
+                    hotseatBarTopPaddingPx,
+                    sideSpacing,
+                    hotseatBarSizePx - hotseatCellHeightPx - hotseatBarTopPaddingPx
+                            + mInsets.bottom);
         } else {
             // We want the edges of the hotseat to line up with the edges of the workspace, but the
             // icons in the hotseat are a different size, and so don't line up perfectly. To account
@@ -1306,6 +1337,7 @@
         writer.println(prefix + pxToDpStr("allAppsLeftRightMargin", allAppsLeftRightMargin));
 
         writer.println(prefix + pxToDpStr("hotseatBarSizePx", hotseatBarSizePx));
+        writer.println(prefix + "\tinv.hotseatColumnSpan: " + inv.hotseatColumnSpan[mTypeIndex]);
         writer.println(prefix + pxToDpStr("hotseatCellHeightPx", hotseatCellHeightPx));
         writer.println(prefix + pxToDpStr("hotseatBarTopPaddingPx", hotseatBarTopPaddingPx));
         writer.println(prefix + pxToDpStr("hotseatBarBottomPaddingPx", hotseatBarBottomPaddingPx));
@@ -1384,7 +1416,7 @@
     private static Context getContext(Context c, Info info, int orientation, WindowBounds bounds) {
         Configuration config = new Configuration(c.getResources().getConfiguration());
         config.orientation = orientation;
-        config.densityDpi = info.densityDpi;
+        config.densityDpi = info.getDensityDpi();
         config.smallestScreenWidthDp = (int) info.smallestSizeDp(bounds);
         return c.createConfigurationContext(config);
     }
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index a9db5ce..76106fc 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -173,17 +173,9 @@
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 
-        int width;
-        if (mActivity.getDeviceProfile().isQsbInline) {
-            width = mActivity.getDeviceProfile().qsbWidth;
-        } else {
-            MarginLayoutParams qsbParams = (MarginLayoutParams) mQsb.getLayoutParams();
-            width = getShortcutsAndWidgets().getMeasuredWidth()
-                    - qsbParams.getMarginStart()
-                    - qsbParams.getMarginEnd();
-        }
+        int qsbWidth = mActivity.getDeviceProfile().qsbWidth;
 
-        mQsb.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+        mQsb.measure(MeasureSpec.makeMeasureSpec(qsbWidth, MeasureSpec.EXACTLY),
                 MeasureSpec.makeMeasureSpec(mQsbHeight, MeasureSpec.EXACTLY));
     }
 
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 36c1797..89b1771 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -125,6 +125,7 @@
     public PointF[] borderSpaces;
     public float folderBorderSpace;
     public float[] hotseatBorderSpaces;
+    public int[] hotseatColumnSpan;
 
     public float[] horizontalMargin;
 
@@ -356,6 +357,7 @@
         numDatabaseHotseatIcons = deviceType == TYPE_MULTI_DISPLAY
                 ? closestProfile.numDatabaseHotseatIcons : closestProfile.numHotseatIcons;
         hotseatBorderSpaces = displayOption.hotseatBorderSpaces;
+        hotseatColumnSpan = displayOption.hotseatColumnSpan;
 
         numAllAppsColumns = closestProfile.numAllAppsColumns;
         numDatabaseAllAppsColumns = deviceType == TYPE_MULTI_DISPLAY
@@ -396,7 +398,8 @@
             // We need to ensure that there is enough extra space in the wallpaper
             // for the intended parallax effects
             float parallaxFactor =
-                    dpiFromPx(Math.min(displayWidth, displayHeight), displayInfo.densityDpi) < 720
+                    dpiFromPx(Math.min(displayWidth, displayHeight), displayInfo.getDensityDpi())
+                            < 720
                             ? 2
                             : wallpaperTravelToScreenWidthRatio(displayWidth, displayHeight);
             defaultWallpaperSize.x =
@@ -585,8 +588,8 @@
             }
         }
 
-        float width = dpiFromPx(minWidthPx, displayInfo.densityDpi);
-        float height = dpiFromPx(minHeightPx, displayInfo.densityDpi);
+        float width = dpiFromPx(minWidthPx, displayInfo.getDensityDpi());
+        float height = dpiFromPx(minHeightPx, displayInfo.getDensityDpi());
 
         // Sort the profiles based on the closeness to the device size
         Collections.sort(points, (a, b) ->
@@ -806,7 +809,9 @@
         private float folderBorderSpace;
         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 int[] hotseatColumnSpan = new int[COUNT_SIZES];
 
         private final float[] iconSizes = new float[COUNT_SIZES];
         private final float[] textSizes = new float[COUNT_SIZES];
@@ -1032,6 +1037,17 @@
                     R.styleable.ProfileDisplayOption_hotseatBorderSpaceTwoPanelPortrait,
                     hotseatBorderSpaces[INDEX_DEFAULT]);
 
+            hotseatColumnSpan[INDEX_DEFAULT] = a.getInt(
+                    R.styleable.ProfileDisplayOption_hotseatColumnSpan, grid.numColumns);
+            hotseatColumnSpan[INDEX_LANDSCAPE] = a.getInt(
+                    R.styleable.ProfileDisplayOption_hotseatColumnSpanLandscape, grid.numColumns);
+            hotseatColumnSpan[INDEX_TWO_PANEL_LANDSCAPE] = a.getInt(
+                    R.styleable.ProfileDisplayOption_hotseatColumnSpanTwoPanelLandscape,
+                    grid.numColumns);
+            hotseatColumnSpan[INDEX_TWO_PANEL_PORTRAIT] = a.getInt(
+                    R.styleable.ProfileDisplayOption_hotseatColumnSpanTwoPanelPortrait,
+                    grid.numColumns);
+
             a.recycle();
         }
 
@@ -1090,6 +1106,7 @@
                 minCellSize[i].y += p.minCellSize[i].y;
                 horizontalMargin[i] += p.horizontalMargin[i];
                 hotseatBorderSpaces[i] += p.hotseatBorderSpaces[i];
+                hotseatColumnSpan[i] = p.hotseatColumnSpan[i];
                 allAppsCellSize[i].x += p.allAppsCellSize[i].x;
                 allAppsCellSize[i].y += p.allAppsCellSize[i].y;
                 allAppsIconSizes[i] += p.allAppsIconSizes[i];
diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
index 9f0c1cc..2a16210 100644
--- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
+++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
@@ -192,27 +192,6 @@
         return true;
     }
 
-    public boolean appendSearchResults(ArrayList<AdapterItem> results) {
-        if (hasFilter() && results != null && results.size() > 0) {
-            updateSearchAdapterItems(results, mSearchResults.size());
-            refreshRecyclerView();
-            return true;
-        }
-        return false;
-    }
-
-    void updateSearchAdapterItems(ArrayList<AdapterItem> list, int offset) {
-        for (int i = 0; i < list.size(); i++) {
-            AdapterItem adapterItem = list.get(i);
-            adapterItem.position = offset + i;
-            mAdapterItems.add(adapterItem);
-
-            if (adapterItem.isCountedForAccessibility()) {
-                mAccessibilityResultsCount++;
-            }
-        }
-    }
-
     /**
      * Updates internals when the set of apps are updated.
      */
@@ -282,7 +261,6 @@
         String lastSectionName = null;
         FastScrollSectionInfo lastFastScrollerSectionInfo = null;
         int position = 0;
-        int appIndex = 0;
 
         // Prepare to update the list of sections, filtered apps, etc.
         mAccessibilityResultsCount = 0;
@@ -319,7 +297,16 @@
                 mAdapterItems.add(appItem);
             }
         } else {
-            updateSearchAdapterItems(mSearchResults, 0);
+            int count = mSearchResults.size();
+            for (int i = 0; i < count; i++) {
+                AdapterItem adapterItem = mSearchResults.get(i);
+                adapterItem.position = i;
+                mAdapterItems.add(adapterItem);
+
+                if (adapterItem.isCountedForAccessibility()) {
+                    mAccessibilityResultsCount++;
+                }
+            }
             if (!FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
                 // Append the search market item
                 if (hasNoFilteredResults()) {
diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
index 893e547..bc2c318 100644
--- a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
+++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
@@ -177,14 +177,6 @@
     }
 
     @Override
-    public void onAppendSearchResult(String query, ArrayList<AdapterItem> items) {
-        if (items != null) {
-            mApps.appendSearchResults(items);
-            notifyResultChanged();
-        }
-    }
-
-    @Override
     public void clearSearchResult() {
         if (mApps.setSearchResults(null)) {
             notifyResultChanged();
diff --git a/src/com/android/launcher3/search/SearchCallback.java b/src/com/android/launcher3/search/SearchCallback.java
index 5796116..495a303 100644
--- a/src/com/android/launcher3/search/SearchCallback.java
+++ b/src/com/android/launcher3/search/SearchCallback.java
@@ -32,13 +32,6 @@
     void onSearchResult(String query, ArrayList<T> items);
 
     /**
-     * Called when the search from secondary source is complete.
-     *
-     * @param items list of search results
-     */
-    void onAppendSearchResult(String query, ArrayList<T> items);
-
-    /**
      * Called when the search results should be cleared.
      */
     void clearSearchResult();
diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java
index 777da23..7c73be5 100644
--- a/src/com/android/launcher3/util/DisplayController.java
+++ b/src/com/android/launcher3/util/DisplayController.java
@@ -290,7 +290,7 @@
 
         // Configuration property
         public final float fontScale;
-        public final int densityDpi;
+        private final int densityDpi;
         public final NavigationMode navigationMode;
 
         private final PortraitSize mScreenSizeDp;
@@ -357,6 +357,10 @@
         public float smallestSizeDp(WindowBounds bounds) {
             return dpiFromPx(Math.min(bounds.bounds.width(), bounds.bounds.height()), densityDpi);
         }
+
+        public int getDensityDpi() {
+            return densityDpi;
+        }
     }
 
     /**
diff --git a/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarController.java b/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarController.java
index 2751a52..a15508a 100644
--- a/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarController.java
+++ b/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarController.java
@@ -95,11 +95,6 @@
     }
 
     @Override
-    public void onAppendSearchResult(String query, ArrayList<WidgetsListBaseEntry> items) {
-        // Not needed.
-    }
-
-    @Override
     public void clearSearchResult() {
         // Any existing search session will be cancelled by setting text to empty.
         mInput.setText("");
diff --git a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
index f91f1c4..6d0fcb6 100644
--- a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
+++ b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
@@ -64,6 +64,7 @@
         windowBounds = WindowBounds(x, y, x, y - 100, 0)
 
         whenever(info.isTablet(any())).thenReturn(false)
+        whenever(info.getDensityDpi()).thenReturn(560)
 
         inv = newScalableInvariantDeviceProfile()
     }
@@ -77,6 +78,7 @@
         windowBounds = WindowBounds(x, y, x, y - 100, 0)
 
         whenever(info.isTablet(any())).thenReturn(true)
+        whenever(info.getDensityDpi()).thenReturn(320)
 
         inv = newScalableInvariantDeviceProfile()
     }
@@ -107,6 +109,7 @@
                 PointF(16f, 16f)
             ).toTypedArray()
             hotseatBorderSpaces = FloatArray(4) { 16f }
+            hotseatColumnSpan = IntArray(4) { 4 }
             iconSize = FloatArray(4) { 56f }
             allAppsIconSize = FloatArray(4) { 56f }
             iconTextSize = FloatArray(4) { 14f }
diff --git a/tests/src/com/android/launcher3/HotseatSizeTest.kt b/tests/src/com/android/launcher3/HotseatShownIconsTest.kt
similarity index 97%
rename from tests/src/com/android/launcher3/HotseatSizeTest.kt
rename to tests/src/com/android/launcher3/HotseatShownIconsTest.kt
index a44939f..593239d 100644
--- a/tests/src/com/android/launcher3/HotseatSizeTest.kt
+++ b/tests/src/com/android/launcher3/HotseatShownIconsTest.kt
@@ -23,15 +23,13 @@
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.ArgumentMatchers
-import org.mockito.Mockito.`when` as whenever
 
 /**
  * Test for [DeviceProfile]
  */
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-class HotseatSizeTest : DeviceProfileBaseTest() {
+class HotseatShownIconsTest : DeviceProfileBaseTest() {
 
     @Test
     fun hotseat_size_is_normal_for_handhelds() {
diff --git a/tests/src/com/android/launcher3/InlineQsbTest.kt b/tests/src/com/android/launcher3/InlineQsbTest.kt
index e00dca8..905c1e1 100644
--- a/tests/src/com/android/launcher3/InlineQsbTest.kt
+++ b/tests/src/com/android/launcher3/InlineQsbTest.kt
@@ -29,17 +29,16 @@
 class InlineQsbTest : DeviceProfileBaseTest() {
 
     @Test
-    fun qsbWidth_is_match_parent_for_phones() {
+    fun qsb_is_not_inline_for_phones() {
         initializeVarsForPhone()
 
         val dp = newDP()
 
         assertThat(dp.isQsbInline).isFalse()
-        assertThat(dp.qsbWidth).isEqualTo(0)
     }
 
     @Test
-    fun qsbWidth_is_match_parent_for_tablet_portrait() {
+    fun qsb_is_inline_for_tablet_portrait() {
         initializeVarsForTablet()
         inv = newScalableInvariantDeviceProfile().apply {
             inlineQsb = booleanArrayOf(
@@ -62,11 +61,10 @@
         )
 
         assertThat(dp.isQsbInline).isFalse()
-        assertThat(dp.qsbWidth).isEqualTo(0)
     }
 
     @Test
-    fun qsbWidth_has_size_for_tablet_landscape() {
+    fun qsb_is_inline_for_tablet_landscape() {
         initializeVarsForTablet(isLandscape = true)
         inv = newScalableInvariantDeviceProfile().apply {
             inlineQsb = booleanArrayOf(
@@ -75,16 +73,17 @@
                 false,
                 false
             )
+            numColumns = 6
+            numRows = 5
+            numShownHotseatIcons = 6
         }
 
         val dp = newDP()
 
         if (dp.hotseatQsbHeight > 0) {
             assertThat(dp.isQsbInline).isTrue()
-            assertThat(dp.qsbWidth).isGreaterThan(0)
         } else { // Launcher3 doesn't have QSB height
             assertThat(dp.isQsbInline).isFalse()
-            assertThat(dp.qsbWidth).isEqualTo(0)
         }
     }
 
@@ -92,14 +91,13 @@
      * This test is to make sure that a tablet doesn't inline the QSB if the layout doesn't support
      */
     @Test
-    fun qsbWidth_is_match_parent_for_tablet_landscape_without_inline() {
+    fun qsb_is_not_inline_for_tablet_landscape_without_inline() {
         initializeVarsForTablet(isLandscape = true)
         useTwoPanels = true
 
         val dp = newDP()
 
         assertThat(dp.isQsbInline).isFalse()
-        assertThat(dp.qsbWidth).isEqualTo(0)
     }
 
 }
\ No newline at end of file
diff --git a/tests/src/com/android/launcher3/deviceemulator/models/DeviceEmulationData.java b/tests/src/com/android/launcher3/deviceemulator/models/DeviceEmulationData.java
index 3623513..8d275cc 100644
--- a/tests/src/com/android/launcher3/deviceemulator/models/DeviceEmulationData.java
+++ b/tests/src/com/android/launcher3/deviceemulator/models/DeviceEmulationData.java
@@ -135,7 +135,7 @@
             resourceOverrides.put(s, getDimenByName(s, context.getResources(), 0));
         }
         return new DeviceEmulationData(info.currentSize.x, info.currentSize.y,
-                info.densityDpi, info.cutout, code, grids, resourceOverrides);
+                info.getDensityDpi(), info.cutout, code, grids, resourceOverrides);
     }
 
     public static DeviceEmulationData getDevice(String deviceCode) throws Exception {