Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 43ef145a authored by Tracy Zhou's avatar Tracy Zhou Committed by Android (Google) Code Review
Browse files

Merge "Support grid preview with v2 migration algorithm" into ub-launcher3-master

parents 88a9946b c0000450
Loading
Loading
Loading
Loading
+43 −18
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;
import java.util.function.Supplier;

public class LauncherProvider extends ContentProvider {
    private static final String TAG = "LauncherProvider";
@@ -145,7 +146,7 @@ public class LauncherProvider extends ContentProvider {
     */
    protected synchronized void createDbIfNotExists() {
        if (mOpenHelper == null) {
            mOpenHelper = new DatabaseHelper(getContext());
            mOpenHelper = DatabaseHelper.createDatabaseHelper(getContext());

            if (RestoreDbTask.isPending(getContext())) {
                if (!RestoreDbTask.performRestore(getContext(), mOpenHelper,
@@ -159,17 +160,17 @@ public class LauncherProvider extends ContentProvider {
        }
    }

    private synchronized boolean updateCurrentOpenHelper() {
        final InvariantDeviceProfile idp = InvariantDeviceProfile.INSTANCE.get(getContext());
        if (TextUtils.equals(idp.dbFile, mOpenHelper.getDatabaseName())) {
    private synchronized boolean prepForMigration(String dbFile, String targetTableName,
            Supplier<DatabaseHelper> src, Supplier<DatabaseHelper> dst) {
        if (TextUtils.equals(dbFile, mOpenHelper.getDatabaseName())) {
            return false;
        }

        DatabaseHelper oldHelper = mOpenHelper;
        mOpenHelper = new DatabaseHelper(getContext());
        copyTable(oldHelper.getReadableDatabase(), Favorites.TABLE_NAME,
                mOpenHelper.getWritableDatabase(), Favorites.TMP_TABLE, getContext());
        oldHelper.close();
        final DatabaseHelper helper = src.get();
        mOpenHelper = dst.get();
        copyTable(helper.getReadableDatabase(), Favorites.TABLE_NAME,
                mOpenHelper.getWritableDatabase(), targetTableName, getContext());
        helper.close();
        return true;
    }

@@ -425,7 +426,23 @@ public class LauncherProvider extends ContentProvider {
                if (MULTI_DB_GRID_MIRATION_ALGO.get()) {
                    Bundle result = new Bundle();
                    result.putBoolean(LauncherSettings.Settings.EXTRA_VALUE,
                            updateCurrentOpenHelper());
                            prepForMigration(
                                    InvariantDeviceProfile.INSTANCE.get(getContext()).dbFile,
                                    Favorites.TMP_TABLE,
                                    () -> mOpenHelper,
                                    () -> DatabaseHelper.createDatabaseHelper(getContext())));
                    return result;
                }
            }
            case LauncherSettings.Settings.METHOD_PREP_FOR_PREVIEW: {
                if (MULTI_DB_GRID_MIRATION_ALGO.get()) {
                    Bundle result = new Bundle();
                    result.putBoolean(LauncherSettings.Settings.EXTRA_VALUE,
                            prepForMigration(
                                    arg /* dbFile */,
                                    Favorites.PREVIEW_TABLE_NAME,
                                    () -> DatabaseHelper.createDatabaseHelper(getContext(), arg),
                                    () -> mOpenHelper));
                    return result;
                }
            }
@@ -596,23 +613,31 @@ public class LauncherProvider extends ContentProvider {
        private int mMaxScreenId = -1;
        private boolean mBackupTableExists;

        DatabaseHelper(Context context) {
            this(context, MULTI_DB_GRID_MIRATION_ALGO.get() ? InvariantDeviceProfile.INSTANCE.get(
                    context).dbFile : LauncherFiles.LAUNCHER_DB);
        static DatabaseHelper createDatabaseHelper(Context context) {
            return createDatabaseHelper(context, null);
        }

        static DatabaseHelper createDatabaseHelper(Context context, String dbName) {
            if (dbName == null) {
                dbName = MULTI_DB_GRID_MIRATION_ALGO.get() ? InvariantDeviceProfile.INSTANCE.get(
                        context).dbFile : LauncherFiles.LAUNCHER_DB;
            }
            DatabaseHelper databaseHelper = new DatabaseHelper(context, dbName);
            // 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.
            if (!tableExists(getReadableDatabase(), Favorites.TABLE_NAME)) {
            if (!tableExists(databaseHelper.getReadableDatabase(), Favorites.TABLE_NAME)) {
                Log.e(TAG, "Tables are missing after onCreate has been called. Trying to recreate");
                // This operation is a no-op if the table already exists.
                addFavoritesTable(getWritableDatabase(), true);
                databaseHelper.addFavoritesTable(databaseHelper.getWritableDatabase(), true);
            }
            if (!MULTI_DB_GRID_MIRATION_ALGO.get()) {
                mBackupTableExists = tableExists(getReadableDatabase(),
                        Favorites.BACKUP_TABLE_NAME);
                databaseHelper.mBackupTableExists = tableExists(
                        databaseHelper.getReadableDatabase(), Favorites.BACKUP_TABLE_NAME);
            }

            initIds();
            databaseHelper.initIds();
            return databaseHelper;
        }

        /**
+7 −1
Original line number Diff line number Diff line
@@ -326,10 +326,16 @@ public class LauncherSettings {

        public static final String METHOD_UPDATE_CURRENT_OPEN_HELPER = "update_current_open_helper";

        public static final String METHOD_PREP_FOR_PREVIEW = "prep_for_preview";

        public static final String EXTRA_VALUE = "value";

        public static Bundle call(ContentResolver cr, String method) {
            return cr.call(CONTENT_URI, method, null, null);
            return call(cr, method, null);
        }

        public static Bundle call(ContentResolver cr, String method, String arg) {
            return cr.call(CONTENT_URI, method, arg, null);
        }
    }
}
+4 −2
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import static android.view.View.VISIBLE;

import static com.android.launcher3.config.FeatureFlags.ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER;
import static com.android.launcher3.config.FeatureFlags.MULTI_DB_GRID_MIRATION_ALGO;
import static com.android.launcher3.model.GridSizeMigrationTask.needsToMigrate;
import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems;
import static com.android.launcher3.model.ModelUtils.sortWorkspaceItemsSpatially;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
@@ -397,7 +396,10 @@ public class LauncherPreviewRenderer implements Callable<Bitmap> {

        private void populate() {
            if (ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER.get()) {
                boolean needsToMigrate = needsToMigrate(mContext, mIdp);
                boolean needsToMigrate =
                        MULTI_DB_GRID_MIRATION_ALGO.get()
                                ? GridSizeMigrationTaskV2.needsToMigrate(mContext, mIdp)
                                : GridSizeMigrationTask.needsToMigrate(mContext, mIdp);
                boolean success = false;
                if (needsToMigrate) {
                    success = MULTI_DB_GRID_MIRATION_ALGO.get()
+62 −30
Original line number Diff line number Diff line
@@ -123,8 +123,16 @@ public class GridSizeMigrationTaskV2 {
    }

    /**
     * Run the migration algorithm if needed. For preview, we provide the intended idp because it
     * has not been changed. If idp is null, we read it from the context, for actual grid migration.
     * When migrating the grid for preview, we copy the table
     * {@link LauncherSettings.Favorites.TABLE_NAME} into
     * {@link LauncherSettings.Favorites.PREVIEW_TABLE_NAME}, run grid size migration from the
     * former to the later, then use the later table for preview.
     *
     * Similarly when doing the actual grid migration, the former grid option's table
     * {@link LauncherSettings.Favorites.TABLE_NAME} is copied into the new grid option's
     * {@link LauncherSettings.Favorites.TMP_TABLE}, we then run the grid size migration algorithm
     * to migrate the later to the former, and load the workspace from the default
     * {@link LauncherSettings.Favorites.TABLE_NAME}.
     *
     * @return false if the migration failed.
     */
@@ -151,7 +159,14 @@ public class GridSizeMigrationTaskV2 {
        HashSet<String> validPackages = getValidPackages(context);
        int srcHotseatCount = prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, idp.numHotseatIcons);

        if (migrateForPreview) {
            if (!LauncherSettings.Settings.call(
                    context.getContentResolver(),
                    LauncherSettings.Settings.METHOD_PREP_FOR_PREVIEW, idp.dbFile).getBoolean(
                    LauncherSettings.Settings.EXTRA_VALUE)) {
                return false;
            }
        } else if (!LauncherSettings.Settings.call(
                context.getContentResolver(),
                LauncherSettings.Settings.METHOD_UPDATE_CURRENT_OPEN_HELPER).getBoolean(
                LauncherSettings.Settings.EXTRA_VALUE)) {
@@ -164,9 +179,13 @@ public class GridSizeMigrationTaskV2 {
                LauncherSettings.Settings.METHOD_NEW_TRANSACTION).getBinder(
                LauncherSettings.Settings.EXTRA_VALUE)) {

            DbReader srcReader = new DbReader(t.getDb(), LauncherSettings.Favorites.TMP_TABLE,
            DbReader srcReader = new DbReader(t.getDb(),
                    migrateForPreview ? LauncherSettings.Favorites.TABLE_NAME
                            : LauncherSettings.Favorites.TMP_TABLE,
                    context, validPackages, srcHotseatCount);
            DbReader destReader = new DbReader(t.getDb(), LauncherSettings.Favorites.TABLE_NAME,
            DbReader destReader = new DbReader(t.getDb(),
                    migrateForPreview ? LauncherSettings.Favorites.PREVIEW_TABLE_NAME
                            : LauncherSettings.Favorites.TABLE_NAME,
                    context, validPackages, idp.numHotseatIcons);

            Point targetSize = new Point(idp.numColumns, idp.numRows);
@@ -174,7 +193,9 @@ public class GridSizeMigrationTaskV2 {
                    srcReader, destReader, idp.numHotseatIcons, targetSize);
            task.migrate();

            if (!migrateForPreview) {
                dropTable(t.getDb(), LauncherSettings.Favorites.TMP_TABLE);
            }

            t.commit();
            return true;
@@ -186,6 +207,7 @@ public class GridSizeMigrationTaskV2 {
            Log.v(TAG, "Workspace migration completed in "
                    + (System.currentTimeMillis() - migrationStartTime));

            if (!migrateForPreview) {
                // Save current configuration, so that the migration does not run again.
                prefs.edit()
                        .putString(KEY_MIGRATION_SRC_WORKSPACE_SIZE, gridSizeString)
@@ -193,6 +215,7 @@ public class GridSizeMigrationTaskV2 {
                        .apply();
            }
        }
    }

    @VisibleForTesting
    protected boolean migrate() {
@@ -202,7 +225,7 @@ public class GridSizeMigrationTaskV2 {

        // Migrate hotseat
        HotseatPlacementSolution hotseatSolution = new HotseatPlacementSolution(mDb, mSrcReader,
                mContext, mDestHotseatSize, mHotseatItems, mHotseatDiff);
                mDestReader, mContext, mDestHotseatSize, mHotseatItems, mHotseatDiff);
        hotseatSolution.find();

        // Sort the items by the reading order.
@@ -215,7 +238,7 @@ public class GridSizeMigrationTaskV2 {
            }
            List<DbEntry> entries = mDestReader.loadWorkspaceEntries(screenId);
            GridPlacementSolution workspaceSolution = new GridPlacementSolution(mDb, mSrcReader,
                    mContext, entries, screenId, mTrgX, mTrgY, mWorkspaceDiff);
                    mDestReader, mContext, entries, screenId, mTrgX, mTrgY, mWorkspaceDiff);
            workspaceSolution.find();
            if (mWorkspaceDiff.isEmpty()) {
                break;
@@ -225,7 +248,8 @@ public class GridSizeMigrationTaskV2 {
        int screenId = mDestReader.mLastScreenId + 1;
        while (!mWorkspaceDiff.isEmpty()) {
            GridPlacementSolution workspaceSolution = new GridPlacementSolution(mDb, mSrcReader,
                    mContext, new ArrayList<>(), screenId, mTrgX, mTrgY, mWorkspaceDiff);
                    mDestReader, mContext, new ArrayList<>(), screenId, mTrgX, mTrgY,
                    mWorkspaceDiff);
            workspaceSolution.find();
            screenId++;
        }
@@ -246,7 +270,8 @@ public class GridSizeMigrationTaskV2 {
    }

    private static void insertEntryInDb(SQLiteDatabase db, Context context,
            ArrayList<DbEntry> entriesFromSrcDb, DbEntry entry) {
            ArrayList<DbEntry> entriesFromSrcDb, DbEntry entry, String srcTableName,
            String destTableName) {
        int id = -1;
        switch (entry.itemType) {
            case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
@@ -283,8 +308,8 @@ public class GridSizeMigrationTaskV2 {
                return;
        }

        Cursor c = db.query(LauncherSettings.Favorites.TMP_TABLE, null,
                LauncherSettings.Favorites._ID + " = '" + id + "'", null, null, null, null);
        Cursor c = db.query(srcTableName, null, LauncherSettings.Favorites._ID + " = '" + id + "'",
                null, null, null, null);

        while (c.moveToNext()) {
            ContentValues values = new ContentValues();
@@ -294,14 +319,14 @@ public class GridSizeMigrationTaskV2 {
                    LauncherSettings.Settings.call(context.getContentResolver(),
                            LauncherSettings.Settings.METHOD_NEW_ITEM_ID).getInt(
                            LauncherSettings.Settings.EXTRA_VALUE));
            db.insert(LauncherSettings.Favorites.TABLE_NAME, null, values);
            db.insert(destTableName, 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 void removeEntryFromDb(SQLiteDatabase db, String tableName, IntArray entryId) {
        db.delete(tableName,
                Utilities.createDbSelectionQuery(LauncherSettings.Favorites._ID, entryId), null);
    }

    private static HashSet<String> getValidPackages(Context context) {
@@ -325,6 +350,7 @@ public class GridSizeMigrationTaskV2 {

        private final SQLiteDatabase mDb;
        private final DbReader mSrcReader;
        private final DbReader mDestReader;
        private final Context mContext;
        private final GridOccupancy mOccupied;
        private final int mScreenId;
@@ -335,11 +361,12 @@ public class GridSizeMigrationTaskV2 {
        private int mNextStartX;
        private int mNextStartY;

        GridPlacementSolution(SQLiteDatabase db, DbReader srcReader, Context context,
                List<DbEntry> placedWorkspaceItems, int screenId, int trgX,
        GridPlacementSolution(SQLiteDatabase db, DbReader srcReader, DbReader destReader,
                Context context, List<DbEntry> placedWorkspaceItems, int screenId, int trgX,
                int trgY, List<DbEntry> itemsToPlace) {
            mDb = db;
            mSrcReader = srcReader;
            mDestReader = destReader;
            mContext = context;
            mOccupied = new GridOccupancy(trgX, trgY);
            mScreenId = screenId;
@@ -362,7 +389,8 @@ public class GridSizeMigrationTaskV2 {
                    continue;
                }
                if (findPlacement(entry)) {
                    insertEntryInDb(mDb, mContext, mSrcReader.mWorkspaceEntries, entry);
                    insertEntryInDb(mDb, mContext, mSrcReader.mWorkspaceEntries, entry,
                            mSrcReader.mTableName, mDestReader.mTableName);
                    iterator.remove();
                }
            }
@@ -397,14 +425,17 @@ public class GridSizeMigrationTaskV2 {

        private final SQLiteDatabase mDb;
        private final DbReader mSrcReader;
        private final DbReader mDestReader;
        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) {
        HotseatPlacementSolution(SQLiteDatabase db, DbReader srcReader, DbReader destReader,
                Context context, int hotseatSize, List<DbEntry> placedHotseatItems,
                List<DbEntry> itemsToPlace) {
            mDb = db;
            mSrcReader = srcReader;
            mDestReader = destReader;
            mContext = context;
            mOccupied = new HotseatOccupancy(hotseatSize);
            for (DbEntry entry : placedHotseatItems) {
@@ -422,7 +453,8 @@ public class GridSizeMigrationTaskV2 {
                    // to something other than -1.
                    entry.cellX = i;
                    entry.cellY = 0;
                    insertEntryInDb(mDb, mContext, mSrcReader.mHotseatEntries, entry);
                    insertEntryInDb(mDb, mContext, mSrcReader.mHotseatEntries, entry,
                            mSrcReader.mTableName, mDestReader.mTableName);
                    mOccupied.markCells(entry, true);
                }
            }
@@ -519,7 +551,7 @@ public class GridSizeMigrationTaskV2 {
                }
                mHotseatEntries.add(entry);
            }
            removeEntryFromDb(mDb, entriesToRemove);
            removeEntryFromDb(mDb, mTableName, entriesToRemove);
            c.close();
            return mHotseatEntries;
        }
@@ -639,7 +671,7 @@ public class GridSizeMigrationTaskV2 {
                }
                mWorkspaceEntries.add(entry);
            }
            removeEntryFromDb(mDb, entriesToRemove);
            removeEntryFromDb(mDb, mTableName, entriesToRemove);
            c.close();
            return mWorkspaceEntries;
        }
@@ -657,7 +689,7 @@ public class GridSizeMigrationTaskV2 {
                    total++;
                    entry.mFolderItems.add(intent);
                } catch (Exception e) {
                    removeEntryFromDb(mDb, IntArray.wrap(c.getInt(0)));
                    removeEntryFromDb(mDb, mTableName, IntArray.wrap(c.getInt(0)));
                }
            }
            c.close();
+1 −0
Original line number Diff line number Diff line
@@ -129,6 +129,7 @@ public class LauncherDbUtils {
            toDb.execSQL("ATTACH DATABASE '" + fromDb.getPath() + "' AS from_db");
            toDb.execSQL(
                    "INSERT INTO " + toTable + " SELECT * FROM from_db." + fromTable);
            toDb.execSQL("DETACH DATABASE 'from_db'");
        } else {
            toDb.execSQL("INSERT INTO " + toTable + " SELECT * FROM " + fromTable);
        }