From 08788a939b23c2b6a8fb76a57701c2344c69bc2a Mon Sep 17 00:00:00 2001 From: Sebastian Franco Date: Tue, 17 May 2022 13:46:39 -0700 Subject: [PATCH] Widget migration now supports widgets and repeated elements in the worskpace. The widget migration was using the variable DbEntry.mIntent as an id for calculating the difference between two workspaces but widgets don't have that variable, it's always null. So that had created some bugs. Also, the function GridSizeMigrationTaskV2.calcDiff didn't accounted for repeated icons or repeated widgets. It's not a big deal not account for repeated icons, but repeated widgets can be usefull for the user, so now calcDiff keeps repeated icons and widgets. Fix: 229701468 Test: Add multiple icons and widgets in the workspace and change the grid size, this code only runs after the first time you change the grid size, so try a couple of times. It should keep the widgets and icons, even if they are repeated. Change-Id: I5812445cec8364d8cc57cbcc3f1ae04ba9099932 --- .../model/GridSizeMigrationTaskV2.java | 58 +++++++++++++------ 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java index ef9250c900..a7b0b9d00b 100644 --- a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java +++ b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java @@ -56,6 +56,7 @@ import java.util.List; import java.util.Map; 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 @@ -267,38 +268,33 @@ public class GridSizeMigrationTaskV2 { /** Return what's in the src but not in the dest */ private static List calcDiff(List src, List dest) { - Set destIntentSet = new HashSet<>(); - Set> destFolderIntentSet = new HashSet<>(); + Map destIdSet = new HashMap<>(); for (DbEntry entry : dest) { - if (entry.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) { - destFolderIntentSet.add(getFolderIntents(entry)); + String entryID = entry.getEntryMigrationId(); + if (destIdSet.containsKey(entryID)) { + destIdSet.put(entryID, destIdSet.get(entryID) + 1); } else { - destIntentSet.add(entry.mIntent); + destIdSet.put(entryID, 1); } } List diff = new ArrayList<>(); for (DbEntry entry : src) { - if (entry.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) { - if (!destFolderIntentSet.contains(getFolderIntents(entry))) { + String entryID = entry.getEntryMigrationId(); + if (destIdSet.containsKey(entryID)) { + Integer count = destIdSet.get(entryID); + if (count <= 0) { diff.add(entry); + destIdSet.remove(entryID); + } else { + destIdSet.put(entryID, count - 1); } } else { - if (!destIntentSet.contains(entry.mIntent)) { - diff.add(entry); - } + diff.add(entry); } } return diff; } - private static Map getFolderIntents(DbEntry entry) { - Map folder = new HashMap<>(); - for (String intent : entry.mFolderItems.keySet()) { - folder.put(intent, entry.mFolderItems.get(intent).size()); - } - return folder; - } - private static void insertEntryInDb(SQLiteDatabase db, Context context, DbEntry entry, String srcTableName, String destTableName) { int id = copyEntryAndUpdate(db, context, entry, srcTableName, destTableName); @@ -780,5 +776,31 @@ public class GridSizeMigrationTaskV2 { values.put(LauncherSettings.Favorites.SPANX, spanX); values.put(LauncherSettings.Favorites.SPANY, spanY); } + + /** + * This method should return an id that should be the same for two folders containing the + * same elements. + */ + private String getFolderMigrationId() { + return mFolderItems.keySet().stream() + .map(intentString -> mFolderItems.get(intentString).size() + intentString) + .sorted() + .collect(Collectors.joining(",")); + } + + /** This id is not used in the DB is only used while doing the migration and it identifies + * an entry on each workspace. For example two calculator icons would have the same + * migration id even thought they have different database ids. + */ + public String getEntryMigrationId() { + switch (itemType) { + case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: + return getFolderMigrationId(); + case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: + return mProvider; + default: + return mIntent; + } + } } }