Make hotseat column span responsive

Flag: NONE
Test: DeviceProfileDumpTest, DeviceProfileAlternativeDumpTest, HomeScreenImageTest
Bug: 325084912
Change-Id: Ifa9e8066662a1ab053f66b8800b739d813d2dab8
diff --git a/quickstep/tests/src/com/android/quickstep/HotseatWidthCalculationTest.kt b/quickstep/tests/src/com/android/quickstep/HotseatWidthCalculationTest.kt
index b1ba4c6..a388510 100644
--- a/quickstep/tests/src/com/android/quickstep/HotseatWidthCalculationTest.kt
+++ b/quickstep/tests/src/com/android/quickstep/HotseatWidthCalculationTest.kt
@@ -42,6 +42,8 @@
         assertThat(dp.hotseatBarEndOffset).isEqualTo(510)
         assertThat(dp.numShownHotseatIcons).isEqualTo(6)
         assertThat(dp.hotseatBorderSpace).isEqualTo(70)
+        assertThat(dp.hotseatColumnSpan).isEqualTo(6)
+        assertThat(dp.hotseatWidthPx).isEqualTo(1445)
 
         assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(150)
         assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(580)
@@ -64,6 +66,8 @@
         assertThat(dp.hotseatBarEndOffset).isEqualTo(510)
         assertThat(dp.numShownHotseatIcons).isEqualTo(4)
         assertThat(dp.hotseatBorderSpace).isEqualTo(40)
+        assertThat(dp.hotseatColumnSpan).isEqualTo(6)
+        assertThat(dp.hotseatWidthPx).isEqualTo(1080)
 
         assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(150)
         assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(550)
@@ -85,6 +89,8 @@
         assertThat(dp.hotseatBarEndOffset).isEqualTo(705)
         assertThat(dp.numShownHotseatIcons).isEqualTo(6)
         assertThat(dp.hotseatBorderSpace).isEqualTo(54)
+        assertThat(dp.hotseatColumnSpan).isEqualTo(6)
+        assertThat(dp.hotseatWidthPx).isEqualTo(1468)
 
         assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(231)
         assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(759)
@@ -100,22 +106,21 @@
     @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 }
-        }
+        inv?.apply { inlineQsb = BooleanArray(4) { false } }
         val dp = newDP()
         dp.isTaskbarPresentInApps = true
 
         assertThat(dp.hotseatBarEndOffset).isEqualTo(660)
         assertThat(dp.numShownHotseatIcons).isEqualTo(6)
         assertThat(dp.hotseatBorderSpace).isEqualTo(100)
+        assertThat(dp.hotseatColumnSpan).isEqualTo(6)
+        assertThat(dp.hotseatWidthPx).isEqualTo(1975)
 
         assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(300)
         assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(1040)
 
         assertThat(dp.isQsbInline).isFalse()
-        assertThat(dp.hotseatQsbWidth).isEqualTo(1223)
+        assertThat(dp.hotseatQsbWidth).isEqualTo(1965)
     }
 
     /** This is a case when after setting the hotseat, the QSB width needs to be changed to fit */
@@ -128,13 +133,15 @@
 
         assertThat(dp.hotseatBarEndOffset).isEqualTo(660)
         assertThat(dp.numShownHotseatIcons).isEqualTo(6)
-        assertThat(dp.hotseatBorderSpace).isEqualTo(36)
+        assertThat(dp.hotseatBorderSpace).isEqualTo(34)
+        assertThat(dp.hotseatColumnSpan).isEqualTo(4)
+        assertThat(dp.hotseatWidthPx).isEqualTo(1179)
 
-        assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(864)
-        assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(696)
+        assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(876)
+        assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(694)
 
         assertThat(dp.isQsbInline).isTrue()
-        assertThat(dp.hotseatQsbWidth).isEqualTo(528)
+        assertThat(dp.hotseatQsbWidth).isEqualTo(542)
     }
 
     /**
@@ -151,6 +158,8 @@
         assertThat(dp.hotseatBarEndOffset).isEqualTo(660)
         assertThat(dp.numShownHotseatIcons).isEqualTo(5)
         assertThat(dp.hotseatBorderSpace).isEqualTo(36)
+        assertThat(dp.hotseatColumnSpan).isEqualTo(4)
+        assertThat(dp.hotseatWidthPx).isEqualTo(1095)
 
         assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(816)
         assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(700)
@@ -158,4 +167,23 @@
         assertThat(dp.isQsbInline).isTrue()
         assertThat(dp.hotseatQsbWidth).isEqualTo(480)
     }
+
+    @Test
+    fun increase_span_when_space_between_icons_is_less_than_minimum() {
+        initializeVarsForTwoPanel(isGestureMode = false, isLandscape = false, rows = 5, cols = 5)
+        val dp = newDP()
+        dp.isTaskbarPresentInApps = true
+
+        assertThat(dp.hotseatBarEndOffset).isEqualTo(600)
+        assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+        assertThat(dp.hotseatBorderSpace).isEqualTo(48)
+        assertThat(dp.hotseatColumnSpan).isEqualTo(8)
+        assertThat(dp.hotseatWidthPx).isEqualTo(1383)
+
+        assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(126)
+        assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(652)
+
+        assertThat(dp.isQsbInline).isFalse()
+        assertThat(dp.hotseatQsbWidth).isEqualTo(1372)
+    }
 }
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index cc1f09e..eda9b2d 100644
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -40,6 +40,7 @@
 <!-- Hotseat -->
     <dimen name="dynamic_grid_hotseat_side_padding">0dp</dimen>
     <dimen name="spring_loaded_hotseat_top_margin">65dp</dimen>
+    <dimen name="min_hotseat_icon_space">17dp</dimen>
 
 <!-- Dragging -->
     <dimen name="drop_target_top_margin">64dp</dimen>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index ffc8bd0..ea66635 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -203,17 +203,6 @@
          defaults to 2 * numHotseatIcons -->
         <attr name="numExtendedHotseatIcons" format="integer" />
 
-        <!-- 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" />
-
         <!-- Spacing to have at the end of the nav buttons in large screen 3 button nav,
              defaults to @dimen/taskbar_button_margin_default -->
         <attr name="inlineNavButtonsEndSpacing" format="reference" />
diff --git a/res/xml/device_profiles.xml b/res/xml/device_profiles.xml
index c9a44a1..1d0dbff 100644
--- a/res/xml/device_profiles.xml
+++ b/res/xml/device_profiles.xml
@@ -168,7 +168,6 @@
         launcher:numFolderRows="3"
         launcher:numFolderColumns="3"
         launcher:numHotseatIcons="6"
-        launcher:hotseatColumnSpanLandscape="4"
         launcher:numAllAppsColumns="6"
         launcher:isScalable="true"
         launcher:inlineNavButtonsEndSpacing="@dimen/taskbar_button_margin_6_5"
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 3ddc7aa..65e2120 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -47,6 +47,7 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
 import androidx.core.content.res.ResourcesCompat;
 
 import com.android.launcher3.CellLayout.ContainerType;
@@ -212,6 +213,8 @@
     // Hotseat
     public int numShownHotseatIcons;
     public int hotseatCellHeightPx;
+    private int mHotseatColumnSpan;
+    private int mHotseatWidthPx; // not used in vertical bar layout
     public final boolean areNavButtonsInline;
     // In portrait: size = height, in landscape: size = width
     public int hotseatBarSizePx;
@@ -550,6 +553,7 @@
         areNavButtonsInline = isTaskbarPresent && !isGestureMode;
         numShownHotseatIcons =
                 isTwoPanels ? inv.numDatabaseHotseatIcons : inv.numShownHotseatIcons;
+        mHotseatColumnSpan = inv.numColumns;
 
         numShownAllAppsColumns =
                 isTwoPanels ? inv.numDatabaseAllAppsColumns : inv.numAllAppsColumns;
@@ -817,8 +821,7 @@
                     - hotseatBorderSpace * numShownHotseatIcons
                     - iconExtraSpacePx;
         } else {
-            int columns = inv.hotseatColumnSpan[mTypeIndex];
-            return getIconToIconWidthForColumns(columns) - iconExtraSpacePx;
+            return getIconToIconWidthForColumns(mHotseatColumnSpan) - iconExtraSpacePx;
         }
     }
 
@@ -889,10 +892,31 @@
     public void recalculateHotseatWidthAndBorderSpace() {
         if (!mIsScalableGrid) return;
 
-        int columns = inv.hotseatColumnSpan[mTypeIndex];
-        float hotseatWidthPx = getIconToIconWidthForColumns(columns);
-        hotseatBorderSpace = calculateHotseatBorderSpace(hotseatWidthPx, /* numExtraBorder= */ 0);
+        updateHotseatWidthAndBorderSpace(inv.numColumns);
+        int numWorkspaceColumns = getPanelCount() * inv.numColumns;
+        if (isTwoPanels) {
+            updateHotseatWidthAndBorderSpace(inv.numDatabaseHotseatIcons);
+            // If hotseat doesn't fit with current width, increase column span to fit by multiple
+            // of 2.
+            while (hotseatBorderSpace < mMinHotseatIconSpacePx
+                    && mHotseatColumnSpan < numWorkspaceColumns) {
+                updateHotseatWidthAndBorderSpace(mHotseatColumnSpan + 2);
+            }
+        }
+        if (isQsbInline) {
+            // If QSB is inline, reduce column span until it fits.
+            int maxHotseatWidthAllowedPx = getIconToIconWidthForColumns(numWorkspaceColumns);
+            int minHotseatWidthRequiredPx =
+                    mMinHotseatQsbWidthPx + hotseatBorderSpace + mHotseatWidthPx;
+            while (minHotseatWidthRequiredPx > maxHotseatWidthAllowedPx
+                    && mHotseatColumnSpan > 1) {
+                updateHotseatWidthAndBorderSpace(mHotseatColumnSpan - 1);
+                minHotseatWidthRequiredPx =
+                        mMinHotseatQsbWidthPx + hotseatBorderSpace + mHotseatWidthPx;
+            }
+        }
         hotseatQsbWidth = calculateQsbWidth(hotseatBorderSpace);
+
         // Spaces should be correct when the nav buttons are not inline
         if (!areNavButtonsInline) {
             return;
@@ -934,6 +958,12 @@
         } while (hotseatBorderSpace < mMinHotseatIconSpacePx && numShownHotseatIcons > 1);
     }
 
+    private void updateHotseatWidthAndBorderSpace(int columns) {
+        mHotseatColumnSpan = columns;
+        mHotseatWidthPx = getIconToIconWidthForColumns(mHotseatColumnSpan);
+        hotseatBorderSpace = calculateHotseatBorderSpace(mHotseatWidthPx, /* numExtraBorder= */ 0);
+    }
+
     private Point getCellLayoutBorderSpace(InvariantDeviceProfile idp) {
         return getCellLayoutBorderSpace(idp, 1f);
     }
@@ -957,6 +987,16 @@
         return mInfo;
     }
 
+    @VisibleForTesting
+    public int getHotseatColumnSpan() {
+        return mHotseatColumnSpan;
+    }
+
+    @VisibleForTesting
+    public int getHotseatWidthPx() {
+        return mHotseatWidthPx;
+    }
+
     public Builder toBuilder(Context context) {
         WindowBounds bounds = new WindowBounds(
                 widthPx, heightPx, availableWidthPx, availableHeightPx, rotationHint);
@@ -2119,7 +2159,8 @@
         writer.println(prefix + pxToDpStr("allAppsLeftRightMargin", allAppsLeftRightMargin));
 
         writer.println(prefix + pxToDpStr("hotseatBarSizePx", hotseatBarSizePx));
-        writer.println(prefix + "\tinv.hotseatColumnSpan: " + inv.hotseatColumnSpan[mTypeIndex]);
+        writer.println(prefix + "\tmHotseatColumnSpan: " + mHotseatColumnSpan);
+        writer.println(prefix + pxToDpStr("mHotseatWidthPx", mHotseatWidthPx));
         writer.println(prefix + pxToDpStr("hotseatCellHeightPx", hotseatCellHeightPx));
         writer.println(prefix + pxToDpStr("hotseatBarBottomSpacePx", hotseatBarBottomSpacePx));
         writer.println(prefix + pxToDpStr("mHotseatBarEdgePaddingPx",
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 2e0f676..ca10a57 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -163,7 +163,6 @@
      */
     public int numDatabaseHotseatIcons;
 
-    public int[] hotseatColumnSpan;
     public float[] hotseatBarBottomSpace;
     public float[] hotseatQsbSpace;
 
@@ -420,7 +419,6 @@
         numShownHotseatIcons = closestProfile.numHotseatIcons;
         numDatabaseHotseatIcons = deviceType == TYPE_MULTI_DISPLAY
                 ? closestProfile.numDatabaseHotseatIcons : closestProfile.numHotseatIcons;
-        hotseatColumnSpan = closestProfile.hotseatColumnSpan;
         hotseatBarBottomSpace = displayOption.hotseatBarBottomSpace;
         hotseatQsbSpace = displayOption.hotseatQsbSpace;
 
@@ -870,8 +868,6 @@
         private final int numHotseatIcons;
         private final int numDatabaseHotseatIcons;
 
-        private final int[] hotseatColumnSpan = new int[COUNT_SIZES];
-
         private final boolean[] inlineQsb = new boolean[COUNT_SIZES];
 
         private @DimenRes int inlineNavButtonsEndSpacing;
@@ -922,17 +918,6 @@
             numDatabaseHotseatIcons = a.getInt(
                     R.styleable.GridDisplayOption_numExtendedHotseatIcons, 2 * numHotseatIcons);
 
-            hotseatColumnSpan[INDEX_DEFAULT] = a.getInt(
-                    R.styleable.GridDisplayOption_hotseatColumnSpan, numColumns);
-            hotseatColumnSpan[INDEX_LANDSCAPE] = a.getInt(
-                    R.styleable.GridDisplayOption_hotseatColumnSpanLandscape, numColumns);
-            hotseatColumnSpan[INDEX_TWO_PANEL_LANDSCAPE] = a.getInt(
-                    R.styleable.GridDisplayOption_hotseatColumnSpanTwoPanelLandscape,
-                    numColumns);
-            hotseatColumnSpan[INDEX_TWO_PANEL_PORTRAIT] = a.getInt(
-                    R.styleable.GridDisplayOption_hotseatColumnSpanTwoPanelPortrait,
-                    numColumns);
-
             inlineNavButtonsEndSpacing =
                     a.getResourceId(R.styleable.GridDisplayOption_inlineNavButtonsEndSpacing,
                             R.dimen.taskbar_button_margin_default);
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait.txt
index 197e687..82a6310 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait.txt
@@ -71,7 +71,8 @@
 	allAppsPadding.right: 0.0px (0.0dp)
 	allAppsLeftRightMargin: 0.0px (0.0dp)
 	hotseatBarSizePx: 273.0px (104.0dp)
-	inv.hotseatColumnSpan: 5
+	mHotseatColumnSpan: 5
+	mHotseatWidthPx: 0.0px (0.0dp)
 	hotseatCellHeightPx: 166.0px (63.238094dp)
 	hotseatBarBottomSpacePx: 126.0px (48.0dp)
 	mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait3Button.txt
index 4a9e2e6..4271105 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait3Button.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait3Button.txt
@@ -71,7 +71,8 @@
 	allAppsPadding.right: 0.0px (0.0dp)
 	allAppsLeftRightMargin: 0.0px (0.0dp)
 	hotseatBarSizePx: 294.0px (112.0dp)
-	inv.hotseatColumnSpan: 5
+	mHotseatColumnSpan: 5
+	mHotseatWidthPx: 0.0px (0.0dp)
 	hotseatCellHeightPx: 166.0px (63.238094dp)
 	hotseatBarBottomSpacePx: 147.0px (56.0dp)
 	mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar.txt
index 9e89a16..8bd6b99 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar.txt
@@ -71,7 +71,8 @@
 	allAppsPadding.right: 0.0px (0.0dp)
 	allAppsLeftRightMargin: 0.0px (0.0dp)
 	hotseatBarSizePx: 252.0px (96.0dp)
-	inv.hotseatColumnSpan: 5
+	mHotseatColumnSpan: 5
+	mHotseatWidthPx: 0.0px (0.0dp)
 	hotseatCellHeightPx: 166.0px (63.238094dp)
 	hotseatBarBottomSpacePx: 0.0px (0.0dp)
 	mHotseatBarEdgePaddingPx: 63.0px (24.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar3Button.txt
index ce168b4..8dbb413 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar3Button.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar3Button.txt
@@ -71,7 +71,8 @@
 	allAppsPadding.right: 0.0px (0.0dp)
 	allAppsLeftRightMargin: 0.0px (0.0dp)
 	hotseatBarSizePx: 252.0px (96.0dp)
-	inv.hotseatColumnSpan: 5
+	mHotseatColumnSpan: 5
+	mHotseatWidthPx: 0.0px (0.0dp)
 	hotseatCellHeightPx: 166.0px (63.238094dp)
 	hotseatBarBottomSpacePx: 0.0px (0.0dp)
 	mHotseatBarEdgePaddingPx: 63.0px (24.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape.txt
index 7926033..ab4b286 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape.txt
@@ -71,7 +71,8 @@
 	allAppsPadding.right: 32.0px (16.0dp)
 	allAppsLeftRightMargin: 412.0px (206.0dp)
 	hotseatBarSizePx: 200.0px (100.0dp)
-	inv.hotseatColumnSpan: 4
+	mHotseatColumnSpan: 6
+	mHotseatWidthPx: 1960.0px (980.0dp)
 	hotseatCellHeightPx: 135.0px (67.5dp)
 	hotseatBarBottomSpacePx: 80.0px (40.0dp)
 	mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
@@ -82,12 +83,12 @@
 	springLoadedHotseatBarTopMarginPx: 128.0px (64.0dp)
 	getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
 	getHotseatLayoutPadding(context).bottom: 65.0px (32.5dp)
-	getHotseatLayoutPadding(context).left: 668.0px (334.0dp)
-	getHotseatLayoutPadding(context).right: 668.0px (334.0dp)
+	getHotseatLayoutPadding(context).left: 300.0px (150.0dp)
+	getHotseatLayoutPadding(context).right: 300.0px (150.0dp)
 	numShownHotseatIcons: 6
-	hotseatBorderSpace: 100.0px (50.0dp)
+	hotseatBorderSpace: 248.0px (124.0dp)
 	isQsbInline: false
-	hotseatQsbWidth: 1214.0px (607.0dp)
+	hotseatQsbWidth: 1950.0px (975.0dp)
 	isTaskbarPresent:false
 	isTaskbarPresentInApps:true
 	taskbarHeight: 0.0px (0.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape3Button.txt
index eb20578..80835bc 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape3Button.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape3Button.txt
@@ -71,7 +71,8 @@
 	allAppsPadding.right: 32.0px (16.0dp)
 	allAppsLeftRightMargin: 412.0px (206.0dp)
 	hotseatBarSizePx: 200.0px (100.0dp)
-	inv.hotseatColumnSpan: 4
+	mHotseatColumnSpan: 6
+	mHotseatWidthPx: 1960.0px (980.0dp)
 	hotseatCellHeightPx: 135.0px (67.5dp)
 	hotseatBarBottomSpacePx: 80.0px (40.0dp)
 	mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
@@ -82,12 +83,12 @@
 	springLoadedHotseatBarTopMarginPx: 128.0px (64.0dp)
 	getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
 	getHotseatLayoutPadding(context).bottom: 65.0px (32.5dp)
-	getHotseatLayoutPadding(context).left: 668.0px (334.0dp)
-	getHotseatLayoutPadding(context).right: 668.0px (334.0dp)
+	getHotseatLayoutPadding(context).left: 300.0px (150.0dp)
+	getHotseatLayoutPadding(context).right: 300.0px (150.0dp)
 	numShownHotseatIcons: 6
-	hotseatBorderSpace: 100.0px (50.0dp)
+	hotseatBorderSpace: 248.0px (124.0dp)
 	isQsbInline: false
-	hotseatQsbWidth: 1214.0px (607.0dp)
+	hotseatQsbWidth: 1950.0px (975.0dp)
 	isTaskbarPresent:false
 	isTaskbarPresentInApps:true
 	taskbarHeight: 0.0px (0.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait.txt
index dba0ec4..fc53107 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait.txt
@@ -71,7 +71,8 @@
 	allAppsPadding.right: 32.0px (16.0dp)
 	allAppsLeftRightMargin: 152.0px (76.0dp)
 	hotseatBarSizePx: 272.0px (136.0dp)
-	inv.hotseatColumnSpan: 6
+	mHotseatColumnSpan: 6
+	mHotseatWidthPx: 1300.0px (650.0dp)
 	hotseatCellHeightPx: 135.0px (67.5dp)
 	hotseatBarBottomSpacePx: 152.0px (76.0dp)
 	mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait3Button.txt
index 495afb2..836819f 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait3Button.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait3Button.txt
@@ -71,7 +71,8 @@
 	allAppsPadding.right: 32.0px (16.0dp)
 	allAppsLeftRightMargin: 152.0px (76.0dp)
 	hotseatBarSizePx: 272.0px (136.0dp)
-	inv.hotseatColumnSpan: 6
+	mHotseatColumnSpan: 6
+	mHotseatWidthPx: 1300.0px (650.0dp)
 	hotseatCellHeightPx: 135.0px (67.5dp)
 	hotseatBarBottomSpacePx: 152.0px (76.0dp)
 	mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape.txt
index e7dd3e0..108182f 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape.txt
@@ -71,7 +71,8 @@
 	allAppsPadding.right: 42.0px (16.0dp)
 	allAppsLeftRightMargin: 183.0px (69.71429dp)
 	hotseatBarSizePx: 267.0px (101.71429dp)
-	inv.hotseatColumnSpan: 4
+	mHotseatColumnSpan: 4
+	mHotseatWidthPx: 0.0px (0.0dp)
 	hotseatCellHeightPx: 159.0px (60.57143dp)
 	hotseatBarBottomSpacePx: 126.0px (48.0dp)
 	mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape3Button.txt
index fcbd427..313d2a3 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape3Button.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape3Button.txt
@@ -71,7 +71,8 @@
 	allAppsPadding.right: 42.0px (16.0dp)
 	allAppsLeftRightMargin: 183.0px (69.71429dp)
 	hotseatBarSizePx: 267.0px (101.71429dp)
-	inv.hotseatColumnSpan: 4
+	mHotseatColumnSpan: 4
+	mHotseatWidthPx: 0.0px (0.0dp)
 	hotseatCellHeightPx: 159.0px (60.57143dp)
 	hotseatBarBottomSpacePx: 126.0px (48.0dp)
 	mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait.txt
index 319247c..fb392a8 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait.txt
@@ -71,7 +71,8 @@
 	allAppsPadding.right: 42.0px (16.0dp)
 	allAppsLeftRightMargin: 1.0px (0.3809524dp)
 	hotseatBarSizePx: 267.0px (101.71429dp)
-	inv.hotseatColumnSpan: 4
+	mHotseatColumnSpan: 4
+	mHotseatWidthPx: 0.0px (0.0dp)
 	hotseatCellHeightPx: 159.0px (60.57143dp)
 	hotseatBarBottomSpacePx: 126.0px (48.0dp)
 	mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait3Button.txt
index 50c1d4b..2c4b3c3 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait3Button.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait3Button.txt
@@ -71,7 +71,8 @@
 	allAppsPadding.right: 42.0px (16.0dp)
 	allAppsLeftRightMargin: 1.0px (0.3809524dp)
 	hotseatBarSizePx: 267.0px (101.71429dp)
-	inv.hotseatColumnSpan: 4
+	mHotseatColumnSpan: 4
+	mHotseatWidthPx: 0.0px (0.0dp)
 	hotseatCellHeightPx: 159.0px (60.57143dp)
 	hotseatBarBottomSpacePx: 126.0px (48.0dp)
 	mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
diff --git a/tests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt b/tests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt
index 251a401..13d7499 100644
--- a/tests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt
+++ b/tests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt
@@ -157,7 +157,6 @@
 
                 numDatabaseHotseatIcons = 4
 
-                hotseatColumnSpan = IntArray(4) { 4 }
                 hotseatBarBottomSpace = FloatArray(4) { 48f }
                 hotseatQsbSpace = FloatArray(4) { 36f }
 
@@ -240,7 +239,6 @@
 
                 numDatabaseHotseatIcons = 6
 
-                hotseatColumnSpan = intArrayOf(6, 4, 6, 6)
                 hotseatBarBottomSpace = floatArrayOf(36f, 40f, 36f, 36f)
                 hotseatQsbSpace = FloatArray(4) { 32f }
 
@@ -259,8 +257,10 @@
     }
 
     protected fun initializeVarsForTwoPanel(
-        isLandscape: Boolean = false,
-        isGestureMode: Boolean = true
+            isLandscape: Boolean = false,
+            isGestureMode: Boolean = true,
+            rows: Int = 4,
+            cols: Int = 4,
     ) {
         val (x, y) = if (isLandscape) Pair(2208, 1840) else Pair(1840, 2208)
 
@@ -276,9 +276,9 @@
 
         inv =
             InvariantDeviceProfile().apply {
-                numRows = 4
-                numColumns = 4
-                numSearchContainerColumns = 4
+                numRows = rows
+                numColumns = cols
+                numSearchContainerColumns = cols
 
                 iconSize = floatArrayOf(60f, 52f, 52f, 60f)
                 iconTextSize = floatArrayOf(14f, 14f, 12f, 14f)
@@ -319,7 +319,6 @@
 
                 numDatabaseHotseatIcons = 6
 
-                hotseatColumnSpan = IntArray(4) { 6 }
                 hotseatBarBottomSpace = floatArrayOf(48f, 48f, 36f, 20f)
                 hotseatQsbSpace = floatArrayOf(36f, 36f, 36f, 28f)
 
diff --git a/tests/src/com/android/launcher3/nonquickstep/HotseatWidthCalculationTest.kt b/tests/src/com/android/launcher3/nonquickstep/HotseatWidthCalculationTest.kt
index 9912a34..408691c 100644
--- a/tests/src/com/android/launcher3/nonquickstep/HotseatWidthCalculationTest.kt
+++ b/tests/src/com/android/launcher3/nonquickstep/HotseatWidthCalculationTest.kt
@@ -42,6 +42,8 @@
         assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
         assertThat(dp.numShownHotseatIcons).isEqualTo(6)
         assertThat(dp.hotseatBorderSpace).isEqualTo(145)
+        assertThat(dp.hotseatColumnSpan).isEqualTo(6)
+        assertThat(dp.hotseatWidthPx).isEqualTo(1445)
 
         assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(177)
         assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(177)
@@ -64,6 +66,8 @@
         assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
         assertThat(dp.numShownHotseatIcons).isEqualTo(6)
         assertThat(dp.hotseatBorderSpace).isEqualTo(72)
+        assertThat(dp.hotseatColumnSpan).isEqualTo(6)
+        assertThat(dp.hotseatWidthPx).isEqualTo(1080)
 
         assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(110)
         assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(110)
@@ -85,6 +89,8 @@
         assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
         assertThat(dp.numShownHotseatIcons).isEqualTo(6)
         assertThat(dp.hotseatBorderSpace).isEqualTo(104)
+        assertThat(dp.hotseatColumnSpan).isEqualTo(6)
+        assertThat(dp.hotseatWidthPx).isEqualTo(1468)
 
         assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(370)
         assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(370)
@@ -100,22 +106,21 @@
     @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 }
-        }
+        inv?.apply { 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.hotseatBorderSpace).isEqualTo(248)
+        assertThat(dp.hotseatColumnSpan).isEqualTo(6)
+        assertThat(dp.hotseatWidthPx).isEqualTo(1960)
 
-        assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(668)
-        assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(668)
+        assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(300)
+        assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(300)
 
         assertThat(dp.isQsbInline).isFalse()
-        assertThat(dp.hotseatQsbWidth).isEqualTo(1214)
+        assertThat(dp.hotseatQsbWidth).isEqualTo(1950)
     }
 
     /** This is a case when after setting the hotseat, the QSB width needs to be changed to fit */
@@ -128,13 +133,15 @@
 
         assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
         assertThat(dp.numShownHotseatIcons).isEqualTo(6)
-        assertThat(dp.hotseatBorderSpace).isEqualTo(91)
+        assertThat(dp.hotseatBorderSpace).isEqualTo(233)
+        assertThat(dp.hotseatColumnSpan).isEqualTo(6)
+        assertThat(dp.hotseatWidthPx).isEqualTo(1885)
 
-        assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(640)
-        assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(640)
+        assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(287)
+        assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(287)
 
         assertThat(dp.isQsbInline).isFalse()
-        assertThat(dp.hotseatQsbWidth).isEqualTo(1169)
+        assertThat(dp.hotseatQsbWidth).isEqualTo(1875)
     }
 
     /**
@@ -150,13 +157,15 @@
 
         assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
         assertThat(dp.numShownHotseatIcons).isEqualTo(6)
-        assertThat(dp.hotseatBorderSpace).isEqualTo(75)
+        assertThat(dp.hotseatBorderSpace).isEqualTo(205)
+        assertThat(dp.hotseatColumnSpan).isEqualTo(6)
+        assertThat(dp.hotseatWidthPx).isEqualTo(1745)
 
-        assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(582)
-        assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(582)
+        assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(257)
+        assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(257)
 
         assertThat(dp.isQsbInline).isFalse()
-        assertThat(dp.hotseatQsbWidth).isEqualTo(1085)
+        assertThat(dp.hotseatQsbWidth).isEqualTo(1735)
     }
 
     @Test
@@ -179,4 +188,23 @@
             assertThat(dp.hotseatQsbWidth).isEqualTo(1435)
         }
     }
+
+    @Test
+    fun increase_span_when_space_between_icons_is_less_than_minimum() {
+        initializeVarsForTwoPanel(isGestureMode = false, isLandscape = false, rows = 5, cols = 5)
+        val dp = newDP()
+        dp.isTaskbarPresentInApps = true
+
+        assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
+        assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+        assertThat(dp.hotseatBorderSpace).isEqualTo(112)
+        assertThat(dp.hotseatColumnSpan).isEqualTo(8)
+        assertThat(dp.hotseatWidthPx).isEqualTo(1383)
+
+        assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(228)
+        assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(228)
+
+        assertThat(dp.isQsbInline).isFalse()
+        assertThat(dp.hotseatQsbWidth).isEqualTo(1372)
+    }
 }