Merge "Migrate existing 4x5 and 4x4 grid users to a new 4x5 grid." into sc-dev
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index fc2b4bc..99f6c75 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -132,6 +132,9 @@
         <attr name="isScalable" format="boolean" />
         <attr name="devicePaddingId" format="reference" />
 
+        <!-- whether the grid option is shown to the user -->
+        <attr name="visible" format="boolean" />
+
     </declare-styleable>
 
     <declare-styleable name="DevicePadding">
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 9df8d44..7ece72e 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -19,7 +19,6 @@
 import static android.animation.ValueAnimator.areAnimatorsEnabled;
 
 import static com.android.launcher3.anim.Interpolators.DEACCEL_1_5;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_FOUR_COLUMNS;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -602,7 +601,7 @@
         if (child instanceof BubbleTextView) {
             BubbleTextView bubbleChild = (BubbleTextView) child;
             bubbleChild.setTextVisibility(mContainerType != HOTSEAT);
-            if (ENABLE_FOUR_COLUMNS.get()) {
+            if (mActivity.getDeviceProfile().isScalableGrid) {
                 bubbleChild.setCenterVertically(mContainerType != HOTSEAT);
             }
         }
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index b0c3bb4..754e988 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -626,6 +626,8 @@
         private final boolean isScalable;
         private final int devicePaddingId;
 
+        public final boolean visible;
+
         private final SparseArray<TypedValue> extraAttrs;
 
         public GridOption(Context context, AttributeSet attrs) {
@@ -652,6 +654,8 @@
             devicePaddingId = a.getResourceId(
                     R.styleable.GridDisplayOption_devicePaddingId, 0);
 
+            visible = a.getBoolean(R.styleable.GridDisplayOption_visible, true);
+
             a.recycle();
 
             extraAttrs = Themes.createValueMap(context, attrs,
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 57d7600..ccc023a 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -17,8 +17,11 @@
 package com.android.launcher3;
 
 import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_ICON_PARAMS;
-import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI;
+import static com.android.launcher3.InvariantDeviceProfile.KEY_MIGRATION_SRC_HOTSEAT_COUNT;
+import static com.android.launcher3.InvariantDeviceProfile.KEY_MIGRATION_SRC_WORKSPACE_SIZE;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_FOUR_COLUMNS;
 import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI;
 
 import android.content.ComponentName;
 import android.content.Context;
@@ -37,10 +40,10 @@
 import com.android.launcher3.pm.InstallSessionHelper;
 import com.android.launcher3.pm.InstallSessionTracker;
 import com.android.launcher3.pm.UserCache;
-import com.android.launcher3.util.SettingsCache;
 import com.android.launcher3.util.MainThreadInitializedObject;
 import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.util.SafeCloseable;
+import com.android.launcher3.util.SettingsCache;
 import com.android.launcher3.util.SimpleBroadcastReceiver;
 import com.android.launcher3.widget.custom.CustomWidgetManager;
 
@@ -122,6 +125,34 @@
         mContext = context;
 
         mInvariantDeviceProfile = InvariantDeviceProfile.INSTANCE.get(context);
+
+        // b/175329686 Temporary logic to gracefully migrate group of users to the new 4x5 grid.
+        String gridName = InvariantDeviceProfile.getCurrentGridName(context);
+        if (ENABLE_FOUR_COLUMNS.get()
+                || "reasonable".equals(gridName)
+                || ENABLE_FOUR_COLUMNS.key.equals(gridName)) {
+            // Reset flag and remove it from developer options to prevent it from being enabled
+            // again.
+            ENABLE_FOUR_COLUMNS.reset(context);
+            FeatureFlags.removeFlag(ENABLE_FOUR_COLUMNS);
+
+            // Force migration code to run
+            Utilities.getPrefs(context).edit()
+                    .remove(KEY_MIGRATION_SRC_HOTSEAT_COUNT)
+                    .remove(KEY_MIGRATION_SRC_WORKSPACE_SIZE)
+                    .apply();
+
+            // We make an empty call here to ensure the database is created with the old IDP grid,
+            // so that when we set the new grid the migration can proceeds as expected.
+            LauncherSettings.Settings.call(context.getContentResolver(), "");
+
+            String newGridName = "practical";
+            Utilities.getPrefs(mContext).edit().putString("idp_grid_name", newGridName).commit();
+            mInvariantDeviceProfile.setCurrentGrid(context, "practical");
+        } else {
+            FeatureFlags.removeFlag(ENABLE_FOUR_COLUMNS);
+        }
+
         mIconCache = new IconCache(mContext, mInvariantDeviceProfile, iconCacheFileName);
         mWidgetCache = new WidgetPreviewLoader(mContext, mIconCache);
         mModel = new LauncherModel(context, this, mIconCache, new AppFilter(mContext));
diff --git a/src/com/android/launcher3/LauncherFiles.java b/src/com/android/launcher3/LauncherFiles.java
index 25afb55..6c0daa4 100644
--- a/src/com/android/launcher3/LauncherFiles.java
+++ b/src/com/android/launcher3/LauncherFiles.java
@@ -15,6 +15,7 @@
     private static final String XML = ".xml";
 
     public static final String LAUNCHER_DB = "launcher.db";
+    public static final String LAUNCHER_4_BY_5_DB = "launcher_4_by_5.db";
     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";
@@ -30,6 +31,7 @@
 
     public static final List<String> ALL_FILES = Collections.unmodifiableList(Arrays.asList(
             LAUNCHER_DB,
+            LAUNCHER_4_BY_5_DB,
             LAUNCHER_4_BY_4_DB,
             LAUNCHER_3_BY_3_DB,
             LAUNCHER_2_BY_2_DB,
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 03c802a..c7f0133 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -187,7 +187,7 @@
             "EXPANDED_SMARTSPACE", false, "Expands smartspace height to two rows. "
               + "Any apps occupying the first row will be removed from workspace.");
 
-    public static final BooleanFlag ENABLE_FOUR_COLUMNS = new DeviceFlag(
+    public static final DeviceFlag ENABLE_FOUR_COLUMNS = new DeviceFlag(
             "ENABLE_FOUR_COLUMNS", false, "Uses 4 columns in launcher grid."
             + "Warning: This will permanently alter your home screen items and is not reversible.");
 
@@ -227,6 +227,12 @@
         }
     }
 
+    public static void removeFlag(DebugFlag flag) {
+        synchronized (sDebugFlags) {
+            sDebugFlags.remove(flag);
+        }
+    }
+
     static List<DebugFlag> getDebugFlags() {
         synchronized (sDebugFlags) {
             return new ArrayList<>(sDebugFlags);
@@ -304,6 +310,15 @@
                     .getBoolean(key, defaultValue);
         }
 
+        /**
+         * Resets value to default value.
+         */
+        public void reset(Context context) {
+            mCurrentValue = defaultValue;
+            context.getSharedPreferences(FLAGS_PREF_NAME, Context.MODE_PRIVATE)
+                    .edit().putBoolean(key, defaultValue).apply();
+        }
+
         @Override
         protected StringBuilder appendProps(StringBuilder src) {
             return super.appendProps(src).append(", mCurrentValue=").append(mCurrentValue);
diff --git a/src/com/android/launcher3/graphics/GridCustomizationsProvider.java b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
index cb42e7a..911f8c3 100644
--- a/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
+++ b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
@@ -90,7 +90,10 @@
                     parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
                 if ((type == XmlPullParser.START_TAG)
                         && GridOption.TAG_NAME.equals(parser.getName())) {
-                    result.add(new GridOption(getContext(), Xml.asAttributeSet(parser)));
+                    GridOption option = new GridOption(getContext(), Xml.asAttributeSet(parser));
+                    if (option.visible) {
+                        result.add(option);
+                    }
                 }
             }
         } catch (IOException | XmlPullParserException e) {