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

Commit 5ff84328 authored by fbaron's avatar fbaron
Browse files

Fix grid migration item copy bug

When migrating from a grid with 2+ copies of the same item to a grid that has less copies of that item, but more than 0, the extra copies don't migrate to the new grid.

Bug: 354946925
Test: ValidGridMigrationUnitTest
Flag: EXEMPT bugfix
Change-Id: I76ad0cb0f5abe9b5bf895c07467fc05986e9fea4
parent 892d3583
Loading
Loading
Loading
Loading
+41 −22
Original line number Diff line number Diff line
@@ -213,9 +213,13 @@ public class GridSizeMigrationUtil {
        Collections.sort(hotseatToBeAdded);
        Collections.sort(workspaceToBeAdded);

        List<Integer> idsInUse = dstWorkspaceItems.stream().map(entry -> entry.id).collect(
                Collectors.toList());
        idsInUse.addAll(dstHotseatItems.stream().map(entry -> entry.id).toList());

        // Migrate hotseat
        solveHotseatPlacement(helper, destHotseatSize,
                srcReader, destReader, dstHotseatItems, hotseatToBeAdded);
                srcReader, destReader, dstHotseatItems, hotseatToBeAdded, idsInUse);

        // Migrate workspace.
        // First we create a collection of the screens
@@ -230,7 +234,7 @@ public class GridSizeMigrationUtil {
                Log.d(TAG, "Migrating " + screenId);
            }
            solveGridPlacement(helper, srcReader,
                    destReader, screenId, trgX, trgY, workspaceToBeAdded);
                    destReader, screenId, trgX, trgY, workspaceToBeAdded, idsInUse);
            if (workspaceToBeAdded.isEmpty()) {
                break;
            }
@@ -241,7 +245,7 @@ public class GridSizeMigrationUtil {
        int screenId = destReader.mLastScreenId + 1;
        while (!workspaceToBeAdded.isEmpty()) {
            solveGridPlacement(helper, srcReader, destReader, screenId, trgX, trgY,
                    workspaceToBeAdded);
                    workspaceToBeAdded, srcWorkspaceItems.stream().map(entry -> entry.id).toList());
            screenId++;
        }

@@ -257,47 +261,57 @@ public class GridSizeMigrationUtil {
    private static void calcDiff(@NonNull final List<DbEntry> src,
            @NonNull final List<DbEntry> dest, @NonNull final List<DbEntry> toBeAdded,
            @NonNull final IntArray toBeRemoved) {
        HashMap<DbEntry, Integer> entryCountDiff = new HashMap<>();
        src.forEach(entry ->
                entryCountDiff.put(entry, entryCountDiff.getOrDefault(entry, 0) + 1));
        dest.forEach(entry ->
                entryCountDiff.put(entry, entryCountDiff.getOrDefault(entry, 0) - 1));

        src.forEach(entry -> {
            if (!dest.contains(entry)) {
            if (entryCountDiff.get(entry) > 0) {
                toBeAdded.add(entry);
                entryCountDiff.put(entry, entryCountDiff.get(entry) - 1);
            }
        });

        dest.forEach(entry -> {
            if (!src.contains(entry)) {
            if (entryCountDiff.get(entry) < 0) {
                toBeRemoved.add(entry.id);
                if (entry.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
                    entry.mFolderItems.values().forEach(ids -> ids.forEach(toBeRemoved::add));
                }
                entryCountDiff.put(entry, entryCountDiff.get(entry) + 1);
            }
        });
    }

    private static void insertEntryInDb(DatabaseHelper helper, DbEntry entry,
            String srcTableName, String destTableName) {
        int id = copyEntryAndUpdate(helper, entry, srcTableName, destTableName);

            String srcTableName, String destTableName, List<Integer> idsInUse) {
        int id = copyEntryAndUpdate(helper, entry, srcTableName, destTableName, idsInUse);
        if (entry.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER
                || entry.itemType == LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR) {
            for (Set<Integer> itemIds : entry.mFolderItems.values()) {
                for (int itemId : itemIds) {
                    copyEntryAndUpdate(helper, itemId, id, srcTableName, destTableName);
                    copyEntryAndUpdate(helper, itemId, id, srcTableName, destTableName, idsInUse);
                }
            }
        }
    }

    private static int copyEntryAndUpdate(DatabaseHelper helper,
            DbEntry entry, String srcTableName, String destTableName) {
        return copyEntryAndUpdate(helper, entry, -1, -1, srcTableName, destTableName);
            DbEntry entry, String srcTableName, String destTableName, List<Integer> idsInUse) {
        return copyEntryAndUpdate(
                helper, entry, -1, -1, srcTableName, destTableName, idsInUse);
    }

    private static int copyEntryAndUpdate(DatabaseHelper helper,
            int id, int folderId, String srcTableName, String destTableName) {
        return copyEntryAndUpdate(helper, null, id, folderId, srcTableName, destTableName);
    private static int copyEntryAndUpdate(DatabaseHelper helper, int id,
            int folderId, String srcTableName, String destTableName, List<Integer> idsInUse) {
        return copyEntryAndUpdate(
                helper, null, id, folderId, srcTableName, destTableName, idsInUse);
    }

    private static int copyEntryAndUpdate(DatabaseHelper helper, DbEntry entry,
            int id, int folderId, String srcTableName, String destTableName) {
    private static int copyEntryAndUpdate(DatabaseHelper helper, DbEntry entry, int id,
            int folderId, String srcTableName, String destTableName, List<Integer> idsInUse) {
        int newId = -1;
        Cursor c = helper.getWritableDatabase().query(srcTableName, null,
                LauncherSettings.Favorites._ID + " = '" + (entry != null ? entry.id : id) + "'",
@@ -311,6 +325,9 @@ public class GridSizeMigrationUtil {
                values.put(LauncherSettings.Favorites.CONTAINER, folderId);
            }
            newId = helper.generateNewItemId();
            while (idsInUse.contains(newId)) {
                newId = helper.generateNewItemId();
            }
            values.put(LauncherSettings.Favorites._ID, newId);
            helper.getWritableDatabase().insert(destTableName, null, values);
        }
@@ -343,7 +360,7 @@ public class GridSizeMigrationUtil {
    private static void solveGridPlacement(@NonNull final DatabaseHelper helper,
            @NonNull final DbReader srcReader, @NonNull final DbReader destReader,
            final int screenId, final int trgX, final int trgY,
            @NonNull final List<DbEntry> sortedItemsToPlace) {
            @NonNull final List<DbEntry> sortedItemsToPlace, List<Integer> idsInUse) {
        final GridOccupancy occupied = new GridOccupancy(trgX, trgY);
        final Point trg = new Point(trgX, trgY);
        final Point next = new Point(0, screenId == 0
@@ -366,7 +383,8 @@ public class GridSizeMigrationUtil {
                continue;
            }
            if (findPlacementForEntry(entry, next, trg, occupied, screenId)) {
                insertEntryInDb(helper, entry, srcReader.mTableName, destReader.mTableName);
                insertEntryInDb(
                        helper, entry, srcReader.mTableName, destReader.mTableName, idsInUse);
                iterator.remove();
            }
        }
@@ -407,7 +425,7 @@ public class GridSizeMigrationUtil {
            @NonNull final DatabaseHelper helper, final int hotseatSize,
            @NonNull final DbReader srcReader, @NonNull final DbReader destReader,
            @NonNull final  List<DbEntry> placedHotseatItems,
            @NonNull final List<DbEntry> itemsToPlace) {
            @NonNull final List<DbEntry> itemsToPlace, List<Integer> idsInUse) {

        final boolean[] occupied = new boolean[hotseatSize];
        for (DbEntry entry : placedHotseatItems) {
@@ -422,7 +440,8 @@ public class GridSizeMigrationUtil {
                // to something other than -1.
                entry.cellX = i;
                entry.cellY = 0;
                insertEntryInDb(helper, entry, srcReader.mTableName, destReader.mTableName);
                insertEntryInDb(
                        helper, entry, srcReader.mTableName, destReader.mTableName, idsInUse);
                occupied[entry.screenId] = true;
            }
        }
@@ -564,12 +583,12 @@ public class GridSizeMigrationUtil {
                        }
                        case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: {
                            entry.mProvider = c.getString(indexAppWidgetProvider);
                            entry.appWidgetId = c.getInt(indexAppWidgetId);
                            ComponentName cn = ComponentName.unflattenFromString(entry.mProvider);
                            verifyPackage(cn.getPackageName());

                            int widgetId = c.getInt(indexAppWidgetId);
                            LauncherAppWidgetProviderInfo pInfo = widgetManagerHelper
                                    .getLauncherAppWidgetInfo(widgetId, cn);
                                    .getLauncherAppWidgetInfo(entry.appWidgetId, cn);
                            Point spans = null;
                            if (pInfo != null) {
                                spans = pInfo.getMinSpans();
+7 −1
Original line number Diff line number Diff line
@@ -94,7 +94,13 @@ class ValidGridMigrationUnitTest {

        val srcCountMap = itemsToMap(srcGrid.items)
        val resultCountMap = itemsToMap(resultItems)
        val diff = resultCountMap - srcCountMap
        val diff = resultCountMap.toMutableMap()
        for ((srcKey, srcValue) in srcCountMap) {
            val destValue = diff[srcKey]
            if (destValue != null) {
                diff[srcKey] = destValue - srcValue
            }
        }

        diff.forEach { (k, count) ->
            assert(count >= 0) { "Source item $k not present on the result" }