From ea600c70fd603eec92900f6421f6c33c3f2d0702 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Thu, 9 Jul 2020 19:31:40 -0700 Subject: [PATCH] Creating a common method to iterate over all model items. This would allow adding different source for model items without modifying every model task Bug: 160748731 Change-Id: I5a14dd761e2b8696c58dc8fec7b14077da0aced3 --- src/com/android/launcher3/LauncherModel.java | 8 +- .../allapps/AllAppsContainerView.java | 2 +- .../android/launcher3/model/BgDataModel.java | 14 ++ .../launcher3/model/CacheDataUpdatedTask.java | 22 +- .../model/PackageInstallStateChangedTask.java | 32 +-- .../launcher3/model/PackageUpdatedTask.java | 195 +++++++++--------- .../launcher3/model/ShortcutsChangedTask.java | 11 +- .../model/UserLockStateChangedTask.java | 39 ++-- .../launcher3/util/ItemInfoMatcher.java | 14 +- 9 files changed, 170 insertions(+), 167 deletions(-) diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index f434c9180a..ff4b545a06 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -58,7 +58,7 @@ import com.android.launcher3.pm.InstallSessionTracker; import com.android.launcher3.pm.PackageInstallInfo; import com.android.launcher3.pm.UserCache; import com.android.launcher3.shortcuts.ShortcutRequest; -import com.android.launcher3.util.IntSparseArrayMap; +import com.android.launcher3.util.IntSet; import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.LooperExecutor; import com.android.launcher3.util.PackageUserKey; @@ -410,7 +410,7 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi enqueueModelUpdateTask(new BaseModelUpdateTask() { @Override public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) { - final IntSparseArrayMap removedIds = new IntSparseArrayMap<>(); + final IntSet removedIds = new IntSet(); synchronized (dataModel) { for (ItemInfo info : dataModel.itemsIdMap) { if (info instanceof WorkspaceItemInfo @@ -418,13 +418,13 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi && user.equals(info.user) && info.getIntent() != null && TextUtils.equals(packageName, info.getIntent().getPackage())) { - removedIds.put(info.id, true /* remove */); + removedIds.add(info.id); } } } if (!removedIds.isEmpty()) { - deleteAndBindComponentsRemoved(ItemInfoMatcher.ofItemIds(removedIds, false)); + deleteAndBindComponentsRemoved(ItemInfoMatcher.ofItemIds(removedIds)); } } }); diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index c989e7bf64..77b8a32c7a 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -83,7 +83,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo protected final BaseDraggingActivity mLauncher; protected final AdapterHolder[] mAH; private final ItemInfoMatcher mPersonalMatcher = ItemInfoMatcher.ofUser(Process.myUserHandle()); - private final ItemInfoMatcher mWorkMatcher = ItemInfoMatcher.not(mPersonalMatcher); + private final ItemInfoMatcher mWorkMatcher = mPersonalMatcher.negate(); private final AllAppsStore mAllAppsStore = new AllAppsStore(); private final Paint mNavBarScrimPaint; diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java index 9bef84718b..7524920ce8 100644 --- a/src/com/android/launcher3/model/BgDataModel.java +++ b/src/com/android/launcher3/model/BgDataModel.java @@ -56,6 +56,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.function.BiConsumer; +import java.util.function.Consumer; import java.util.stream.Collectors; /** @@ -348,6 +349,19 @@ public class BgDataModel { } } + /** + * Calls the provided {@code op} for all workspaceItems in the in-memory model (both persisted + * items and dynamic/predicted items for the provided {@code userHandle}. + * Note the call is not synchronized over the model, that should be handled by the called. + */ + public void forAllWorkspaceItemInfos(UserHandle userHandle, Consumer op) { + for (ItemInfo info : itemsIdMap) { + if (info instanceof WorkspaceItemInfo && userHandle.equals(info.user)) { + op.accept((WorkspaceItemInfo) info); + } + } + } + public interface Callbacks { // If the launcher has permission to access deep shortcuts. int FLAG_HAS_SHORTCUT_PERMISSION = 1 << 0; diff --git a/src/com/android/launcher3/model/CacheDataUpdatedTask.java b/src/com/android/launcher3/model/CacheDataUpdatedTask.java index 8e6b064498..f644d49276 100644 --- a/src/com/android/launcher3/model/CacheDataUpdatedTask.java +++ b/src/com/android/launcher3/model/CacheDataUpdatedTask.java @@ -21,7 +21,6 @@ import android.os.UserHandle; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherSettings; import com.android.launcher3.icons.IconCache; -import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import java.util.ArrayList; @@ -48,23 +47,18 @@ public class CacheDataUpdatedTask extends BaseModelUpdateTask { @Override public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) { IconCache iconCache = app.getIconCache(); - - ArrayList updatedShortcuts = new ArrayList<>(); synchronized (dataModel) { - for (ItemInfo info : dataModel.itemsIdMap) { - if (info instanceof WorkspaceItemInfo && mUser.equals(info.user)) { - WorkspaceItemInfo si = (WorkspaceItemInfo) info; - ComponentName cn = si.getTargetComponent(); - if (si.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION - && isValidShortcut(si) && cn != null - && mPackages.contains(cn.getPackageName())) { - iconCache.getTitleAndIcon(si, si.usingLowResIcon()); - updatedShortcuts.add(si); - } + dataModel.forAllWorkspaceItemInfos(mUser, si -> { + ComponentName cn = si.getTargetComponent(); + if (si.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION + && isValidShortcut(si) && cn != null + && mPackages.contains(cn.getPackageName())) { + iconCache.getTitleAndIcon(si, si.usingLowResIcon()); + updatedShortcuts.add(si); } - } + }); apps.updateIconsAndLabels(mPackages, mUser); } bindUpdatedWorkspaceItems(updatedShortcuts); diff --git a/src/com/android/launcher3/model/PackageInstallStateChangedTask.java b/src/com/android/launcher3/model/PackageInstallStateChangedTask.java index 203f1ca8e3..8369c48e5c 100644 --- a/src/com/android/launcher3/model/PackageInstallStateChangedTask.java +++ b/src/com/android/launcher3/model/PackageInstallStateChangedTask.java @@ -20,8 +20,6 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import com.android.launcher3.LauncherAppState; -import com.android.launcher3.LauncherModel.CallbackTask; -import com.android.launcher3.model.BgDataModel.Callbacks; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.LauncherAppWidgetInfo; import com.android.launcher3.model.data.PromiseAppInfo; @@ -70,21 +68,18 @@ public class PackageInstallStateChangedTask extends BaseModelUpdateTask { synchronized (dataModel) { final HashSet updates = new HashSet<>(); - for (ItemInfo info : dataModel.itemsIdMap) { - if (info instanceof WorkspaceItemInfo) { - WorkspaceItemInfo si = (WorkspaceItemInfo) info; - ComponentName cn = si.getTargetComponent(); - if (si.hasPromiseIconUi() && (cn != null) - && mInstallInfo.packageName.equals(cn.getPackageName())) { - si.setInstallProgress(mInstallInfo.progress); - if (mInstallInfo.state == PackageInstallInfo.STATUS_FAILED) { - // Mark this info as broken. - si.status &= ~WorkspaceItemInfo.FLAG_INSTALL_SESSION_ACTIVE; - } - updates.add(si); + dataModel.forAllWorkspaceItemInfos(mInstallInfo.user, si -> { + ComponentName cn = si.getTargetComponent(); + if (si.hasPromiseIconUi() && (cn != null) + && mInstallInfo.packageName.equals(cn.getPackageName())) { + si.setInstallProgress(mInstallInfo.progress); + if (mInstallInfo.state == PackageInstallInfo.STATUS_FAILED) { + // Mark this info as broken. + si.status &= ~WorkspaceItemInfo.FLAG_INSTALL_SESSION_ACTIVE; } + updates.add(si); } - } + }); for (LauncherAppWidgetInfo widget : dataModel.appWidgets) { if (widget.providerName.getPackageName().equals(mInstallInfo.packageName)) { @@ -94,12 +89,7 @@ public class PackageInstallStateChangedTask extends BaseModelUpdateTask { } if (!updates.isEmpty()) { - scheduleCallbackTask(new CallbackTask() { - @Override - public void execute(Callbacks callbacks) { - callbacks.bindRestoreItemsChange(updates); - } - }); + scheduleCallbackTask(callbacks -> callbacks.bindRestoreItemsChange(updates)); } } } diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java index 7cd467efd6..dca4ec0dcc 100644 --- a/src/com/android/launcher3/model/PackageUpdatedTask.java +++ b/src/com/android/launcher3/model/PackageUpdatedTask.java @@ -45,7 +45,7 @@ import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.pm.UserCache; import com.android.launcher3.shortcuts.ShortcutRequest; import com.android.launcher3.util.FlagOp; -import com.android.launcher3.util.IntSparseArrayMap; +import com.android.launcher3.util.IntSet; import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.PackageUserKey; @@ -92,9 +92,11 @@ public class PackageUpdatedTask extends BaseModelUpdateTask { final String[] packages = mPackages; final int N = packages.length; - FlagOp flagOp = FlagOp.NO_OP; + final FlagOp flagOp; final HashSet packageSet = new HashSet<>(Arrays.asList(packages)); - ItemInfoMatcher matcher = ItemInfoMatcher.ofPackages(packageSet, mUser); + final ItemInfoMatcher matcher = mOp == OP_USER_AVAILABILITY_CHANGE + ? ItemInfoMatcher.ofUser(mUser) // We want to update all packages for this user + : ItemInfoMatcher.ofPackages(packageSet, mUser); final HashSet removedComponents = new HashSet<>(); switch (mOp) { @@ -158,19 +160,22 @@ public class PackageUpdatedTask extends BaseModelUpdateTask { flagOp = ums.isUserQuiet(mUser) ? FlagOp.addFlag(WorkspaceItemInfo.FLAG_DISABLED_QUIET_USER) : FlagOp.removeFlag(WorkspaceItemInfo.FLAG_DISABLED_QUIET_USER); - // We want to update all packages for this user. - matcher = ItemInfoMatcher.ofUser(mUser); appsList.updateDisabledFlags(matcher, flagOp); // We are not synchronizing here, as int operations are atomic appsList.setFlags(FLAG_QUIET_MODE_ENABLED, ums.isAnyProfileQuietModeEnabled()); break; } + default: + flagOp = FlagOp.NO_OP; + break; } bindApplicationsIfNeeded(); - final IntSparseArrayMap removedShortcuts = new IntSparseArrayMap<>(); + final IntSet removedShortcuts = new IntSet(); + // Shortcuts to keep even if the corresponding app was removed + final IntSet forceKeepShortcuts = new IntSet(); // Update shortcut infos if (mOp == OP_ADD || flagOp != FlagOp.NO_OP) { @@ -180,118 +185,118 @@ public class PackageUpdatedTask extends BaseModelUpdateTask { // For system apps, package manager send OP_UPDATE when an app is enabled. final boolean isNewApkAvailable = mOp == OP_ADD || mOp == OP_UPDATE; synchronized (dataModel) { - for (ItemInfo info : dataModel.itemsIdMap) { - if (info instanceof WorkspaceItemInfo && mUser.equals(info.user)) { - WorkspaceItemInfo si = (WorkspaceItemInfo) info; - boolean infoUpdated = false; - boolean shortcutUpdated = false; + dataModel.forAllWorkspaceItemInfos(mUser, si -> { - // Update shortcuts which use iconResource. - if ((si.iconResource != null) - && packageSet.contains(si.iconResource.packageName)) { - LauncherIcons li = LauncherIcons.obtain(context); - BitmapInfo iconInfo = li.createIconBitmap(si.iconResource); - li.recycle(); - if (iconInfo != null) { - si.bitmap = iconInfo; - infoUpdated = true; + boolean infoUpdated = false; + boolean shortcutUpdated = false; + + // Update shortcuts which use iconResource. + if ((si.iconResource != null) + && packageSet.contains(si.iconResource.packageName)) { + LauncherIcons li = LauncherIcons.obtain(context); + BitmapInfo iconInfo = li.createIconBitmap(si.iconResource); + li.recycle(); + if (iconInfo != null) { + si.bitmap = iconInfo; + infoUpdated = true; + } + } + + ComponentName cn = si.getTargetComponent(); + if (cn != null && matcher.matches(si, cn)) { + String packageName = cn.getPackageName(); + + if (si.hasStatusFlag(WorkspaceItemInfo.FLAG_SUPPORTS_WEB_UI)) { + forceKeepShortcuts.add(si.id); + if (mOp == OP_REMOVE) { + return; } } - ComponentName cn = si.getTargetComponent(); - if (cn != null && matcher.matches(si, cn)) { - String packageName = cn.getPackageName(); - - if (si.hasStatusFlag(WorkspaceItemInfo.FLAG_SUPPORTS_WEB_UI)) { - removedShortcuts.put(si.id, false); - if (mOp == OP_REMOVE) { - continue; - } - } - - if (si.isPromise() && isNewApkAvailable) { - boolean isTargetValid = true; - if (si.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT) { - List shortcut = - new ShortcutRequest(context, mUser) - .forPackage(cn.getPackageName(), - si.getDeepShortcutId()) - .query(ShortcutRequest.PINNED); - if (shortcut.isEmpty()) { - isTargetValid = false; - } else { - si.updateFromDeepShortcutInfo(shortcut.get(0), context); - infoUpdated = true; - } - } else if (!cn.getClassName().equals(IconCache.EMPTY_CLASS_NAME)) { - isTargetValid = context.getSystemService(LauncherApps.class) - .isActivityEnabled(cn, mUser); - } - if (si.hasStatusFlag(FLAG_RESTORED_ICON | FLAG_AUTOINSTALL_ICON)) { - if (updateWorkspaceItemIntent(context, si, packageName)) { - infoUpdated = true; - } else if (si.hasPromiseIconUi()) { - removedShortcuts.put(si.id, true); - continue; - } - } else if (!isTargetValid) { - removedShortcuts.put(si.id, true); - FileLog.e(TAG, "Restored shortcut no longer valid " - + si.getIntent()); - continue; + if (si.isPromise() && isNewApkAvailable) { + boolean isTargetValid = true; + if (si.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT) { + List shortcut = + new ShortcutRequest(context, mUser) + .forPackage(cn.getPackageName(), + si.getDeepShortcutId()) + .query(ShortcutRequest.PINNED); + if (shortcut.isEmpty()) { + isTargetValid = false; } else { - si.status = WorkspaceItemInfo.DEFAULT; + si.updateFromDeepShortcutInfo(shortcut.get(0), context); infoUpdated = true; } - } else if (isNewApkAvailable && removedComponents.contains(cn)) { + } else if (!cn.getClassName().equals(IconCache.EMPTY_CLASS_NAME)) { + isTargetValid = context.getSystemService(LauncherApps.class) + .isActivityEnabled(cn, mUser); + } + if (si.hasStatusFlag(FLAG_RESTORED_ICON | FLAG_AUTOINSTALL_ICON)) { if (updateWorkspaceItemIntent(context, si, packageName)) { infoUpdated = true; + } else if (si.hasPromiseIconUi()) { + removedShortcuts.add(si.id); + return; } - } - - if (isNewApkAvailable && - si.itemType == Favorites.ITEM_TYPE_APPLICATION) { - iconCache.getTitleAndIcon(si, si.usingLowResIcon()); + } else if (!isTargetValid) { + removedShortcuts.add(si.id); + FileLog.e(TAG, "Restored shortcut no longer valid " + + si.getIntent()); + return; + } else { + si.status = WorkspaceItemInfo.DEFAULT; infoUpdated = true; } - - int oldRuntimeFlags = si.runtimeStatusFlags; - si.runtimeStatusFlags = flagOp.apply(si.runtimeStatusFlags); - if (si.runtimeStatusFlags != oldRuntimeFlags) { - shortcutUpdated = true; + } else if (isNewApkAvailable && removedComponents.contains(cn)) { + if (updateWorkspaceItemIntent(context, si, packageName)) { + infoUpdated = true; } } - if (infoUpdated || shortcutUpdated) { - updatedWorkspaceItems.add(si); + if (isNewApkAvailable + && si.itemType == Favorites.ITEM_TYPE_APPLICATION) { + iconCache.getTitleAndIcon(si, si.usingLowResIcon()); + infoUpdated = true; } - if (infoUpdated) { - getModelWriter().updateItemInDatabase(si); - } - } else if (info instanceof LauncherAppWidgetInfo && isNewApkAvailable) { - LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo) info; - if (mUser.equals(widgetInfo.user) - && widgetInfo.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) - && packageSet.contains(widgetInfo.providerName.getPackageName())) { - widgetInfo.restoreStatus &= - ~LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY & - ~LauncherAppWidgetInfo.FLAG_RESTORE_STARTED; - // adding this flag ensures that launcher shows 'click to setup' - // if the widget has a config activity. In case there is no config - // activity, it will be marked as 'restored' during bind. - widgetInfo.restoreStatus |= LauncherAppWidgetInfo.FLAG_UI_NOT_READY; - - widgets.add(widgetInfo); - getModelWriter().updateItemInDatabase(widgetInfo); + int oldRuntimeFlags = si.runtimeStatusFlags; + si.runtimeStatusFlags = flagOp.apply(si.runtimeStatusFlags); + if (si.runtimeStatusFlags != oldRuntimeFlags) { + shortcutUpdated = true; } } + + if (infoUpdated || shortcutUpdated) { + updatedWorkspaceItems.add(si); + } + if (infoUpdated && si.id != ItemInfo.NO_ID) { + getModelWriter().updateItemInDatabase(si); + } + }); + + for (LauncherAppWidgetInfo widgetInfo : dataModel.appWidgets) { + if (mUser.equals(widgetInfo.user) + && widgetInfo.hasRestoreFlag( + LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) + && packageSet.contains(widgetInfo.providerName.getPackageName())) { + widgetInfo.restoreStatus &= + ~LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY + & ~LauncherAppWidgetInfo.FLAG_RESTORE_STARTED; + + // adding this flag ensures that launcher shows 'click to setup' + // if the widget has a config activity. In case there is no config + // activity, it will be marked as 'restored' during bind. + widgetInfo.restoreStatus |= LauncherAppWidgetInfo.FLAG_UI_NOT_READY; + + widgets.add(widgetInfo); + getModelWriter().updateItemInDatabase(widgetInfo); + } } } bindUpdatedWorkspaceItems(updatedWorkspaceItems); if (!removedShortcuts.isEmpty()) { - deleteAndBindComponentsRemoved(ItemInfoMatcher.ofItemIds(removedShortcuts, false)); + deleteAndBindComponentsRemoved(ItemInfoMatcher.ofItemIds(removedShortcuts)); } if (!widgets.isEmpty()) { @@ -319,7 +324,7 @@ public class PackageUpdatedTask extends BaseModelUpdateTask { if (!removedPackages.isEmpty() || !removedComponents.isEmpty()) { ItemInfoMatcher removeMatch = ItemInfoMatcher.ofPackages(removedPackages, mUser) .or(ItemInfoMatcher.ofComponents(removedComponents, mUser)) - .and(ItemInfoMatcher.ofItemIds(removedShortcuts, true)); + .and(ItemInfoMatcher.ofItemIds(forceKeepShortcuts).negate()); deleteAndBindComponentsRemoved(removeMatch); // Remove any queued items from the install queue diff --git a/src/com/android/launcher3/model/ShortcutsChangedTask.java b/src/com/android/launcher3/model/ShortcutsChangedTask.java index 1cbe5c2f1b..88006ba6fb 100644 --- a/src/com/android/launcher3/model/ShortcutsChangedTask.java +++ b/src/com/android/launcher3/model/ShortcutsChangedTask.java @@ -21,7 +21,6 @@ import android.os.UserHandle; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherSettings; -import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.shortcuts.ShortcutKey; import com.android.launcher3.shortcuts.ShortcutRequest; @@ -58,14 +57,14 @@ public class ShortcutsChangedTask extends BaseModelUpdateTask { MultiHashMap keyToShortcutInfo = new MultiHashMap<>(); HashSet allIds = new HashSet<>(); - for (ItemInfo itemInfo : dataModel.itemsIdMap) { - if (itemInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) { - WorkspaceItemInfo si = (WorkspaceItemInfo) itemInfo; - if (mPackageName.equals(si.getIntent().getPackage()) && si.user.equals(mUser)) { + synchronized (dataModel) { + dataModel.forAllWorkspaceItemInfos(mUser, si -> { + if ((si.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) + && mPackageName.equals(si.getIntent().getPackage())) { keyToShortcutInfo.addToList(ShortcutKey.fromItemInfo(si), si); allIds.add(si.getDeepShortcutId()); } - } + }); } final ArrayList updatedWorkspaceItemInfos = new ArrayList<>(); diff --git a/src/com/android/launcher3/model/UserLockStateChangedTask.java b/src/com/android/launcher3/model/UserLockStateChangedTask.java index 7ec884f424..5048e13e3e 100644 --- a/src/com/android/launcher3/model/UserLockStateChangedTask.java +++ b/src/com/android/launcher3/model/UserLockStateChangedTask.java @@ -23,7 +23,6 @@ import android.os.UserHandle; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherSettings; -import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.shortcuts.ShortcutKey; import com.android.launcher3.shortcuts.ShortcutRequest; @@ -73,27 +72,27 @@ public class UserLockStateChangedTask extends BaseModelUpdateTask { ArrayList updatedWorkspaceItemInfos = new ArrayList<>(); HashSet removedKeys = new HashSet<>(); - for (ItemInfo itemInfo : dataModel.itemsIdMap) { - if (itemInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT - && mUser.equals(itemInfo.user)) { - WorkspaceItemInfo si = (WorkspaceItemInfo) itemInfo; - if (mIsUserUnlocked) { - ShortcutKey key = ShortcutKey.fromItemInfo(si); - ShortcutInfo shortcut = pinnedShortcuts.get(key); - // We couldn't verify the shortcut during loader. If its no longer available - // (probably due to clear data), delete the workspace item as well - if (shortcut == null) { - removedKeys.add(key); - continue; + synchronized (dataModel) { + dataModel.forAllWorkspaceItemInfos(mUser, si -> { + if (si.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) { + if (mIsUserUnlocked) { + ShortcutKey key = ShortcutKey.fromItemInfo(si); + ShortcutInfo shortcut = pinnedShortcuts.get(key); + // We couldn't verify the shortcut during loader. If its no longer available + // (probably due to clear data), delete the workspace item as well + if (shortcut == null) { + removedKeys.add(key); + return; + } + si.runtimeStatusFlags &= ~FLAG_DISABLED_LOCKED_USER; + si.updateFromDeepShortcutInfo(shortcut, context); + app.getIconCache().getShortcutIcon(si, shortcut); + } else { + si.runtimeStatusFlags |= FLAG_DISABLED_LOCKED_USER; } - si.runtimeStatusFlags &= ~FLAG_DISABLED_LOCKED_USER; - si.updateFromDeepShortcutInfo(shortcut, context); - app.getIconCache().getShortcutIcon(si, shortcut); - } else { - si.runtimeStatusFlags |= FLAG_DISABLED_LOCKED_USER; + updatedWorkspaceItemInfos.add(si); } - updatedWorkspaceItemInfos.add(si); - } + }); } bindUpdatedWorkspaceItems(updatedWorkspaceItemInfos); if (!removedKeys.isEmpty()) { diff --git a/src/com/android/launcher3/util/ItemInfoMatcher.java b/src/com/android/launcher3/util/ItemInfoMatcher.java index 4d5405d102..e98af35563 100644 --- a/src/com/android/launcher3/util/ItemInfoMatcher.java +++ b/src/com/android/launcher3/util/ItemInfoMatcher.java @@ -81,11 +81,10 @@ public interface ItemInfoMatcher { } /** - * Returns a new matcher which returns the opposite boolean value of the provided - * {@param matcher}. + * Returns a new matcher with returns the opposite value of this. */ - static ItemInfoMatcher not(ItemInfoMatcher matcher) { - return (info, cn) -> !matcher.matches(info, cn); + default ItemInfoMatcher negate() { + return (info, cn) -> !matches(info, cn); } static ItemInfoMatcher ofUser(UserHandle user) { @@ -105,7 +104,10 @@ public interface ItemInfoMatcher { keys.contains(ShortcutKey.fromItemInfo(info)); } - static ItemInfoMatcher ofItemIds(IntSparseArrayMap ids, Boolean matchDefault) { - return (info, cn) -> ids.get(info.id, matchDefault); + /** + * Returns a matcher for items with provided ids + */ + static ItemInfoMatcher ofItemIds(IntSet ids) { + return (info, cn) -> ids.contains(info.id); } }