diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java index 62a8da787d..05b81671c3 100644 --- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java +++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java @@ -55,13 +55,13 @@ import com.android.launcher3.popup.SystemShortcut; import com.android.launcher3.touch.ItemLongClickListener; import com.android.launcher3.uioverrides.PredictedAppIcon; import com.android.launcher3.uioverrides.QuickstepLauncher; -import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.OnboardingPrefs; import com.android.launcher3.views.Snackbar; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.function.Predicate; import java.util.stream.Collectors; /** @@ -480,8 +480,8 @@ public class HotseatPredictionController implements DragController.DragListener, * * @param matcher filter matching items that have been removed */ - public void onModelItemsRemoved(ItemInfoMatcher matcher) { - if (mPredictedItems.removeIf(matcher::matchesInfo)) { + public void onModelItemsRemoved(Predicate matcher) { + if (mPredictedItems.removeIf(matcher)) { fillGapsWithPrediction(true); } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java index 5c10565dc1..c522888fce 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java @@ -73,6 +73,7 @@ import com.android.systemui.shared.recents.model.Task; import java.io.PrintWriter; import java.util.Arrays; import java.util.Collections; +import java.util.function.Predicate; /** * Handles long click on Taskbar items to start a system drag and drop operation. @@ -439,12 +440,12 @@ public class TaskbarDragController extends DragController im target = taskbarViewController.getAllAppsButtonView(); } else if (item.container >= 0) { // Since folders close when the drag starts, target the folder icon instead. - ItemInfoMatcher matcher = ItemInfoMatcher.forFolderMatch( + Predicate matcher = ItemInfoMatcher.forFolderMatch( ItemInfoMatcher.ofItemIds(IntSet.wrap(item.id))); target = taskbarViewController.getFirstIconMatch(matcher); } else if (item.itemType == ITEM_TYPE_DEEP_SHORTCUT) { // Find first icon with same package/user as the deep shortcut. - ItemInfoMatcher packageUserMatcher = ItemInfoMatcher.ofPackages( + Predicate packageUserMatcher = ItemInfoMatcher.ofPackages( Collections.singleton(item.getTargetPackage()), item.user); target = taskbarViewController.getFirstIconMatch(packageUserMatcher); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java index 62392eea29..75881a31f2 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java @@ -36,6 +36,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.function.Predicate; /** * Launcher model Callbacks for rendering taskbar. @@ -126,16 +127,16 @@ public class TaskbarModelCallbacks implements } @Override - public void bindWorkspaceComponentsRemoved(ItemInfoMatcher matcher) { + public void bindWorkspaceComponentsRemoved(Predicate matcher) { if (handleItemsRemoved(matcher)) { commitItemsToUI(); } } - private boolean handleItemsRemoved(ItemInfoMatcher matcher) { + private boolean handleItemsRemoved(Predicate matcher) { boolean modified = false; for (int i = mHotseatItems.size() - 1; i >= 0; i--) { - if (matcher.matchesInfo(mHotseatItems.valueAt(i))) { + if (matcher.test(mHotseatItems.valueAt(i))) { modified = true; mHotseatItems.removeAt(i); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java index 7548398be2..6f88d649fb 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java @@ -41,12 +41,13 @@ import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.uioverrides.ApiWrapper; -import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.LauncherBindableItemsContainer; import com.android.launcher3.views.ActivityContext; import com.android.launcher3.views.AllAppsButton; import com.android.launcher3.views.DoubleShadowBubbleTextView; +import java.util.function.Predicate; + /** * Hosts the Taskbar content such as Hotseat and Recent Apps. Drawn on top of other apps. */ @@ -424,8 +425,8 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar * Finds the first icon to match one of the given matchers, from highest to lowest priority. * @return The first match, or All Apps button if no match was found. */ - public View getFirstMatch(ItemInfoMatcher... matchers) { - for (ItemInfoMatcher matcher : matchers) { + public View getFirstMatch(Predicate... matchers) { + for (Predicate matcher : matchers) { for (int i = 0; i < getChildCount(); i++) { View item = getChildAt(i); if (!(item.getTag() instanceof ItemInfo)) { @@ -433,7 +434,7 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar continue; } ItemInfo info = (ItemInfo) item.getTag(); - if (matcher.matchesInfo(info)) { + if (matcher.test(info)) { return item; } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java index 6416720962..0cc3590641 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java @@ -47,6 +47,7 @@ import com.android.launcher3.util.MultiValueAlpha; import com.android.quickstep.AnimatedFloat; import java.io.PrintWriter; +import java.util.function.Predicate; /** * Handles properties/data collection, then passes the results to TaskbarView to render. @@ -309,8 +310,8 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar * 2) FolderIcon of the Folder containing the given icon * 3) All Apps button */ - public View getFirstIconMatch(ItemInfoMatcher matcher) { - ItemInfoMatcher folderMatcher = ItemInfoMatcher.forFolderMatch(matcher); + public View getFirstIconMatch(Predicate matcher) { + Predicate folderMatcher = ItemInfoMatcher.forFolderMatch(matcher); return mTaskbarView.getFirstMatch(matcher, folderMatcher); } diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 7c52e806cb..4bb43431bc 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -70,7 +70,6 @@ import com.android.launcher3.uioverrides.touchcontrollers.TransposedQuickSwitchT import com.android.launcher3.uioverrides.touchcontrollers.TwoButtonNavbarTouchController; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.DisplayController.NavigationMode; -import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.PendingRequestArgs; import com.android.launcher3.util.TouchController; import com.android.launcher3.util.UiThreadHelper; @@ -86,6 +85,7 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Objects; +import java.util.function.Predicate; import java.util.stream.Stream; public class QuickstepLauncher extends BaseQuickstepLauncher { @@ -245,7 +245,7 @@ public class QuickstepLauncher extends BaseQuickstepLauncher { } @Override - public void bindWorkspaceComponentsRemoved(ItemInfoMatcher matcher) { + public void bindWorkspaceComponentsRemoved(Predicate matcher) { super.bindWorkspaceComponentsRemoved(matcher); mHotseatPredictionController.onModelItemsRemoved(matcher); } diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 4b42ecbae0..3164db206d 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -182,7 +182,6 @@ import com.android.launcher3.util.ActivityTracker; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.IntSet; -import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.OnboardingPrefs; import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.PackageUserKey; @@ -2739,9 +2738,9 @@ public class Launcher extends StatefulActivity */ public View getFirstMatchForAppClose(int preferredItemId, String packageName, UserHandle user, boolean supportsAllAppsState) { - final ItemInfoMatcher preferredItem = (info, cn) -> + final Predicate preferredItem = info -> info != null && info.id == preferredItemId; - final ItemInfoMatcher packageAndUserAndApp = (info, cn) -> + final Predicate packageAndUserAndApp = info -> info != null && info.itemType == ITEM_TYPE_APPLICATION && info.user.equals(user) @@ -2770,8 +2769,8 @@ public class Launcher extends StatefulActivity * @param operators List of operators, in order starting from best matching operator. */ private static View getFirstMatch(Iterable containers, - final ItemInfoMatcher... operators) { - for (ItemInfoMatcher operator : operators) { + final Predicate... operators) { + for (Predicate operator : operators) { for (ViewGroup container : containers) { View match = mapOverViewGroup(container, operator); if (match != null) { @@ -2786,11 +2785,11 @@ public class Launcher extends StatefulActivity * Returns the first view matching the operator in the given ViewGroups, or null if none. * Forward iteration matters. */ - private static View mapOverViewGroup(ViewGroup container, ItemInfoMatcher op) { + private static View mapOverViewGroup(ViewGroup container, Predicate op) { final int itemCount = container.getChildCount(); for (int itemIdx = 0; itemIdx < itemCount; itemIdx++) { View item = container.getChildAt(itemIdx); - if (op.matchesInfo((ItemInfo) item.getTag())) { + if (op.test((ItemInfo) item.getTag())) { return item; } } @@ -2887,7 +2886,7 @@ public class Launcher extends StatefulActivity * package-removal should clear all items by package name. */ @Override - public void bindWorkspaceComponentsRemoved(final ItemInfoMatcher matcher) { + public void bindWorkspaceComponentsRemoved(Predicate matcher) { mWorkspace.removeItemsByMatcher(matcher); mDragController.onAppsRemoved(matcher); PopupContainerWithArrow.dismissInvalidPopup(this); diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 78771ce84a..14320eb28b 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -102,7 +102,6 @@ import com.android.launcher3.util.Executors; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.IntSet; import com.android.launcher3.util.IntSparseArrayMap; -import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.LauncherBindableItemsContainer; import com.android.launcher3.util.OverlayEdgeEffect; import com.android.launcher3.util.PackageUserKey; @@ -3235,7 +3234,7 @@ public class Workspace extends PagedView * as a part of an update, this is called to ensure that other widgets and application * shortcuts are not removed. */ - public void removeItemsByMatcher(final ItemInfoMatcher matcher) { + public void removeItemsByMatcher(final Predicate matcher) { for (CellLayout layout : getWorkspaceAndHotseatCellLayouts()) { ShortcutAndWidgetContainer container = layout.getShortcutsAndWidgets(); // Iterate in reverse order as we are removing items @@ -3243,7 +3242,7 @@ public class Workspace extends PagedView View child = container.getChildAt(i); ItemInfo info = (ItemInfo) child.getTag(); - if (matcher.matchesInfo(info)) { + if (matcher.test(info)) { layout.removeViewInLayout(child); if (child instanceof DropTarget) { mDragController.removeDropTarget((DropTarget) child); @@ -3251,7 +3250,7 @@ public class Workspace extends PagedView } else if (child instanceof FolderIcon) { FolderInfo folderInfo = (FolderInfo) info; List matches = folderInfo.contents.stream() - .filter(matcher::matchesInfo) + .filter(matcher) .collect(Collectors.toList()); if (!matches.isEmpty()) { folderInfo.removeAll(matches, false); @@ -3330,7 +3329,7 @@ public class Workspace extends PagedView * * @param matcher the matcher generated by the caller. */ - public void persistRemoveItemsByMatcher(ItemInfoMatcher matcher) { + public void persistRemoveItemsByMatcher(Predicate matcher) { mLauncher.getModelWriter().deleteItemsFromDatabase(matcher); removeItemsByMatcher(matcher); } diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java index 2a16210861..cdaf80a804 100644 --- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java +++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java @@ -21,17 +21,18 @@ import android.content.Context; import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.model.data.AppInfo; -import com.android.launcher3.util.ItemInfoMatcher; +import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.util.LabelComparator; import com.android.launcher3.views.ActivityContext; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Locale; -import java.util.Map; import java.util.Objects; import java.util.TreeMap; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** * The alphabetically sorted list of applications. @@ -82,7 +83,7 @@ public class AlphabeticalAppsList implement private AppInfoComparator mAppNameComparator; private final int mNumAppsPerRowAllApps; private int mNumAppRowsInAdapter; - private ItemInfoMatcher mItemFilter; + private Predicate mItemFilter; public AlphabeticalAppsList(Context context, AllAppsStore appsStore, WorkAdapterProvider adapterProvider) { @@ -94,7 +95,7 @@ public class AlphabeticalAppsList implement mAllAppsStore.addUpdateListener(this); } - public void updateItemFilter(ItemInfoMatcher itemFilter) { + public void updateItemFilter(Predicate itemFilter) { this.mItemFilter = itemFilter; onAppsUpdated(); } @@ -200,13 +201,11 @@ public class AlphabeticalAppsList implement // Sort the list of apps mApps.clear(); - for (AppInfo app : mAllAppsStore.getApps()) { - if (mItemFilter == null || mItemFilter.matches(app, null) || hasFilter()) { - mApps.add(app); - } + Stream appSteam = Stream.of(mAllAppsStore.getApps()); + if (!hasFilter() && mItemFilter != null) { + appSteam = appSteam.filter(mItemFilter); } - - Collections.sort(mApps, mAppNameComparator); + appSteam = appSteam.sorted(mAppNameComparator); // As a special case for some languages (currently only Simplified Chinese), we may need to // coalesce sections @@ -215,27 +214,16 @@ public class AlphabeticalAppsList implement if (localeRequiresSectionSorting) { // Compute the section headers. We use a TreeMap with the section name comparator to // ensure that the sections are ordered when we iterate over it later - TreeMap> sectionMap = new TreeMap<>(new LabelComparator()); - for (AppInfo info : mApps) { - // Add the section to the cache - String sectionName = info.sectionName; - - // Add it to the mapping - ArrayList sectionApps = sectionMap.get(sectionName); - if (sectionApps == null) { - sectionApps = new ArrayList<>(); - sectionMap.put(sectionName, sectionApps); - } - sectionApps.add(info); - } - - // Add each of the section apps to the list in order - mApps.clear(); - for (Map.Entry> entry : sectionMap.entrySet()) { - mApps.addAll(entry.getValue()); - } + appSteam = appSteam.collect(Collectors.groupingBy( + info -> info.sectionName, + () -> new TreeMap<>(new LabelComparator()), + Collectors.toCollection(ArrayList::new))) + .values() + .stream() + .flatMap(ArrayList::stream); } + appSteam.forEachOrdered(mApps::add); // Recompose the set of adapter items from the current set of apps if (mSearchResults.isEmpty()) { updateAdapterItems(); diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java index f913aa9093..891fe8f53c 100644 --- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java @@ -58,7 +58,7 @@ import com.android.launcher3.Utilities; import com.android.launcher3.allapps.search.SearchAdapterProvider; import com.android.launcher3.keyboard.FocusedItemDecorator; import com.android.launcher3.model.StringCache; -import com.android.launcher3.model.data.AppInfo; +import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.Themes; import com.android.launcher3.views.ActivityContext; @@ -69,6 +69,8 @@ import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip.OnActivePag import java.util.Arrays; import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Stream; /** * Base all apps view container. @@ -91,7 +93,7 @@ public abstract class BaseAllAppsContainerView mAH; - protected final ItemInfoMatcher mPersonalMatcher = ItemInfoMatcher.ofUser( + protected final Predicate mPersonalMatcher = ItemInfoMatcher.ofUser( Process.myUserHandle()); private final SearchAdapterProvider mMainAdapterProvider; private final AllAppsStore mAllAppsStore = new AllAppsStore(); @@ -229,17 +231,10 @@ public abstract class BaseAllAppsContainerView matcher) { mAppsList.updateItemFilter(matcher); mRecyclerView = (AllAppsRecyclerView) rv; mRecyclerView.setEdgeEffectFactory(createEdgeEffectFactory()); diff --git a/src/com/android/launcher3/allapps/WorkProfileManager.java b/src/com/android/launcher3/allapps/WorkProfileManager.java index 6203cead2d..c5b02dd1f5 100644 --- a/src/com/android/launcher3/allapps/WorkProfileManager.java +++ b/src/com/android/launcher3/allapps/WorkProfileManager.java @@ -27,7 +27,6 @@ import android.os.UserHandle; import android.os.UserManager; import android.util.Log; import android.view.ViewGroup; -import android.view.WindowInsets; import androidx.annotation.IntDef; import androidx.annotation.Nullable; @@ -35,11 +34,12 @@ import androidx.annotation.RequiresApi; import com.android.launcher3.R; import com.android.launcher3.config.FeatureFlags; -import com.android.launcher3.util.ItemInfoMatcher; +import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.function.Predicate; /** * Companion class for {@link BaseAllAppsContainerView} to manage work tab and personal tab @@ -70,7 +70,7 @@ public class WorkProfileManager implements PersonalWorkSlidingTabStrip.OnActiveP private final BaseAllAppsContainerView mAllApps; private final WorkAdapterProvider mAdapterProvider; - private final ItemInfoMatcher mMatcher; + private final Predicate mMatcher; private WorkModeSwitch mWorkModeSwitch; @@ -176,7 +176,7 @@ public class WorkProfileManager implements PersonalWorkSlidingTabStrip.OnActiveP return mAdapterProvider; } - public ItemInfoMatcher getMatcher() { + public Predicate getMatcher() { return mMatcher; } diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java index fdb27998de..35cdfef465 100644 --- a/src/com/android/launcher3/dragndrop/DragController.java +++ b/src/com/android/launcher3/dragndrop/DragController.java @@ -18,7 +18,6 @@ package com.android.launcher3.dragndrop; import static com.android.launcher3.Utilities.ATLEAST_Q; -import android.content.ComponentName; import android.graphics.Point; import android.graphics.Rect; import android.graphics.drawable.Drawable; @@ -36,12 +35,12 @@ import com.android.launcher3.logging.InstanceId; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.testing.TestProtocol; -import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.TouchController; import com.android.launcher3.views.ActivityContext; import java.util.ArrayList; import java.util.Optional; +import java.util.function.Predicate; /** * Class for initiating a drag within a view or across multiple views. @@ -275,15 +274,12 @@ public abstract class DragController protected abstract void exitDrag(); - public void onAppsRemoved(ItemInfoMatcher matcher) { + public void onAppsRemoved(Predicate matcher) { // Cancel the current drag if we are removing an app that we are dragging if (mDragObject != null) { ItemInfo dragInfo = mDragObject.dragInfo; - if (dragInfo instanceof WorkspaceItemInfo) { - ComponentName cn = dragInfo.getTargetComponent(); - if (cn != null && matcher.matches(dragInfo, cn)) { - cancelDrag(); - } + if (dragInfo instanceof WorkspaceItemInfo && matcher.test(dragInfo)) { + cancelDrag(); } } } diff --git a/src/com/android/launcher3/model/AllAppsList.java b/src/com/android/launcher3/model/AllAppsList.java index b8c9762c24..4875d83942 100644 --- a/src/com/android/launcher3/model/AllAppsList.java +++ b/src/com/android/launcher3/model/AllAppsList.java @@ -36,9 +36,9 @@ import com.android.launcher3.compat.AlphabeticIndexCompat; import com.android.launcher3.icons.IconCache; import com.android.launcher3.model.BgDataModel.Callbacks; import com.android.launcher3.model.data.AppInfo; +import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.pm.PackageInstallInfo; import com.android.launcher3.util.FlagOp; -import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.SafeCloseable; @@ -47,6 +47,7 @@ import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.function.Consumer; +import java.util.function.Predicate; /** @@ -257,11 +258,11 @@ public class AllAppsList { /** * Updates the disabled flags of apps matching {@param matcher} based on {@param op}. */ - public void updateDisabledFlags(ItemInfoMatcher matcher, FlagOp op) { + public void updateDisabledFlags(Predicate matcher, FlagOp op) { final List data = this.data; for (int i = data.size() - 1; i >= 0; i--) { AppInfo info = data.get(i); - if (matcher.matches(info, info.componentName)) { + if (matcher.test(info)) { info.runtimeStatusFlags = op.apply(info.runtimeStatusFlags); mDataChanged = true; } diff --git a/src/com/android/launcher3/model/BaseModelUpdateTask.java b/src/com/android/launcher3/model/BaseModelUpdateTask.java index a3a471775c..832c1dd166 100644 --- a/src/com/android/launcher3/model/BaseModelUpdateTask.java +++ b/src/com/android/launcher3/model/BaseModelUpdateTask.java @@ -27,7 +27,6 @@ import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.util.ComponentKey; -import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.widget.model.WidgetsListBaseEntry; import java.util.ArrayList; @@ -35,6 +34,7 @@ import java.util.HashMap; import java.util.List; import java.util.Objects; import java.util.concurrent.Executor; +import java.util.function.Predicate; import java.util.stream.Collectors; /** @@ -128,7 +128,7 @@ public abstract class BaseModelUpdateTask implements ModelUpdateTask { scheduleCallbackTask(c -> c.bindAllWidgets(widgets)); } - public void deleteAndBindComponentsRemoved(final ItemInfoMatcher matcher) { + public void deleteAndBindComponentsRemoved(final Predicate matcher) { getModelWriter().deleteItemsFromDatabase(matcher); // Call the components-removed callback diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java index 866d18a86b..d52537e074 100644 --- a/src/com/android/launcher3/model/BgDataModel.java +++ b/src/com/android/launcher3/model/BgDataModel.java @@ -50,7 +50,6 @@ import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.IntSet; import com.android.launcher3.util.IntSparseArrayMap; -import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.RunnableList; import com.android.launcher3.widget.model.WidgetsListBaseEntry; @@ -66,6 +65,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Consumer; +import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -495,7 +495,7 @@ public class BgDataModel { default void bindWorkspaceItemsChanged(List updated) { } default void bindWidgetsRestored(ArrayList widgets) { } default void bindRestoreItemsChange(HashSet updates) { } - default void bindWorkspaceComponentsRemoved(ItemInfoMatcher matcher) { } + default void bindWorkspaceComponentsRemoved(Predicate matcher) { } default void bindAllWidgets(List widgets) { } default void onInitialBindComplete(IntSet boundPages, RunnableList pendingTasks) { diff --git a/src/com/android/launcher3/model/ModelWriter.java b/src/com/android/launcher3/model/ModelWriter.java index 94e06d16ce..015abe94bc 100644 --- a/src/com/android/launcher3/model/ModelWriter.java +++ b/src/com/android/launcher3/model/ModelWriter.java @@ -53,6 +53,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.StreamSupport; @@ -278,10 +279,9 @@ public class ModelWriter { /** * Removes all the items from the database matching {@param matcher}. */ - public void deleteItemsFromDatabase(ItemInfoMatcher matcher) { + public void deleteItemsFromDatabase(Predicate matcher) { deleteItemsFromDatabase(StreamSupport.stream(mBgDataModel.itemsIdMap.spliterator(), false) - .filter(matcher::matchesInfo) - .collect(Collectors.toList())); + .filter(matcher).collect(Collectors.toList())); } /** diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java index d47edff223..239dd4565a 100644 --- a/src/com/android/launcher3/model/PackageUpdatedTask.java +++ b/src/com/android/launcher3/model/PackageUpdatedTask.java @@ -57,6 +57,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.function.Predicate; /** * Handles updates due to changes in package manager (app installed/updated/removed) @@ -95,7 +96,7 @@ public class PackageUpdatedTask extends BaseModelUpdateTask { final int N = packages.length; final FlagOp flagOp; final HashSet packageSet = new HashSet<>(Arrays.asList(packages)); - final ItemInfoMatcher matcher = mOp == OP_USER_AVAILABILITY_CHANGE + final Predicate 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<>(); @@ -206,7 +207,7 @@ public class PackageUpdatedTask extends BaseModelUpdateTask { } ComponentName cn = si.getTargetComponent(); - if (cn != null && matcher.matches(si, cn)) { + if (cn != null && matcher.test(si)) { String packageName = cn.getPackageName(); if (si.hasStatusFlag(WorkspaceItemInfo.FLAG_SUPPORTS_WEB_UI)) { @@ -336,7 +337,7 @@ public class PackageUpdatedTask extends BaseModelUpdateTask { } if (!removedPackages.isEmpty() || !removedComponents.isEmpty()) { - ItemInfoMatcher removeMatch = ItemInfoMatcher.ofPackages(removedPackages, mUser) + Predicate removeMatch = ItemInfoMatcher.ofPackages(removedPackages, mUser) .or(ItemInfoMatcher.ofComponents(removedComponents, mUser)) .and(ItemInfoMatcher.ofItemIds(forceKeepShortcuts).negate()); deleteAndBindComponentsRemoved(removeMatch); diff --git a/src/com/android/launcher3/util/ItemInfoMatcher.java b/src/com/android/launcher3/util/ItemInfoMatcher.java index 7917410b3b..b6af3140fa 100644 --- a/src/com/android/launcher3/util/ItemInfoMatcher.java +++ b/src/com/android/launcher3/util/ItemInfoMatcher.java @@ -19,6 +19,8 @@ package com.android.launcher3.util; import android.content.ComponentName; import android.os.UserHandle; +import androidx.annotation.NonNull; + import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.model.data.ItemInfo; @@ -27,90 +29,64 @@ import com.android.launcher3.shortcuts.ShortcutKey; import java.util.Collection; import java.util.HashSet; import java.util.Set; +import java.util.function.Predicate; /** * A utility class to check for {@link ItemInfo} */ -public interface ItemInfoMatcher { +public abstract class ItemInfoMatcher { /** * Empty component used for match testing */ - ComponentName EMPTY_COMPONENT = new ComponentName("", ""); + private static final ComponentName EMPTY_COMPONENT = new ComponentName("", ""); - boolean matches(ItemInfo info, ComponentName cn); - - /** - * Returns true if the itemInfo matches this check - */ - default boolean matchesInfo(ItemInfo info) { - if (info != null) { - ComponentName cn = info.getTargetComponent(); - return matches(info, cn != null ? cn : EMPTY_COMPONENT); - } else { - return false; - } + public static Predicate ofUser(UserHandle user) { + return info -> info != null && info.user.equals(user); } - /** - * Returns a new matcher with returns true if either this or {@param matcher} returns true. - */ - default ItemInfoMatcher or(ItemInfoMatcher matcher) { - return (info, cn) -> matches(info, cn) || matcher.matches(info, cn); + public static Predicate ofComponents( + HashSet components, UserHandle user) { + return info -> info != null && info.user.equals(user) + && components.contains(getNonNullComponent(info)); } - /** - * Returns a new matcher with returns true if both this and {@param matcher} returns true. - */ - default ItemInfoMatcher and(ItemInfoMatcher matcher) { - return (info, cn) -> matches(info, cn) && matcher.matches(info, cn); + public static Predicate ofPackages(Set packageNames, UserHandle user) { + return info -> info != null && info.user.equals(user) + && packageNames.contains(getNonNullComponent(info).getPackageName()); } - /** - * Returns a new matcher with returns the opposite value of this. - */ - default ItemInfoMatcher negate() { - return (info, cn) -> !matches(info, cn); - } - - static ItemInfoMatcher ofUser(UserHandle user) { - return (info, cn) -> info.user.equals(user); - } - - static ItemInfoMatcher ofComponents(HashSet components, UserHandle user) { - return (info, cn) -> components.contains(cn) && info.user.equals(user); - } - - static ItemInfoMatcher ofPackages(Set packageNames, UserHandle user) { - return (info, cn) -> packageNames.contains(cn.getPackageName()) && info.user.equals(user); - } - - static ItemInfoMatcher ofShortcutKeys(Set keys) { - return (info, cn) -> info.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT + public static Predicate ofShortcutKeys(Set keys) { + return info -> info != null && info.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT && keys.contains(ShortcutKey.fromItemInfo(info)); } /** * Returns a matcher for items within folders. */ - static ItemInfoMatcher forFolderMatch(ItemInfoMatcher childOperator) { - return (info, cn) -> info instanceof FolderInfo && ((FolderInfo) info).contents.stream() - .anyMatch(childOperator::matchesInfo); + public static Predicate forFolderMatch(Predicate childOperator) { + return info -> info instanceof FolderInfo && ((FolderInfo) info).contents.stream() + .anyMatch(childOperator); } /** * Returns a matcher for items with provided ids */ - static ItemInfoMatcher ofItemIds(IntSet ids) { - return (info, cn) -> ids.contains(info.id); + public static Predicate ofItemIds(IntSet ids) { + return info -> info != null && ids.contains(info.id); } /** * Returns a matcher for items with provided items */ - static ItemInfoMatcher ofItems(Collection items) { + public static Predicate ofItems(Collection items) { IntSet ids = new IntSet(); items.forEach(item -> ids.add(item.id)); return ofItemIds(ids); } + + private static ComponentName getNonNullComponent(@NonNull ItemInfo info) { + ComponentName cn = info.getTargetComponent(); + return cn != null ? cn : EMPTY_COMPONENT; + } }