diff --git a/robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.java b/robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.java
new file mode 100644
index 0000000..8f58d8b
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2020 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.model;
+
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
+import static com.android.launcher3.LauncherSettings.Favorites.TMP_CONTENT_URI;
+import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
+import static com.android.launcher3.util.LauncherModelHelper.APP_ICON;
+import static com.android.launcher3.util.LauncherModelHelper.DESKTOP;
+import static com.android.launcher3.util.LauncherModelHelper.HOTSEAT;
+import static com.android.launcher3.util.LauncherModelHelper.SHORTCUT;
+import static com.android.launcher3.util.LauncherModelHelper.TEST_PACKAGE;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.graphics.Point;
+import android.os.Process;
+
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.pm.UserCache;
+import com.android.launcher3.util.LauncherModelHelper;
+import com.android.launcher3.util.LauncherRoboTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.HashSet;
+
+/** Unit tests for {@link GridSizeMigrationTaskV2} */
+@RunWith(LauncherRoboTestRunner.class)
+public class GridSizeMigrationTaskV2Test {
+
+    private LauncherModelHelper mModelHelper;
+    private Context mContext;
+    private SQLiteDatabase mDb;
+
+    private HashSet<String> mValidPackages;
+    private InvariantDeviceProfile mIdp;
+
+    @Before
+    public void setUp() {
+        mModelHelper = new LauncherModelHelper();
+        mContext = RuntimeEnvironment.application;
+        mDb = mModelHelper.provider.getDb();
+
+        mValidPackages = new HashSet<>();
+        mValidPackages.add(TEST_PACKAGE);
+        mIdp = InvariantDeviceProfile.INSTANCE.get(mContext);
+
+        long userSerial = UserCache.INSTANCE.get(mContext).getSerialNumberForUser(
+                Process.myUserHandle());
+        dropTable(mDb, LauncherSettings.Favorites.TMP_TABLE);
+        LauncherSettings.Favorites.addTableToDb(mDb, userSerial, false,
+                LauncherSettings.Favorites.TMP_TABLE);
+    }
+
+    @Test
+    public void testMigration() {
+        final String testPackage1 = "com.android.launcher3.validpackage1";
+        final String testPackage2 = "com.android.launcher3.validpackage2";
+        final String testPackage3 = "com.android.launcher3.validpackage3";
+        final String testPackage4 = "com.android.launcher3.validpackage4";
+        final String testPackage5 = "com.android.launcher3.validpackage5";
+        final String testPackage7 = "com.android.launcher3.validpackage7";
+
+        mValidPackages.add(testPackage1);
+        mValidPackages.add(testPackage2);
+        mValidPackages.add(testPackage3);
+        mValidPackages.add(testPackage4);
+        mValidPackages.add(testPackage5);
+        mValidPackages.add(testPackage7);
+
+        int[] srcHotseatItems = {
+                mModelHelper.addItem(APP_ICON, 0, HOTSEAT, 0, 0, testPackage1, 1, TMP_CONTENT_URI),
+                mModelHelper.addItem(SHORTCUT, 1, HOTSEAT, 0, 0, testPackage2, 2, TMP_CONTENT_URI),
+                -1,
+                mModelHelper.addItem(SHORTCUT, 3, HOTSEAT, 0, 0, testPackage3, 3, TMP_CONTENT_URI),
+                mModelHelper.addItem(APP_ICON, 4, HOTSEAT, 0, 0, testPackage4, 4, TMP_CONTENT_URI),
+        };
+        mModelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 2, testPackage5, 5, TMP_CONTENT_URI);
+
+        int[] destHotseatItems = {
+                -1,
+                mModelHelper.addItem(SHORTCUT, 1, HOTSEAT, 0, 0, testPackage2),
+                -1,
+        };
+        mModelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 2, testPackage7);
+
+        mIdp.numHotseatIcons = 3;
+        mIdp.numColumns = 3;
+        mIdp.numRows = 3;
+        GridSizeMigrationTaskV2.DbReader srcReader = new GridSizeMigrationTaskV2.DbReader(mDb,
+                LauncherSettings.Favorites.TMP_TABLE, mContext, mValidPackages, 5);
+        GridSizeMigrationTaskV2.DbReader destReader = new GridSizeMigrationTaskV2.DbReader(mDb,
+                LauncherSettings.Favorites.TABLE_NAME, mContext, mValidPackages, 3);
+        GridSizeMigrationTaskV2 task = new GridSizeMigrationTaskV2(mContext, mDb, srcReader,
+                destReader, 3, new Point(mIdp.numColumns, mIdp.numRows));
+        task.migrate();
+
+        Cursor c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
+                new String[]{LauncherSettings.Favorites.SCREEN, LauncherSettings.Favorites.INTENT},
+                "container=" + CONTAINER_HOTSEAT, null, null, null);
+        assertEquals(c.getCount(), 3);
+        int screenIndex = c.getColumnIndex(LauncherSettings.Favorites.SCREEN);
+        int intentIndex = c.getColumnIndex(LauncherSettings.Favorites.INTENT);
+        c.moveToNext();
+        assertEquals(c.getInt(screenIndex), 1);
+        assertTrue(c.getString(intentIndex).contains(testPackage2));
+        c.moveToNext();
+        assertEquals(c.getInt(screenIndex), 0);
+        assertTrue(c.getString(intentIndex).contains(testPackage1));
+        c.moveToNext();
+        assertEquals(c.getInt(screenIndex), 2);
+        assertTrue(c.getString(intentIndex).contains(testPackage3));
+        c.close();
+
+        c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
+                new String[]{LauncherSettings.Favorites.CELLX, LauncherSettings.Favorites.CELLY,
+                        LauncherSettings.Favorites.INTENT},
+                "container=" + CONTAINER_DESKTOP, null, null, null);
+        assertEquals(c.getCount(), 2);
+        intentIndex = c.getColumnIndex(LauncherSettings.Favorites.INTENT);
+        int cellXIndex = c.getColumnIndex(LauncherSettings.Favorites.CELLX);
+        int cellYIndex = c.getColumnIndex(LauncherSettings.Favorites.CELLY);
+
+        c.moveToNext();
+        assertTrue(c.getString(intentIndex).contains(testPackage7));
+        c.moveToNext();
+        assertTrue(c.getString(intentIndex).contains(testPackage5));
+        assertEquals(c.getInt(cellXIndex), 0);
+        assertEquals(c.getInt(cellYIndex), 2);
+    }
+}
diff --git a/robolectric_tests/src/com/android/launcher3/util/LauncherModelHelper.java b/robolectric_tests/src/com/android/launcher3/util/LauncherModelHelper.java
index e133cf2..20b1453 100644
--- a/robolectric_tests/src/com/android/launcher3/util/LauncherModelHelper.java
+++ b/robolectric_tests/src/com/android/launcher3/util/LauncherModelHelper.java
@@ -230,7 +230,21 @@
     }
 
     public int addItem(int type, int screen, int container, int x, int y) {
-        return addItem(type, screen, container, x, y, mDefaultProfileId);
+        return addItem(type, screen, container, x, y, mDefaultProfileId, TEST_PACKAGE);
+    }
+
+    public int addItem(int type, int screen, int container, int x, int y, long profileId) {
+        return addItem(type, screen, container, x, y, profileId, TEST_PACKAGE);
+    }
+
+    public int addItem(int type, int screen, int container, int x, int y, String packageName) {
+        return addItem(type, screen, container, x, y, mDefaultProfileId, packageName);
+    }
+
+    public int addItem(int type, int screen, int container, int x, int y, String packageName,
+            int id, Uri contentUri) {
+        addItem(type, screen, container, x, y, mDefaultProfileId, packageName, id, contentUri);
+        return id;
     }
 
     /**
@@ -238,11 +252,19 @@
      * @param type {@link #APP_ICON} or {@link #SHORTCUT} or >= 2 for
      *             folder (where the type represents the number of items in the folder).
      */
-    public int addItem(int type, int screen, int container, int x, int y, long profileId) {
+    public int addItem(int type, int screen, int container, int x, int y, long profileId,
+            String packageName) {
         Context context = RuntimeEnvironment.application;
         int id = LauncherSettings.Settings.call(context.getContentResolver(),
                 LauncherSettings.Settings.METHOD_NEW_ITEM_ID)
                 .getInt(LauncherSettings.Settings.EXTRA_VALUE);
+        addItem(type, screen, container, x, y, profileId, packageName, id, CONTENT_URI);
+        return id;
+    }
+
+    public void addItem(int type, int screen, int container, int x, int y, long profileId,
+            String packageName, int id, Uri contentUri) {
+        Context context = RuntimeEnvironment.application;
 
         ContentValues values = new ContentValues();
         values.put(LauncherSettings.Favorites._ID, id);
@@ -257,7 +279,7 @@
         if (type == APP_ICON || type == SHORTCUT) {
             values.put(LauncherSettings.Favorites.ITEM_TYPE, type);
             values.put(LauncherSettings.Favorites.INTENT,
-                    new Intent(Intent.ACTION_MAIN).setPackage(TEST_PACKAGE).toUri(0));
+                    new Intent(Intent.ACTION_MAIN).setPackage(packageName).toUri(0));
         } else {
             values.put(LauncherSettings.Favorites.ITEM_TYPE,
                     LauncherSettings.Favorites.ITEM_TYPE_FOLDER);
@@ -267,8 +289,7 @@
             }
         }
 
-        context.getContentResolver().insert(CONTENT_URI, values);
-        return id;
+        context.getContentResolver().insert(contentUri, values);
     }
 
     public int[][][] createGrid(int[][][] typeArray) {
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 697048a..a699c32 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -17,6 +17,7 @@
 package com.android.launcher3;
 
 import static com.android.launcher3.config.FeatureFlags.MULTI_DB_GRID_MIRATION_ALGO;
+import static com.android.launcher3.provider.LauncherDbUtils.copyTable;
 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;
@@ -164,8 +165,11 @@
             return false;
         }
 
-        mOpenHelper.close();
+        DatabaseHelper oldHelper = mOpenHelper;
         mOpenHelper = new DatabaseHelper(getContext());
+        copyTable(oldHelper.getReadableDatabase(), Favorites.TABLE_NAME,
+                mOpenHelper.getWritableDatabase(), Favorites.TMP_TABLE, getContext());
+        oldHelper.close();
         return true;
     }
 
diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java
index 216c221..f516446 100644
--- a/src/com/android/launcher3/LauncherSettings.java
+++ b/src/com/android/launcher3/LauncherSettings.java
@@ -103,6 +103,11 @@
         public static final String PREVIEW_TABLE_NAME = "favorites_preview";
 
         /**
+         * Temporary table used specifically for multi-db grid migrations
+         */
+        public static final String TMP_TABLE = "favorites_tmp";
+
+        /**
          * The content:// style URL for "favorites" table
          */
         public static final Uri CONTENT_URI = Uri.parse("content://"
@@ -115,6 +120,12 @@
                 + LauncherProvider.AUTHORITY + "/" + PREVIEW_TABLE_NAME);
 
         /**
+         * The content:// style URL for "favorites_tmp" table
+         */
+        public static final Uri TMP_CONTENT_URI = Uri.parse("content://"
+                + LauncherProvider.AUTHORITY + "/" + TMP_TABLE);
+
+        /**
          * The content:// style URL for a given row, identified by its id.
          *
          * @param id The row id.
diff --git a/src/com/android/launcher3/model/GridSizeMigrationTask.java b/src/com/android/launcher3/model/GridSizeMigrationTask.java
index 3ba740d..a084600 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationTask.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationTask.java
@@ -936,8 +936,8 @@
 
             boolean dbChanged = false;
             if (migrateForPreview) {
-                copyTable(transaction.getDb(), Favorites.TABLE_NAME, Favorites.PREVIEW_TABLE_NAME,
-                        context);
+                copyTable(transaction.getDb(), Favorites.TABLE_NAME, transaction.getDb(),
+                        Favorites.PREVIEW_TABLE_NAME, context);
             }
 
             GridBackupTable backupTable = new GridBackupTable(context, transaction.getDb(),
@@ -950,10 +950,11 @@
 
             HashSet<String> validPackages = getValidPackages(context);
             // Hotseat.
-            if (srcHotseatCount != idp.numHotseatIcons) {
-                // Migrate hotseat.
-                dbChanged = new GridSizeMigrationTask(context, transaction.getDb(), validPackages,
-                        migrateForPreview, srcHotseatCount, idp.numHotseatIcons).migrateHotseat();
+            if (srcHotseatCount != idp.numHotseatIcons
+                    && new GridSizeMigrationTask(context, transaction.getDb(), validPackages,
+                            migrateForPreview, srcHotseatCount,
+                            idp.numHotseatIcons).migrateHotseat()) {
+                dbChanged = true;
             }
 
             // Grid size
diff --git a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
index 197b29c..0bdccfa 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
@@ -16,9 +16,46 @@
 
 package com.android.launcher3.model;
 
+import static com.android.launcher3.Utilities.getPointString;
+import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
+
+import android.content.ComponentName;
+import android.content.ContentValues;
 import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.database.sqlite.SQLiteDatabase;
+import android.graphics.Point;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
 
 import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.ItemInfo;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherAppWidgetProviderInfo;
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.graphics.LauncherPreviewRenderer;
+import com.android.launcher3.pm.InstallSessionHelper;
+import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
+import com.android.launcher3.util.GridOccupancy;
+import com.android.launcher3.util.IntArray;
+import com.android.launcher3.widget.WidgetManagerHelper;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * This class takes care of shrinking the workspace (by maximum of one row and one column), as a
@@ -26,14 +63,63 @@
  */
 public class GridSizeMigrationTaskV2 {
 
-    private GridSizeMigrationTaskV2(Context context) {
+    public static final String KEY_MIGRATION_SRC_WORKSPACE_SIZE = "migration_src_workspace_size";
+    public static final String KEY_MIGRATION_SRC_HOTSEAT_COUNT = "migration_src_hotseat_count";
 
+    private static final String TAG = "GridSizeMigrationTaskV2";
+    private static final boolean DEBUG = true;
+
+    private final Context mContext;
+    private final SQLiteDatabase mDb;
+    private final DbReader mSrcReader;
+    private final DbReader mDestReader;
+
+    private final List<DbEntry> mHotseatItems;
+    private final List<DbEntry> mWorkspaceItems;
+
+    private final List<DbEntry> mHotseatDiff;
+    private final List<DbEntry> mWorkspaceDiff;
+
+    private final int mDestHotseatSize;
+    private final int mTrgX, mTrgY;
+
+    @VisibleForTesting
+    protected GridSizeMigrationTaskV2(Context context, SQLiteDatabase db, DbReader srcReader,
+            DbReader destReader, int destHotseatSize, Point targetSize) {
+        mContext = context;
+        mDb = db;
+        mSrcReader = srcReader;
+        mDestReader = destReader;
+
+        mHotseatItems = destReader.loadHotseatEntries();
+        mWorkspaceItems = destReader.loadAllWorkspaceEntries();
+
+        mHotseatDiff = calcDiff(mSrcReader.loadHotseatEntries(), mHotseatItems);
+        mWorkspaceDiff = calcDiff(mSrcReader.loadAllWorkspaceEntries(), mWorkspaceItems);
+        mDestHotseatSize = destHotseatSize;
+
+        mTrgX = targetSize.x;
+        mTrgY = targetSize.y;
+    }
+
+    /**
+     * Check given a new IDP, if migration is necessary.
+     */
+    public static boolean needsToMigrate(Context context, InvariantDeviceProfile idp) {
+        SharedPreferences prefs = Utilities.getPrefs(context);
+        String gridSizeString = getPointString(idp.numColumns, idp.numRows);
+
+        return !gridSizeString.equals(prefs.getString(KEY_MIGRATION_SRC_WORKSPACE_SIZE, ""))
+                || idp.numHotseatIcons != prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT,
+                idp.numHotseatIcons);
     }
 
     /** See {@link #migrateGridIfNeeded(Context, InvariantDeviceProfile)} */
     public static boolean migrateGridIfNeeded(Context context) {
-        // To be implemented.
-        return true;
+        if (context instanceof LauncherPreviewRenderer.PreviewContext) {
+            return true;
+        }
+        return migrateGridIfNeeded(context, null);
     }
 
     /**
@@ -43,7 +129,608 @@
      * @return false if the migration failed.
      */
     public static boolean migrateGridIfNeeded(Context context, InvariantDeviceProfile idp) {
-        // To be implemented.
+        boolean migrateForPreview = idp != null;
+        if (!migrateForPreview) {
+            idp = LauncherAppState.getIDP(context);
+        }
+
+        if (!needsToMigrate(context, idp)) {
+            return true;
+        }
+
+        SharedPreferences prefs = Utilities.getPrefs(context);
+        String gridSizeString = getPointString(idp.numColumns, idp.numRows);
+
+        if (gridSizeString.equals(prefs.getString(KEY_MIGRATION_SRC_WORKSPACE_SIZE, ""))
+                && idp.numHotseatIcons == prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT,
+                idp.numHotseatIcons)) {
+            // Skip if workspace and hotseat sizes have not changed.
+            return true;
+        }
+
+        HashSet<String> validPackages = getValidPackages(context);
+        int srcHotseatCount = prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, idp.numHotseatIcons);
+
+        if (!LauncherSettings.Settings.call(
+                context.getContentResolver(),
+                LauncherSettings.Settings.METHOD_UPDATE_CURRENT_OPEN_HELPER).getBoolean(
+                LauncherSettings.Settings.EXTRA_VALUE)) {
+            return false;
+        }
+
+        long migrationStartTime = System.currentTimeMillis();
+        try (SQLiteTransaction t = (SQLiteTransaction) LauncherSettings.Settings.call(
+                context.getContentResolver(),
+                LauncherSettings.Settings.METHOD_NEW_TRANSACTION).getBinder(
+                LauncherSettings.Settings.EXTRA_VALUE)) {
+
+            DbReader srcReader = new DbReader(t.getDb(), LauncherSettings.Favorites.TMP_TABLE,
+                    context, validPackages, srcHotseatCount);
+            DbReader destReader = new DbReader(t.getDb(), LauncherSettings.Favorites.TABLE_NAME,
+                    context, validPackages, idp.numHotseatIcons);
+
+            Point targetSize = new Point(idp.numColumns, idp.numRows);
+            GridSizeMigrationTaskV2 task = new GridSizeMigrationTaskV2(context, t.getDb(),
+                    srcReader, destReader, idp.numHotseatIcons, targetSize);
+            task.migrate();
+
+            dropTable(t.getDb(), LauncherSettings.Favorites.TMP_TABLE);
+
+            t.commit();
+            return true;
+        } catch (Exception e) {
+            Log.e(TAG, "Error during grid migration", e);
+
+            return false;
+        } finally {
+            Log.v(TAG, "Workspace migration completed in "
+                    + (System.currentTimeMillis() - migrationStartTime));
+
+            // Save current configuration, so that the migration does not run again.
+            prefs.edit()
+                    .putString(KEY_MIGRATION_SRC_WORKSPACE_SIZE, gridSizeString)
+                    .putInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, idp.numHotseatIcons)
+                    .apply();
+        }
+    }
+
+    @VisibleForTesting
+    protected boolean migrate() {
+        if (mHotseatDiff.isEmpty() && mWorkspaceDiff.isEmpty()) {
+            return false;
+        }
+
+        // Migrate hotseat
+        HotseatPlacementSolution hotseatSolution = new HotseatPlacementSolution(mDb, mSrcReader,
+                mContext, mDestHotseatSize, mHotseatItems, mHotseatDiff);
+        hotseatSolution.find();
+
+        // Sort the items by the reading order.
+        Collections.sort(mWorkspaceDiff);
+
+        // Migrate workspace.
+        for (int screenId = 0; screenId <= mDestReader.mLastScreenId; screenId++) {
+            if (DEBUG) {
+                Log.d(TAG, "Migrating " + screenId);
+            }
+            List<DbEntry> entries = mDestReader.loadWorkspaceEntries(screenId);
+            GridPlacementSolution workspaceSolution = new GridPlacementSolution(mDb, mSrcReader,
+                    mContext, entries, screenId, mTrgX, mTrgY, mWorkspaceDiff);
+            workspaceSolution.find();
+            if (mWorkspaceDiff.isEmpty()) {
+                break;
+            }
+        }
+
+        int screenId = mDestReader.mLastScreenId + 1;
+        while (!mWorkspaceDiff.isEmpty()) {
+            GridPlacementSolution workspaceSolution = new GridPlacementSolution(mDb, mSrcReader,
+                    mContext, new ArrayList<>(), screenId, mTrgX, mTrgY, mWorkspaceDiff);
+            workspaceSolution.find();
+            screenId++;
+        }
         return true;
     }
+
+    /** Return what's in the src but not in the dest */
+    private static List<DbEntry> calcDiff(List<DbEntry> src, List<DbEntry> dest) {
+        Set<String> destSet = dest.parallelStream().map(DbEntry::getIntentStr).collect(
+                Collectors.toSet());
+        List<DbEntry> diff = new ArrayList<>();
+        for (DbEntry entry : src) {
+            if (!destSet.contains(entry.mIntent)) {
+                diff.add(entry);
+            }
+        }
+        return diff;
+    }
+
+    private static void insertEntryInDb(SQLiteDatabase db, Context context,
+            ArrayList<DbEntry> entriesFromSrcDb, DbEntry entry) {
+        int id = -1;
+        switch (entry.itemType) {
+            case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
+            case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
+            case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: {
+                for (DbEntry e : entriesFromSrcDb) {
+                    if (TextUtils.equals(e.mIntent, entry.mIntent)) {
+                        id = e.id;
+                    }
+                }
+
+                break;
+            }
+            case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: {
+                for (DbEntry e : entriesFromSrcDb) {
+                    if (e.mFolderItems.size() == entry.mFolderItems.size()
+                            && e.mFolderItems.containsAll(entry.mFolderItems)) {
+                        id = e.id;
+                    }
+                }
+                break;
+            }
+            case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
+            case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET: {
+                for (DbEntry e : entriesFromSrcDb) {
+                    if (TextUtils.equals(e.mProvider, entry.mProvider)) {
+                        id = e.id;
+                        break;
+                    }
+                }
+                break;
+            }
+            default:
+                return;
+        }
+
+        Cursor c = db.query(LauncherSettings.Favorites.TMP_TABLE, null,
+                LauncherSettings.Favorites._ID + " = '" + id + "'", null, null, null, null);
+
+        while (c.moveToNext()) {
+            ContentValues values = new ContentValues();
+            DatabaseUtils.cursorRowToContentValues(c, values);
+            entry.updateContentValues(values);
+            values.put(LauncherSettings.Favorites._ID,
+                    LauncherSettings.Settings.call(context.getContentResolver(),
+                            LauncherSettings.Settings.METHOD_NEW_ITEM_ID).getInt(
+                            LauncherSettings.Settings.EXTRA_VALUE));
+            db.insert(LauncherSettings.Favorites.TABLE_NAME, null, values);
+        }
+        c.close();
+    }
+
+    private static void removeEntryFromDb(SQLiteDatabase db, IntArray entryId) {
+        db.delete(LauncherSettings.Favorites.TABLE_NAME, Utilities.createDbSelectionQuery(
+                LauncherSettings.Favorites._ID, entryId), null);
+    }
+
+    private static HashSet<String> getValidPackages(Context context) {
+        // Initialize list of valid packages. This contain all the packages which are already on
+        // the device and packages which are being installed. Any item which doesn't belong to
+        // this set is removed.
+        // Since the loader removes such items anyway, removing these items here doesn't cause
+        // any extra data loss and gives us more free space on the grid for better migration.
+        HashSet<String> validPackages = new HashSet<>();
+        for (PackageInfo info : context.getPackageManager()
+                .getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES)) {
+            validPackages.add(info.packageName);
+        }
+        InstallSessionHelper.INSTANCE.get(context)
+                .getActiveSessions().keySet()
+                .forEach(packageUserKey -> validPackages.add(packageUserKey.mPackageName));
+        return validPackages;
+    }
+
+    protected static class GridPlacementSolution {
+
+        private final SQLiteDatabase mDb;
+        private final DbReader mSrcReader;
+        private final Context mContext;
+        private final GridOccupancy mOccupied;
+        private final int mScreenId;
+        private final int mTrgX;
+        private final int mTrgY;
+        private final List<DbEntry> mItemsToPlace;
+
+        private int mNextStartX;
+        private int mNextStartY;
+
+        GridPlacementSolution(SQLiteDatabase db, DbReader srcReader, Context context,
+                List<DbEntry> placedWorkspaceItems, int screenId, int trgX,
+                int trgY, List<DbEntry> itemsToPlace) {
+            mDb = db;
+            mSrcReader = srcReader;
+            mContext = context;
+            mOccupied = new GridOccupancy(trgX, trgY);
+            mScreenId = screenId;
+            mTrgX = trgX;
+            mTrgY = trgY;
+            mNextStartX = 0;
+            mNextStartY = mTrgY - 1;
+            for (DbEntry entry : placedWorkspaceItems) {
+                mOccupied.markCells(entry, true);
+            }
+            mItemsToPlace = itemsToPlace;
+        }
+
+        public void find() {
+            Iterator<DbEntry> iterator = mItemsToPlace.iterator();
+            while (iterator.hasNext()) {
+                final DbEntry entry = iterator.next();
+                if (entry.minSpanX > mTrgX || entry.minSpanY > mTrgY) {
+                    iterator.remove();
+                    continue;
+                }
+                if (findPlacement(entry)) {
+                    insertEntryInDb(mDb, mContext, mSrcReader.mWorkspaceEntries, entry);
+                    iterator.remove();
+                }
+            }
+        }
+
+        private boolean findPlacement(DbEntry entry) {
+            for (int y = mNextStartY; y >= 0; y--) {
+                for (int x = mNextStartX; x < mTrgX; x++) {
+                    boolean fits = mOccupied.isRegionVacant(x, y, entry.spanX, entry.spanY);
+                    boolean minFits = mOccupied.isRegionVacant(x, y, entry.minSpanX,
+                            entry.minSpanY);
+                    if (minFits) {
+                        entry.spanX = entry.minSpanX;
+                        entry.spanY = entry.minSpanY;
+                    }
+                    if (fits || minFits) {
+                        entry.screenId = mScreenId;
+                        entry.cellX = x;
+                        entry.cellY = y;
+                        mOccupied.markCells(entry, true);
+                        mNextStartX = x + entry.spanX;
+                        mNextStartY = y;
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+    }
+
+    protected static class HotseatPlacementSolution {
+
+        private final SQLiteDatabase mDb;
+        private final DbReader mSrcReader;
+        private final Context mContext;
+        private final HotseatOccupancy mOccupied;
+        private final List<DbEntry> mItemsToPlace;
+
+        HotseatPlacementSolution(SQLiteDatabase db, DbReader srcReader, Context context,
+                int hotseatSize, List<DbEntry> placedHotseatItems, List<DbEntry> itemsToPlace) {
+            mDb = db;
+            mSrcReader = srcReader;
+            mContext = context;
+            mOccupied = new HotseatOccupancy(hotseatSize);
+            for (DbEntry entry : placedHotseatItems) {
+                mOccupied.markCells(entry, true);
+            }
+            mItemsToPlace = itemsToPlace;
+        }
+
+        public void find() {
+            for (int i = 0; i < mOccupied.mCells.length; i++) {
+                if (!mOccupied.mCells[i] && !mItemsToPlace.isEmpty()) {
+                    DbEntry entry = mItemsToPlace.remove(0);
+                    entry.screenId = i;
+                    // These values does not affect the item position, but we should set them
+                    // to something other than -1.
+                    entry.cellX = i;
+                    entry.cellY = 0;
+                    insertEntryInDb(mDb, mContext, mSrcReader.mHotseatEntries, entry);
+                    mOccupied.markCells(entry, true);
+                }
+            }
+        }
+
+        private class HotseatOccupancy {
+
+            private final boolean[] mCells;
+
+            private HotseatOccupancy(int hotseatSize) {
+                mCells = new boolean[hotseatSize];
+            }
+
+            private void markCells(ItemInfo item, boolean value) {
+                mCells[item.screenId] = value;
+            }
+        }
+    }
+
+    protected static class DbReader {
+
+        private final SQLiteDatabase mDb;
+        private final String mTableName;
+        private final Context mContext;
+        private final HashSet<String> mValidPackages;
+        private final int mHotseatSize;
+        private int mLastScreenId = -1;
+
+        private final ArrayList<DbEntry> mHotseatEntries = new ArrayList<>();
+        private final ArrayList<DbEntry> mWorkspaceEntries = new ArrayList<>();
+
+        DbReader(SQLiteDatabase db, String tableName, Context context,
+                HashSet<String> validPackages, int hotseatSize) {
+            mDb = db;
+            mTableName = tableName;
+            mContext = context;
+            mValidPackages = validPackages;
+            mHotseatSize = hotseatSize;
+        }
+
+        protected ArrayList<DbEntry> loadHotseatEntries() {
+            Cursor c = queryWorkspace(
+                    new String[]{
+                            LauncherSettings.Favorites._ID,                  // 0
+                            LauncherSettings.Favorites.ITEM_TYPE,            // 1
+                            LauncherSettings.Favorites.INTENT,               // 2
+                            LauncherSettings.Favorites.SCREEN},              // 3
+                    LauncherSettings.Favorites.CONTAINER + " = "
+                            + LauncherSettings.Favorites.CONTAINER_HOTSEAT);
+
+            final int indexId = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID);
+            final int indexItemType = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
+            final int indexIntent = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
+            final int indexScreen = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
+
+            IntArray entriesToRemove = new IntArray();
+            while (c.moveToNext()) {
+                DbEntry entry = new DbEntry();
+                entry.id = c.getInt(indexId);
+                entry.itemType = c.getInt(indexItemType);
+                entry.screenId = c.getInt(indexScreen);
+
+                if (entry.screenId >= mHotseatSize) {
+                    entriesToRemove.add(entry.id);
+                    continue;
+                }
+
+                try {
+                    // calculate weight
+                    switch (entry.itemType) {
+                        case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
+                        case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
+                        case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: {
+                            entry.mIntent = c.getString(indexIntent);
+                            verifyIntent(c.getString(indexIntent));
+                            break;
+                        }
+                        case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: {
+                            int total = getFolderItemsCount(entry);
+                            if (total == 0) {
+                                throw new Exception("Folder is empty");
+                            }
+                            break;
+                        }
+                        default:
+                            throw new Exception("Invalid item type");
+                    }
+                } catch (Exception e) {
+                    if (DEBUG) {
+                        Log.d(TAG, "Removing item " + entry.id, e);
+                    }
+                    entriesToRemove.add(entry.id);
+                    continue;
+                }
+                mHotseatEntries.add(entry);
+            }
+            removeEntryFromDb(mDb, entriesToRemove);
+            c.close();
+            return mHotseatEntries;
+        }
+
+        protected ArrayList<DbEntry> loadAllWorkspaceEntries() {
+            Cursor c = queryWorkspace(
+                    new String[]{
+                            LauncherSettings.Favorites._ID,                  // 0
+                            LauncherSettings.Favorites.ITEM_TYPE,            // 1
+                            LauncherSettings.Favorites.SCREEN,               // 2
+                            LauncherSettings.Favorites.CELLX,                // 3
+                            LauncherSettings.Favorites.CELLY,                // 4
+                            LauncherSettings.Favorites.SPANX,                // 5
+                            LauncherSettings.Favorites.SPANY,                // 6
+                            LauncherSettings.Favorites.INTENT,               // 7
+                            LauncherSettings.Favorites.APPWIDGET_PROVIDER,   // 8
+                            LauncherSettings.Favorites.APPWIDGET_ID},        // 9
+                        LauncherSettings.Favorites.CONTAINER + " = "
+                            + LauncherSettings.Favorites.CONTAINER_DESKTOP);
+            return loadWorkspaceEntries(c);
+        }
+
+        protected ArrayList<DbEntry> loadWorkspaceEntries(int screen) {
+            Cursor c = queryWorkspace(
+                    new String[]{
+                            LauncherSettings.Favorites._ID,                  // 0
+                            LauncherSettings.Favorites.ITEM_TYPE,            // 1
+                            LauncherSettings.Favorites.SCREEN,               // 2
+                            LauncherSettings.Favorites.CELLX,                // 3
+                            LauncherSettings.Favorites.CELLY,                // 4
+                            LauncherSettings.Favorites.SPANX,                // 5
+                            LauncherSettings.Favorites.SPANY,                // 6
+                            LauncherSettings.Favorites.INTENT,               // 7
+                            LauncherSettings.Favorites.APPWIDGET_PROVIDER,   // 8
+                            LauncherSettings.Favorites.APPWIDGET_ID},        // 9
+                    LauncherSettings.Favorites.CONTAINER + " = "
+                            + LauncherSettings.Favorites.CONTAINER_DESKTOP
+                            + " AND " + LauncherSettings.Favorites.SCREEN + " = " + screen);
+            return loadWorkspaceEntries(c);
+        }
+
+        private ArrayList<DbEntry> loadWorkspaceEntries(Cursor c) {
+            final int indexId = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID);
+            final int indexItemType = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
+            final int indexScreen = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
+            final int indexCellX = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
+            final int indexCellY = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
+            final int indexSpanX = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANX);
+            final int indexSpanY = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANY);
+            final int indexIntent = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
+            final int indexAppWidgetProvider = c.getColumnIndexOrThrow(
+                    LauncherSettings.Favorites.APPWIDGET_PROVIDER);
+            final int indexAppWidgetId = c.getColumnIndexOrThrow(
+                    LauncherSettings.Favorites.APPWIDGET_ID);
+
+            IntArray entriesToRemove = new IntArray();
+            WidgetManagerHelper widgetManagerHelper = new WidgetManagerHelper(mContext);
+            while (c.moveToNext()) {
+                DbEntry entry = new DbEntry();
+                entry.id = c.getInt(indexId);
+                entry.itemType = c.getInt(indexItemType);
+                entry.screenId = c.getInt(indexScreen);
+                mLastScreenId = Math.max(mLastScreenId, entry.screenId);
+                entry.cellX = c.getInt(indexCellX);
+                entry.cellY = c.getInt(indexCellY);
+                entry.spanX = c.getInt(indexSpanX);
+                entry.spanY = c.getInt(indexSpanY);
+
+                try {
+                    // calculate weight
+                    switch (entry.itemType) {
+                        case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
+                        case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
+                        case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: {
+                            entry.mIntent = c.getString(indexIntent);
+                            verifyIntent(entry.mIntent);
+                            break;
+                        }
+                        case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: {
+                            entry.mProvider = c.getString(indexAppWidgetProvider);
+                            ComponentName cn = ComponentName.unflattenFromString(entry.mProvider);
+                            verifyPackage(cn.getPackageName());
+
+                            int widgetId = c.getInt(indexAppWidgetId);
+                            LauncherAppWidgetProviderInfo pInfo =
+                                    widgetManagerHelper.getLauncherAppWidgetInfo(widgetId);
+                            Point spans = null;
+                            if (pInfo != null) {
+                                spans = pInfo.getMinSpans();
+                            }
+                            if (spans != null) {
+                                entry.minSpanX = spans.x > 0 ? spans.x : entry.spanX;
+                                entry.minSpanY = spans.y > 0 ? spans.y : entry.spanY;
+                            } else {
+                                // Assume that the widget be resized down to 2x2
+                                entry.minSpanX = entry.minSpanY = 2;
+                            }
+
+                            break;
+                        }
+                        case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: {
+                            int total = getFolderItemsCount(entry);
+                            if (total == 0) {
+                                throw new Exception("Folder is empty");
+                            }
+                            break;
+                        }
+                        default:
+                            throw new Exception("Invalid item type");
+                    }
+                } catch (Exception e) {
+                    if (DEBUG) {
+                        Log.d(TAG, "Removing item " + entry.id, e);
+                    }
+                    entriesToRemove.add(entry.id);
+                    continue;
+                }
+                mWorkspaceEntries.add(entry);
+            }
+            removeEntryFromDb(mDb, entriesToRemove);
+            c.close();
+            return mWorkspaceEntries;
+        }
+
+        private int getFolderItemsCount(DbEntry entry) {
+            Cursor c = queryWorkspace(
+                    new String[]{LauncherSettings.Favorites._ID, LauncherSettings.Favorites.INTENT},
+                    LauncherSettings.Favorites.CONTAINER + " = " + entry.id);
+
+            int total = 0;
+            while (c.moveToNext()) {
+                try {
+                    String intent = c.getString(1);
+                    verifyIntent(intent);
+                    total++;
+                    entry.mFolderItems.add(intent);
+                } catch (Exception e) {
+                    removeEntryFromDb(mDb, IntArray.wrap(c.getInt(0)));
+                }
+            }
+            c.close();
+            return total;
+        }
+
+        private Cursor queryWorkspace(String[] columns, String where) {
+            return mDb.query(mTableName, columns, where, null, null, null, null);
+        }
+
+        /** Verifies if the mIntent should be restored. */
+        private void verifyIntent(String intentStr)
+                throws Exception {
+            Intent intent = Intent.parseUri(intentStr, 0);
+            if (intent.getComponent() != null) {
+                verifyPackage(intent.getComponent().getPackageName());
+            } else if (intent.getPackage() != null) {
+                // Only verify package if the component was null.
+                verifyPackage(intent.getPackage());
+            }
+        }
+
+        /** Verifies if the package should be restored */
+        private void verifyPackage(String packageName)
+                throws Exception {
+            if (!mValidPackages.contains(packageName)) {
+                // TODO(b/151468819): Handle promise app icon restoration during grid migration.
+                throw new Exception("Package not available");
+            }
+        }
+    }
+
+    protected static class DbEntry extends ItemInfo implements Comparable<DbEntry> {
+
+        private String mIntent;
+        private String mProvider;
+        private Set<String> mFolderItems = new HashSet<>();
+
+        /** Comparator according to the reading order */
+        @Override
+        public int compareTo(DbEntry another) {
+            if (screenId != another.screenId) {
+                return Integer.compare(screenId, another.screenId);
+            }
+            if (cellY != another.cellY) {
+                return -Integer.compare(cellY, another.cellY);
+            }
+            return Integer.compare(cellX, another.cellX);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            DbEntry entry = (DbEntry) o;
+            return Objects.equals(mIntent, entry.mIntent);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mIntent);
+        }
+
+        public void updateContentValues(ContentValues values) {
+            values.put(LauncherSettings.Favorites.SCREEN, screenId);
+            values.put(LauncherSettings.Favorites.CELLX, cellX);
+            values.put(LauncherSettings.Favorites.CELLY, cellY);
+            values.put(LauncherSettings.Favorites.SPANX, spanX);
+            values.put(LauncherSettings.Favorites.SPANY, spanY);
+        }
+
+        public String getIntentStr() {
+            return mIntent;
+        }
+    }
 }
diff --git a/src/com/android/launcher3/provider/LauncherDbUtils.java b/src/com/android/launcher3/provider/LauncherDbUtils.java
index f7ecc3f..dacea84 100644
--- a/src/com/android/launcher3/provider/LauncherDbUtils.java
+++ b/src/com/android/launcher3/provider/LauncherDbUtils.java
@@ -118,13 +118,20 @@
         db.execSQL("DROP TABLE IF EXISTS " + tableName);
     }
 
-    /** Copy from table to the to table. */
-    public static void copyTable(SQLiteDatabase db, String from, String to, Context context) {
+    /** Copy fromTable in fromDb to toTable in toDb. */
+    public static void copyTable(SQLiteDatabase fromDb, String fromTable, SQLiteDatabase toDb,
+            String toTable, Context context) {
         long userSerial = UserCache.INSTANCE.get(context).getSerialNumberForUser(
                 Process.myUserHandle());
-        dropTable(db, to);
-        Favorites.addTableToDb(db, userSerial, false, to);
-        db.execSQL("INSERT INTO " + to + " SELECT * FROM " + from);
+        dropTable(toDb, toTable);
+        Favorites.addTableToDb(toDb, userSerial, false, toTable);
+        if (fromDb != toDb) {
+            toDb.execSQL("ATTACH DATABASE '" + fromDb.getPath() + "' AS from_db");
+            toDb.execSQL(
+                    "INSERT INTO " + toTable + " SELECT * FROM from_db." + fromTable);
+        } else {
+            toDb.execSQL("INSERT INTO " + toTable + " SELECT * FROM " + fromTable);
+        }
     }
 
     /**
