Replacing ItemInfoMatcher with predicate
This removed unnecessary componentName lookups when it
is not required. Many checks just rely on IDs and
userHandle
Bug: 231153610
Test: Presubmit
Change-Id: Ief93954abc5861062a9f55dc2ef181d3de106c62
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 4b42ecb..3164db2 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -182,7 +182,6 @@
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 View getFirstMatchForAppClose(int preferredItemId, String packageName, UserHandle user,
boolean supportsAllAppsState) {
- final ItemInfoMatcher preferredItem = (info, cn) ->
+ final Predicate<ItemInfo> preferredItem = info ->
info != null && info.id == preferredItemId;
- final ItemInfoMatcher packageAndUserAndApp = (info, cn) ->
+ final Predicate<ItemInfo> packageAndUserAndApp = info ->
info != null
&& info.itemType == ITEM_TYPE_APPLICATION
&& info.user.equals(user)
@@ -2770,8 +2769,8 @@
* @param operators List of operators, in order starting from best matching operator.
*/
private static View getFirstMatch(Iterable<ViewGroup> containers,
- final ItemInfoMatcher... operators) {
- for (ItemInfoMatcher operator : operators) {
+ final Predicate<ItemInfo>... operators) {
+ for (Predicate<ItemInfo> operator : operators) {
for (ViewGroup container : containers) {
View match = mapOverViewGroup(container, operator);
if (match != null) {
@@ -2786,11 +2785,11 @@
* 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<ItemInfo> 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 @@
* package-removal should clear all items by package name.
*/
@Override
- public void bindWorkspaceComponentsRemoved(final ItemInfoMatcher matcher) {
+ public void bindWorkspaceComponentsRemoved(Predicate<ItemInfo> 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 78771ce..14320eb 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -102,7 +102,6 @@
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 @@
* 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<ItemInfo> matcher) {
for (CellLayout layout : getWorkspaceAndHotseatCellLayouts()) {
ShortcutAndWidgetContainer container = layout.getShortcutsAndWidgets();
// Iterate in reverse order as we are removing items
@@ -3243,7 +3242,7 @@
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 @@
} else if (child instanceof FolderIcon) {
FolderInfo folderInfo = (FolderInfo) info;
List<WorkspaceItemInfo> matches = folderInfo.contents.stream()
- .filter(matcher::matchesInfo)
+ .filter(matcher)
.collect(Collectors.toList());
if (!matches.isEmpty()) {
folderInfo.removeAll(matches, false);
@@ -3330,7 +3329,7 @@
*
* @param matcher the matcher generated by the caller.
*/
- public void persistRemoveItemsByMatcher(ItemInfoMatcher matcher) {
+ public void persistRemoveItemsByMatcher(Predicate<ItemInfo> 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 2a16210..cdaf80a 100644
--- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
+++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
@@ -21,17 +21,18 @@
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 @@
private AppInfoComparator mAppNameComparator;
private final int mNumAppsPerRowAllApps;
private int mNumAppRowsInAdapter;
- private ItemInfoMatcher mItemFilter;
+ private Predicate<ItemInfo> mItemFilter;
public AlphabeticalAppsList(Context context, AllAppsStore appsStore,
WorkAdapterProvider adapterProvider) {
@@ -94,7 +95,7 @@
mAllAppsStore.addUpdateListener(this);
}
- public void updateItemFilter(ItemInfoMatcher itemFilter) {
+ public void updateItemFilter(Predicate<ItemInfo> itemFilter) {
this.mItemFilter = itemFilter;
onAppsUpdated();
}
@@ -200,13 +201,11 @@
// Sort the list of apps
mApps.clear();
- for (AppInfo app : mAllAppsStore.getApps()) {
- if (mItemFilter == null || mItemFilter.matches(app, null) || hasFilter()) {
- mApps.add(app);
- }
+ Stream<AppInfo> 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 @@
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<String, ArrayList<AppInfo>> 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<AppInfo> 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<String, ArrayList<AppInfo>> 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 f913aa9..891fe8f 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.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 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 @@
/** Context of an activity or window that is inflating this container. */
protected final T mActivityContext;
protected final List<AdapterHolder> mAH;
- protected final ItemInfoMatcher mPersonalMatcher = ItemInfoMatcher.ofUser(
+ protected final Predicate<ItemInfo> mPersonalMatcher = ItemInfoMatcher.ofUser(
Process.myUserHandle());
private final SearchAdapterProvider<?> mMainAdapterProvider;
private final AllAppsStore mAllAppsStore = new AllAppsStore();
@@ -229,17 +231,10 @@
}
private void onAppsUpdated() {
- boolean hasWorkApps = false;
- for (AppInfo app : mAllAppsStore.getApps()) {
- if (mWorkManager.getMatcher().matches(app, null)) {
- hasWorkApps = true;
- break;
- }
- }
- mHasWorkApps = hasWorkApps;
+ mHasWorkApps = Stream.of(mAllAppsStore.getApps()).anyMatch(mWorkManager.getMatcher());
if (!mAH.get(AdapterHolder.MAIN).mAppsList.hasFilter()) {
rebindAdapters();
- if (hasWorkApps) {
+ if (mHasWorkApps) {
mWorkManager.reset();
}
}
@@ -731,7 +726,7 @@
mLayoutManager = adapter.getLayoutManager();
}
- void setup(@NonNull View rv, @Nullable ItemInfoMatcher matcher) {
+ void setup(@NonNull View rv, @Nullable Predicate<ItemInfo> 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 6203cea..c5b02dd 100644
--- a/src/com/android/launcher3/allapps/WorkProfileManager.java
+++ b/src/com/android/launcher3/allapps/WorkProfileManager.java
@@ -27,7 +27,6 @@
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 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 @@
private final BaseAllAppsContainerView<?> mAllApps;
private final WorkAdapterProvider mAdapterProvider;
- private final ItemInfoMatcher mMatcher;
+ private final Predicate<ItemInfo> mMatcher;
private WorkModeSwitch mWorkModeSwitch;
@@ -176,7 +176,7 @@
return mAdapterProvider;
}
- public ItemInfoMatcher getMatcher() {
+ public Predicate<ItemInfo> getMatcher() {
return mMatcher;
}
diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java
index fdb2799..35cdfef 100644
--- a/src/com/android/launcher3/dragndrop/DragController.java
+++ b/src/com/android/launcher3/dragndrop/DragController.java
@@ -18,7 +18,6 @@
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.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 @@
protected abstract void exitDrag();
- public void onAppsRemoved(ItemInfoMatcher matcher) {
+ public void onAppsRemoved(Predicate<ItemInfo> 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 b8c9762..4875d83 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.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.HashSet;
import java.util.List;
import java.util.function.Consumer;
+import java.util.function.Predicate;
/**
@@ -257,11 +258,11 @@
/**
* Updates the disabled flags of apps matching {@param matcher} based on {@param op}.
*/
- public void updateDisabledFlags(ItemInfoMatcher matcher, FlagOp op) {
+ public void updateDisabledFlags(Predicate<ItemInfo> matcher, FlagOp op) {
final List<AppInfo> 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 a3a4717..832c1dd 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.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.List;
import java.util.Objects;
import java.util.concurrent.Executor;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
@@ -128,7 +128,7 @@
scheduleCallbackTask(c -> c.bindAllWidgets(widgets));
}
- public void deleteAndBindComponentsRemoved(final ItemInfoMatcher matcher) {
+ public void deleteAndBindComponentsRemoved(final Predicate<ItemInfo> 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 866d18a..d52537e 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.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.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 @@
default void bindWorkspaceItemsChanged(List<WorkspaceItemInfo> updated) { }
default void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets) { }
default void bindRestoreItemsChange(HashSet<ItemInfo> updates) { }
- default void bindWorkspaceComponentsRemoved(ItemInfoMatcher matcher) { }
+ default void bindWorkspaceComponentsRemoved(Predicate<ItemInfo> matcher) { }
default void bindAllWidgets(List<WidgetsListBaseEntry> 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 94e06d1..015abe9 100644
--- a/src/com/android/launcher3/model/ModelWriter.java
+++ b/src/com/android/launcher3/model/ModelWriter.java
@@ -53,6 +53,7 @@
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 @@
/**
* Removes all the items from the database matching {@param matcher}.
*/
- public void deleteItemsFromDatabase(ItemInfoMatcher matcher) {
+ public void deleteItemsFromDatabase(Predicate<ItemInfo> 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 d47edff..239dd45 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -57,6 +57,7 @@
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 @@
final int N = packages.length;
final FlagOp flagOp;
final HashSet<String> packageSet = new HashSet<>(Arrays.asList(packages));
- final ItemInfoMatcher matcher = mOp == OP_USER_AVAILABILITY_CHANGE
+ final Predicate<ItemInfo> matcher = mOp == OP_USER_AVAILABILITY_CHANGE
? ItemInfoMatcher.ofUser(mUser) // We want to update all packages for this user
: ItemInfoMatcher.ofPackages(packageSet, mUser);
final HashSet<ComponentName> removedComponents = new HashSet<>();
@@ -206,7 +207,7 @@
}
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 @@
}
if (!removedPackages.isEmpty() || !removedComponents.isEmpty()) {
- ItemInfoMatcher removeMatch = ItemInfoMatcher.ofPackages(removedPackages, mUser)
+ Predicate<ItemInfo> 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 7917410..b6af314 100644
--- a/src/com/android/launcher3/util/ItemInfoMatcher.java
+++ b/src/com/android/launcher3/util/ItemInfoMatcher.java
@@ -19,6 +19,8 @@
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 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<ItemInfo> 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<ItemInfo> ofComponents(
+ HashSet<ComponentName> 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<ItemInfo> ofPackages(Set<String> 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<ComponentName> components, UserHandle user) {
- return (info, cn) -> components.contains(cn) && info.user.equals(user);
- }
-
- static ItemInfoMatcher ofPackages(Set<String> packageNames, UserHandle user) {
- return (info, cn) -> packageNames.contains(cn.getPackageName()) && info.user.equals(user);
- }
-
- static ItemInfoMatcher ofShortcutKeys(Set<ShortcutKey> keys) {
- return (info, cn) -> info.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT
+ public static Predicate<ItemInfo> ofShortcutKeys(Set<ShortcutKey> 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<ItemInfo> forFolderMatch(Predicate<ItemInfo> 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<ItemInfo> ofItemIds(IntSet ids) {
+ return info -> info != null && ids.contains(info.id);
}
/**
* Returns a matcher for items with provided items
*/
- static ItemInfoMatcher ofItems(Collection<? extends ItemInfo> items) {
+ public static Predicate<ItemInfo> ofItems(Collection<? extends ItemInfo> 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;
+ }
}