Setup infrastructure (multi-db support) for the new grid migration algorithm

We'll have a db for each grid option and a db for back up / restore.

TODO(pinyaoting): support back up / restore using the new infrastructure, particularly calls to GridBackupTable should use different DBs when the feature flag (NEW_GRID_MIGRATION_ALGORITHM) is on.

Bug: 144052802
Test: N/A

Change-Id: I644a3e70148bd78204a747a337446a3c038f616f
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index b0ab35c..5544240 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3;
 
+import static com.android.launcher3.config.FeatureFlags.MULTI_DB_GRID_MIRATION_ALGO;
 import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
 import static com.android.launcher3.provider.LauncherDbUtils.tableExists;
 import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
@@ -157,6 +158,17 @@
         }
     }
 
+    private synchronized boolean updateCurrentOpenHelper() {
+        final InvariantDeviceProfile idp = InvariantDeviceProfile.INSTANCE.get(getContext());
+        if (TextUtils.equals(idp.dbFile, mOpenHelper.getDatabaseName())) {
+            return false;
+        }
+
+        mOpenHelper.close();
+        mOpenHelper = new DatabaseHelper(getContext());
+        return true;
+    }
+
     @Override
     public Cursor query(Uri uri, String[] projection, String selection,
             String[] selectionArgs, String sortOrder) {
@@ -210,7 +222,7 @@
         addModifiedTime(initialValues);
         final int rowId = dbInsertAndCheck(mOpenHelper, db, args.table, null, initialValues);
         if (rowId < 0) return null;
-        mOpenHelper.onAddOrDeleteOp(db);
+        onAddOrDeleteOp(db);
 
         uri = ContentUris.withAppendedId(uri, rowId);
         reloadLauncherIfExternal();
@@ -268,7 +280,7 @@
                     return 0;
                 }
             }
-            mOpenHelper.onAddOrDeleteOp(db);
+            onAddOrDeleteOp(db);
             t.commit();
         }
 
@@ -294,7 +306,7 @@
                         results[i].count != null && results[i].count > 0;
             }
             if (isAddOrDelete) {
-                mOpenHelper.onAddOrDeleteOp(t.getDb());
+                onAddOrDeleteOp(t.getDb());
             }
 
             t.commit();
@@ -316,7 +328,7 @@
         }
         int count = db.delete(args.table, args.where, args.args);
         if (count > 0) {
-            mOpenHelper.onAddOrDeleteOp(db);
+            onAddOrDeleteOp(db);
             reloadLauncherIfExternal();
         }
         return count;
@@ -360,12 +372,14 @@
             }
             case LauncherSettings.Settings.METHOD_NEW_ITEM_ID: {
                 Bundle result = new Bundle();
-                result.putInt(LauncherSettings.Settings.EXTRA_VALUE, mOpenHelper.generateNewItemId());
+                result.putInt(LauncherSettings.Settings.EXTRA_VALUE,
+                        mOpenHelper.generateNewItemId());
                 return result;
             }
             case LauncherSettings.Settings.METHOD_NEW_SCREEN_ID: {
                 Bundle result = new Bundle();
-                result.putInt(LauncherSettings.Settings.EXTRA_VALUE, mOpenHelper.generateNewScreenId());
+                result.putInt(LauncherSettings.Settings.EXTRA_VALUE,
+                        mOpenHelper.generateNewScreenId());
                 return result;
             }
             case LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB: {
@@ -387,8 +401,12 @@
                 return result;
             }
             case LauncherSettings.Settings.METHOD_REFRESH_BACKUP_TABLE: {
-                mOpenHelper.mBackupTableExists =
-                        tableExists(mOpenHelper.getReadableDatabase(), Favorites.BACKUP_TABLE_NAME);
+                // TODO(pinyaoting): Update the behavior here.
+                if (!MULTI_DB_GRID_MIRATION_ALGO.get()) {
+                    mOpenHelper.mBackupTableExists =
+                            tableExists(mOpenHelper.getReadableDatabase(),
+                                    Favorites.BACKUP_TABLE_NAME);
+                }
                 return null;
             }
             case LauncherSettings.Settings.METHOD_RESTORE_BACKUP_TABLE: {
@@ -399,10 +417,26 @@
                         TOKEN_RESTORE_BACKUP_TABLE, RESTORE_BACKUP_TABLE_DELAY);
                 return null;
             }
+            case LauncherSettings.Settings.METHOD_UPDATE_CURRENT_OPEN_HELPER: {
+                if (MULTI_DB_GRID_MIRATION_ALGO.get()) {
+                    Bundle result = new Bundle();
+                    result.putBoolean(LauncherSettings.Settings.EXTRA_VALUE,
+                            updateCurrentOpenHelper());
+                    return result;
+                }
+            }
         }
         return null;
     }
 
+    private void onAddOrDeleteOp(SQLiteDatabase db) {
+        if (MULTI_DB_GRID_MIRATION_ALGO.get()) {
+            // TODO(pingyaoting): Implement the behavior here.
+        } else {
+            mOpenHelper.onAddOrDeleteOp(db);
+        }
+    }
+
     /**
      * Deletes any empty folder from the DB.
      * @return Ids of deleted folders.
@@ -551,14 +585,16 @@
     /**
      * The class is subclassed in tests to create an in-memory db.
      */
-    public static class DatabaseHelper extends NoLocaleSQLiteHelper implements LayoutParserCallback {
+    public static class DatabaseHelper extends NoLocaleSQLiteHelper implements
+            LayoutParserCallback {
         private final Context mContext;
         private int mMaxItemId = -1;
         private int mMaxScreenId = -1;
         private boolean mBackupTableExists;
 
         DatabaseHelper(Context context) {
-            this(context, LauncherFiles.LAUNCHER_DB);
+            this(context, MULTI_DB_GRID_MIRATION_ALGO.get() ? InvariantDeviceProfile.INSTANCE.get(
+                    context).dbFile : LauncherFiles.LAUNCHER_DB);
             // Table creation sometimes fails silently, which leads to a crash loop.
             // This way, we will try to create a table every time after crash, so the device
             // would eventually be able to recover.
@@ -567,7 +603,10 @@
                 // This operation is a no-op if the table already exists.
                 addFavoritesTable(getWritableDatabase(), true);
             }
-            mBackupTableExists = tableExists(getReadableDatabase(), Favorites.BACKUP_TABLE_NAME);
+            if (!MULTI_DB_GRID_MIRATION_ALGO.get()) {
+                mBackupTableExists = tableExists(getReadableDatabase(),
+                        Favorites.BACKUP_TABLE_NAME);
+            }
 
             initIds();
         }
@@ -575,8 +614,8 @@
         /**
          * Constructor used in tests and for restore.
          */
-        public DatabaseHelper(Context context, String tableName) {
-            super(context, tableName, SCHEMA_VERSION);
+        public DatabaseHelper(Context context, String dbName) {
+            super(context, dbName, SCHEMA_VERSION);
             mContext = context;
         }
 
@@ -606,7 +645,7 @@
         }
 
         protected void onAddOrDeleteOp(SQLiteDatabase db) {
-            if (mBackupTableExists) {
+            if (!MULTI_DB_GRID_MIRATION_ALGO.get() && mBackupTableExists) {
                 dropTable(db, Favorites.BACKUP_TABLE_NAME);
                 mBackupTableExists = false;
             }