Add GridDimensionSpecs to fixed landscape and make grid dimension generalized so we can use it to determine row count or col count

Bug: 364711064
Flag: com.android.launcher3.one_grid_specs
Test: HomeScreenImageTest
Change-Id: If1dafedc710ebc483fc7b6b5cd6cae6f70dc3cfc
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index c477633..698877a 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -162,10 +162,11 @@
         <attr name="layout_sticky" format="boolean" />
     </declare-styleable>
 
-    <declare-styleable name="GridDimension">
-        <attr name="minDeviceWidthDp" format="integer"/>
-        <attr name="minDeviceHeightDp" format="integer"/>
-        <attr name="numGridDimension" format="integer"/>
+    <declare-styleable name="GridSize">
+        <attr name="minDeviceWidthDp" format="float"/>
+        <attr name="minDeviceHeightDp" format="float"/>
+        <attr name="numGridRows" format="integer"/>
+        <attr name="numGridColumns" format="integer"/>
         <attr name="dbFile" />
         <attr name="defaultLayoutId"/>
         <attr name="demoModeLayoutId"/>
@@ -261,7 +262,7 @@
         <!-- File that contains the specs for all apps icon and text size.
         Needs FeatureFlags.ENABLE_RESPONSIVE_WORKSPACE enabled -->
         <attr name="allAppsCellSpecsId" format="reference" />
-        <attr name="rowCountSpecsId" format="reference" />
+        <attr name="gridSizeSpecsId" format="reference" />
         <!-- defaults to allAppsCellSpecsId, if not specified -->
         <attr name="allAppsCellSpecsTwoPanelId" format="reference" />
         <!-- defaults to false, if not specified -->
diff --git a/res/xml/backupscheme.xml b/res/xml/backupscheme.xml
index 34b80b1..083af5c 100644
--- a/res/xml/backupscheme.xml
+++ b/res/xml/backupscheme.xml
@@ -11,6 +11,7 @@
     <include domain="database" path="launcher_3_by_3.db" />
     <include domain="database" path="launcher_2_by_2.db" />
     <include domain="database" path="launcher_7_by_3.db" />
+    <include domain="database" path="launcher_8_by_3.db" />
     <include domain="sharedpref" path="com.android.launcher3.prefs.xml" />
     <include domain="file" path="downgrade_schema.json" />
 
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 9b6fe4e..16d9525 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -865,7 +865,7 @@
         canQsbInline = canQsbInline && hotseatQsbHeight > 0;
 
         return (mIsScalableGrid && inv.inlineQsb[mTypeIndex] && canQsbInline)
-                || inv.isFixedLandscapeMode;
+                || inv.isFixedLandscape;
     }
 
     private static DotRenderer createDotRenderer(
@@ -1834,7 +1834,7 @@
             }
             int paddingTop = workspaceTopPadding + (mIsScalableGrid ? 0 : edgeMarginPx);
             // On isFixedLandscapeMode on phones we already have padding because of the camera hole
-            int paddingSide = inv.isFixedLandscapeMode ? 0 : desiredWorkspaceHorizontalMarginPx;
+            int paddingSide = inv.isFixedLandscape ? 0 : desiredWorkspaceHorizontalMarginPx;
 
             padding.set(paddingSide, paddingTop, paddingSide, paddingBottom);
         }
@@ -1934,7 +1934,7 @@
                 hotseatBarPadding.set(mHotseatBarWorkspaceSpacePx, paddingTop,
                         mInsets.right + mHotseatBarEdgePaddingPx, paddingBottom);
             }
-        } else if (isTaskbarPresent || inv.isFixedLandscapeMode) {
+        } else if (isTaskbarPresent || inv.isFixedLandscape) {
             // Center the QSB vertically with hotseat
             int hotseatBarBottomPadding = getHotseatBarBottomPadding();
             int hotseatBarTopPadding =
@@ -1953,7 +1953,7 @@
             }
             startSpacing += getAdditionalQsbSpace();
 
-            if (inv.isFixedLandscapeMode) {
+            if (inv.isFixedLandscape) {
                 endSpacing += mInsets.right;
                 startSpacing +=  mInsets.left;
             }
@@ -2568,7 +2568,7 @@
             }
             if (mTransposeLayoutWithOrientation == null) {
                 mTransposeLayoutWithOrientation =
-                        !(mInfo.isTablet(mWindowBounds) || mInv.isFixedLandscapeMode);
+                        !(mInfo.isTablet(mWindowBounds) || mInv.isFixedLandscape);
             }
             if (mIsGestureMode == null) {
                 mIsGestureMode = mInfo.getNavigationMode().hasGestures;
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index c044c52..dfbcf5c 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -188,7 +188,7 @@
     @XmlRes
     public int workspaceSpecsId = INVALID_RESOURCE_HANDLE;
     @XmlRes
-    public int rowCountSpecsId = INVALID_RESOURCE_HANDLE;;
+    public int gridSizeSpecsId = INVALID_RESOURCE_HANDLE;;
     @XmlRes
     public int workspaceSpecsTwoPanelId = INVALID_RESOURCE_HANDLE;
     @XmlRes
@@ -216,7 +216,7 @@
     /**
      * Fixed landscape mode is the landscape on the phones.
      */
-    public boolean isFixedLandscapeMode = false;
+    public boolean isFixedLandscape = false;
     private LauncherPrefChangeListener mLandscapeModePreferenceListener;
 
     public String dbFile;
@@ -255,9 +255,12 @@
                 });
         if (Flags.oneGridSpecs()) {
             mLandscapeModePreferenceListener = (String s) -> {
-                boolean newFixedLandscapeValue = FIXED_LANDSCAPE_MODE.get(context);
-                if (isFixedLandscapeMode != newFixedLandscapeValue) {
-                    setFixedLandscape(context, newFixedLandscapeValue);
+                if (isFixedLandscape != FIXED_LANDSCAPE_MODE.get(context)) {
+                    MAIN_EXECUTOR.execute(() -> {
+                        Trace.beginSection("InvariantDeviceProfile#setFixedLandscape");
+                        onConfigChanged(context.getApplicationContext());
+                        Trace.endSection();
+                    });
                 }
             };
             LauncherPrefs.INSTANCE.get(context).addListener(
@@ -295,7 +298,7 @@
                         gridName,
                         defaultInfo,
                         /*allowDisabledGrid=*/false,
-                        isFixedLandscapeMode
+                        FIXED_LANDSCAPE_MODE.get(context)
                 ),
                 defaultDeviceType);
 
@@ -309,7 +312,7 @@
                         gridName,
                         myInfo,
                         /*allowDisabledGrid=*/false,
-                        isFixedLandscapeMode
+                        FIXED_LANDSCAPE_MODE.get(context)
                 ),
                 deviceType);
 
@@ -345,13 +348,7 @@
     }
 
     private String initGrid(Context context, String gridName) {
-        if (!Flags.oneGridSpecs() && (isFixedLandscapeMode || FIXED_LANDSCAPE_MODE.get(context))) {
-            LauncherPrefs.get(context).put(FIXED_LANDSCAPE_MODE, false);
-            isFixedLandscapeMode = false;
-        }
-
         Info displayInfo = DisplayController.INSTANCE.get(context).getInfo();
-
         List<DisplayOption> allOptions = getPredefinedDeviceProfiles(
                 context,
                 gridName,
@@ -413,7 +410,7 @@
         isScalable = closestProfile.isScalable;
         devicePaddingId = closestProfile.devicePaddingId;
         workspaceSpecsId = closestProfile.mWorkspaceSpecsId;
-        rowCountSpecsId = closestProfile.mRowCountSpecsId;
+        gridSizeSpecsId = closestProfile.mGridSizeSpecsId;
         workspaceSpecsTwoPanelId = closestProfile.mWorkspaceSpecsTwoPanelId;
         allAppsSpecsId = closestProfile.mAllAppsSpecsId;
         allAppsSpecsTwoPanelId = closestProfile.mAllAppsSpecsTwoPanelId;
@@ -473,7 +470,7 @@
         startAlignTaskbar = displayOption.startAlignTaskbar;
 
         // Fixed Landscape mode
-        isFixedLandscapeMode = FIXED_LANDSCAPE_MODE.get(context) && Flags.oneGridSpecs();
+        isFixedLandscape = closestProfile.mIsFixedLandscape;
 
         // If the partner customization apk contains any grid overrides, apply them
         // Supported overrides: numRows, numColumns, iconSize
@@ -543,24 +540,6 @@
         });
     }
 
-    /**
-     * Updates the fixed landscape mode, this triggers a new IDP, reloads the database and triggers
-     * a grid migration.
-     */
-    public void setFixedLandscape(Context context, boolean isFixedLandscape) {
-        this.isFixedLandscapeMode = isFixedLandscape;
-        if (isFixedLandscape) {
-            // When in isFixedLandscape there should only be one default grid to choose from
-            MAIN_EXECUTOR.execute(() -> {
-                Trace.beginSection("InvariantDeviceProfile#setFixedLandscape");
-                onConfigChanged(context.getApplicationContext());
-                Trace.endSection();
-            });
-        } else {
-            setCurrentGrid(context, LauncherPrefs.get(context).get(GRID_NAME));
-        }
-    }
-
     private Object[] toModelState() {
         return new Object[]{
                 numColumns, numRows, numSearchContainerColumns, numDatabaseHotseatIcons,
@@ -651,14 +630,14 @@
     }
 
     /**
-     * Parses through the xml to find GridDimension specs. Then calls findBestRowCount to get the
-     * correct row count for this GridOption.
+     * Parses through the xml to find GridSize specs. Then calls findBestGridSize to get the
+     * correct grid size for this GridOption.
      *
-     * @return the result of {@link #findBestRowCount(List, int, int)}.
+     * @return the result of {@link #findBestGridSize(List, int, int)}.
      */
-    private static GridDimension getRowCount(ResourceHelper resourceHelper, Context context,
+    private static GridSize getGridSize(ResourceHelper resourceHelper, Context context,
             Info displayInfo) {
-        ArrayList<GridDimension> rowCounts = new ArrayList<>();
+        ArrayList<GridSize> gridSizes = new ArrayList<>();
 
         try (XmlResourceParser parser = resourceHelper.getXml()) {
             final int depth = parser.getDepth();
@@ -666,8 +645,8 @@
             while (((type = parser.next()) != XmlPullParser.END_TAG
                     || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
                 if ((type == XmlPullParser.START_TAG)
-                        && "GridDimension".equals(parser.getName())) {
-                    rowCounts.add(new GridDimension(context, Xml.asAttributeSet(parser)));
+                        && "GridSize".equals(parser.getName())) {
+                    gridSizes.add(new GridSize(context, Xml.asAttributeSet(parser)));
                 }
             }
         } catch (IOException | XmlPullParserException e) {
@@ -677,24 +656,26 @@
         // Finds the min width and height in dp for all displays.
         int[] dimens = findMinWidthAndHeightDpForDevice(displayInfo);
 
-        return findBestRowCount(rowCounts, dimens[0], dimens[1]);
+        return findBestGridSize(gridSizes, dimens[0], dimens[1]);
     }
 
     /**
-     * @return the biggest row count that fits the display dimensions spec using GridDimension to
-     * determine that. If no best row count is found, return null.
+     * @return the biggest grid size that fits the display dimensions.
+     * If no best grid size is found, return null.
      */
-    private static GridDimension findBestRowCount(List<GridDimension> list, int minWidthDp,
+    private static GridSize findBestGridSize(List<GridSize> list, int minWidthDp,
             int minHeightDp) {
-        GridDimension selectedRow = null;
-        for (GridDimension item: list) {
+        GridSize selectedGridSize = null;
+        for (GridSize item: list) {
             if (minWidthDp >= item.mMinDeviceWidthDp && minHeightDp >= item.mMinDeviceHeightDp) {
-                if (selectedRow == null || selectedRow.mNumGridDimension < item.mNumGridDimension) {
-                    selectedRow = item;
+                if (selectedGridSize == null
+                        || (selectedGridSize.mNumColumns <= item.mNumColumns
+                        && selectedGridSize.mNumRows <= item.mNumRows)) {
+                    selectedGridSize = item;
                 }
             }
         }
-        return selectedRow;
+        return selectedGridSize;
     }
 
     private static int[] findMinWidthAndHeightDpForDevice(Info displayInfo) {
@@ -767,7 +748,7 @@
         return parseAllDefinedGridOptions(context, displayInfo)
                 .stream()
                 .filter(go -> go.isEnabled(deviceType))
-                .filter(go -> go.filterByFlag(deviceType, isFixedLandscapeMode))
+                .filter(go -> go.filterByFlag(deviceType, isFixedLandscape))
                 .collect(Collectors.toList());
     }
 
@@ -1037,7 +1018,7 @@
         private final int mWorkspaceCellSpecsTwoPanelId;
         private final int mAllAppsCellSpecsId;
         private final int mAllAppsCellSpecsTwoPanelId;
-        private final int mRowCountSpecsId;
+        private final int mGridSizeSpecsId;
         private final boolean mIsFixedLandscape;
         private final boolean mIsOldGrid;
 
@@ -1048,18 +1029,20 @@
             title = a.getString(R.styleable.GridDisplayOption_title);
             deviceCategory = a.getInt(R.styleable.GridDisplayOption_deviceCategory,
                     DEVICE_CATEGORY_ALL);
-            mRowCountSpecsId = a.getResourceId(
-                    R.styleable.GridDisplayOption_rowCountSpecsId, INVALID_RESOURCE_HANDLE);
+            mGridSizeSpecsId = a.getResourceId(
+                    R.styleable.GridDisplayOption_gridSizeSpecsId, INVALID_RESOURCE_HANDLE);
             mIsDualGrid = a.getBoolean(R.styleable.GridDisplayOption_isDualGrid, false);
-            if (mRowCountSpecsId != INVALID_RESOURCE_HANDLE) {
-                ResourceHelper resourceHelper = new ResourceHelper(context, mRowCountSpecsId);
-                GridDimension numR = getRowCount(resourceHelper, context, displayInfo);
-                numRows = numR.mNumGridDimension;
-                dbFile = numR.mDbFile;
-                defaultLayoutId = numR.mDefaultLayoutId;
-                demoModeLayoutId = numR.mDemoModeLayoutId;
+            if (mGridSizeSpecsId != INVALID_RESOURCE_HANDLE) {
+                ResourceHelper resourceHelper = new ResourceHelper(context, mGridSizeSpecsId);
+                GridSize gridSize = getGridSize(resourceHelper, context, displayInfo);
+                numColumns = gridSize.mNumColumns;
+                numRows = gridSize.mNumRows;
+                dbFile = gridSize.mDbFile;
+                defaultLayoutId = gridSize.mDefaultLayoutId;
+                demoModeLayoutId = gridSize.mDemoModeLayoutId;
             } else {
                 numRows = a.getInt(R.styleable.GridDisplayOption_numRows, 0);
+                numColumns = a.getInt(R.styleable.GridDisplayOption_numColumns, 0);
                 dbFile = a.getString(R.styleable.GridDisplayOption_dbFile);
                 defaultLayoutId = a.getResourceId(
                         R.styleable.GridDisplayOption_defaultLayoutId, 0);
@@ -1067,7 +1050,6 @@
                         R.styleable.GridDisplayOption_demoModeLayoutId, defaultLayoutId);
             }
 
-            numColumns = a.getInt(R.styleable.GridDisplayOption_numColumns, 0);
             numSearchContainerColumns = a.getInt(
                     R.styleable.GridDisplayOption_numSearchContainerColumns, numColumns);
 
@@ -1230,7 +1212,7 @@
             }
 
             // Here we return true if we want to show the new grids.
-            if (mRowCountSpecsId != INVALID_RESOURCE_HANDLE) {
+            if (mGridSizeSpecsId != INVALID_RESOURCE_HANDLE) {
                 return Flags.oneGridSpecs();
             }
 
@@ -1243,26 +1225,28 @@
         }
     }
 
-    public static final class GridDimension {
-        final int mNumGridDimension;
-        final int mMinDeviceWidthDp;
-        final int mMinDeviceHeightDp;
+    public static final class GridSize {
+        final int mNumRows;
+        final int mNumColumns;
+        final float mMinDeviceWidthDp;
+        final float mMinDeviceHeightDp;
         final String mDbFile;
         final int mDefaultLayoutId;
         final int mDemoModeLayoutId;
 
 
-        GridDimension(Context context, AttributeSet attrs) {
-            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GridDimension);
+        GridSize(Context context, AttributeSet attrs) {
+            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GridSize);
 
-            mNumGridDimension = (int) a.getFloat(R.styleable.GridDimension_numGridDimension, 0);
-            mMinDeviceWidthDp = a.getInt(R.styleable.GridDimension_minDeviceWidthDp, 0);
-            mMinDeviceHeightDp = a.getInt(R.styleable.GridDimension_minDeviceHeightDp, 0);
-            mDbFile = a.getString(R.styleable.GridDimension_dbFile);
+            mNumRows = (int) a.getFloat(R.styleable.GridSize_numGridRows, 0);
+            mNumColumns = (int) a.getFloat(R.styleable.GridSize_numGridColumns, 0);
+            mMinDeviceWidthDp = a.getFloat(R.styleable.GridSize_minDeviceWidthDp, 0);
+            mMinDeviceHeightDp = a.getFloat(R.styleable.GridSize_minDeviceHeightDp, 0);
+            mDbFile = a.getString(R.styleable.GridSize_dbFile);
             mDefaultLayoutId = a.getResourceId(
-                    R.styleable.GridDimension_defaultLayoutId, 0);
+                    R.styleable.GridSize_defaultLayoutId, 0);
             mDemoModeLayoutId = a.getResourceId(
-                    R.styleable.GridDimension_demoModeLayoutId, mDefaultLayoutId);
+                    R.styleable.GridSize_demoModeLayoutId, mDefaultLayoutId);
 
             a.recycle();
         }
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 8981024..aaa0c41 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -789,7 +789,7 @@
             LauncherPrefs.get(this).put(LauncherPrefs.ALLOW_ROTATION, false);
         }
         getRotationHelper().setFixedLandscape(
-                Objects.requireNonNull(mDeviceProfile.inv).isFixedLandscapeMode
+                Objects.requireNonNull(mDeviceProfile.inv).isFixedLandscape
         );
     }
 
diff --git a/src/com/android/launcher3/LauncherFiles.java b/src/com/android/launcher3/LauncherFiles.java
index a5b8168..c702414 100644
--- a/src/com/android/launcher3/LauncherFiles.java
+++ b/src/com/android/launcher3/LauncherFiles.java
@@ -24,6 +24,7 @@
     public static final String LAUNCHER_4_BY_4_DB = "launcher_4_by_4.db";
     public static final String LAUNCHER_3_BY_3_DB = "launcher_3_by_3.db";
     public static final String LAUNCHER_2_BY_2_DB = "launcher_2_by_2.db";
+    public static final String LAUNCHER_7_BY_3_DB = "launcher_7_by_3.db";
     public static final String LAUNCHER_8_BY_3_DB = "launcher_8_by_3.db";
     public static final String BACKUP_DB = "backup.db";
     public static final String SHARED_PREFERENCES_KEY = "com.android.launcher3.prefs";
@@ -45,6 +46,7 @@
             LAUNCHER_4_BY_4_DB,
             LAUNCHER_3_BY_3_DB,
             LAUNCHER_2_BY_2_DB,
+            LAUNCHER_7_BY_3_DB,
             LAUNCHER_8_BY_3_DB));
 
     public static final List<String> OTHER_FILES = Collections.unmodifiableList(Arrays.asList(
diff --git a/src/com/android/launcher3/settings/SettingsActivity.java b/src/com/android/launcher3/settings/SettingsActivity.java
index 5068b48..6008287 100644
--- a/src/com/android/launcher3/settings/SettingsActivity.java
+++ b/src/com/android/launcher3/settings/SettingsActivity.java
@@ -23,6 +23,7 @@
 import static com.android.launcher3.BuildConfig.IS_DEBUG_DEVICE;
 import static com.android.launcher3.BuildConfig.IS_STUDIO_BUILD;
 import static com.android.launcher3.InvariantDeviceProfile.TYPE_MULTI_DISPLAY;
+import static com.android.launcher3.InvariantDeviceProfile.TYPE_TABLET;
 import static com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY;
 
 import android.app.Activity;
@@ -315,7 +316,9 @@
                     if (!Flags.oneGridSpecs()
                             // adding this condition until fixing b/378972567
                             || InvariantDeviceProfile.INSTANCE.get(getContext()).deviceType
-                            == TYPE_MULTI_DISPLAY) {
+                            == TYPE_MULTI_DISPLAY
+                            || InvariantDeviceProfile.INSTANCE.get(getContext()).deviceType
+                            == TYPE_TABLET) {
                         return false;
                     }
                     // When the setting changes rotate the screen accordingly to showcase the result