Merge "Simplifying widget search pipeline" into sc-dev
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java b/robolectric_tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
index c2bf1ae..36b6f01 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
+++ b/robolectric_tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
@@ -18,64 +18,197 @@
import static android.os.Looper.getMainLooper;
+import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.matches;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
import static org.robolectric.Shadows.shadowOf;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.ComponentName;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.os.UserHandle;
+
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.icons.BitmapInfo;
+import com.android.launcher3.icons.ComponentWithLabel;
+import com.android.launcher3.icons.IconCache;
+import com.android.launcher3.model.WidgetItem;
+import com.android.launcher3.model.data.PackageItemInfo;
+import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.search.SearchCallback;
+import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
+import com.android.launcher3.widget.model.WidgetsListContentEntry;
+import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
+import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowPackageManager;
+import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
-import java.util.function.Consumer;
@RunWith(RobolectricTestRunner.class)
public class SimpleWidgetsSearchAlgorithmTest {
+ @Mock private IconCache mIconCache;
+
+ private InvariantDeviceProfile mTestProfile;
+ private WidgetsListHeaderEntry mCalendarHeaderEntry;
+ private WidgetsListContentEntry mCalendarContentEntry;
+ private WidgetsListHeaderEntry mCameraHeaderEntry;
+ private WidgetsListContentEntry mCameraContentEntry;
+ private WidgetsListHeaderEntry mClockHeaderEntry;
+ private WidgetsListContentEntry mClockContentEntry;
+ private Context mContext;
+
private SimpleWidgetsSearchAlgorithm mSimpleWidgetsSearchAlgorithm;
@Mock
- private WidgetsPickerSearchPipeline mSearchPipeline;
+ private PopupDataProvider mDataProvider;
@Mock
private SearchCallback<WidgetsListBaseEntry> mSearchCallback;
- @Captor
- private ArgumentCaptor<Consumer<List<WidgetsListBaseEntry>>> mConsumerCaptor;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mSimpleWidgetsSearchAlgorithm = new SimpleWidgetsSearchAlgorithm(mSearchPipeline);
+ doAnswer(invocation -> {
+ ComponentWithLabel componentWithLabel = (ComponentWithLabel) invocation.getArgument(0);
+ return componentWithLabel.getComponent().getShortClassName();
+ }).when(mIconCache).getTitleNoCache(any());
+ mTestProfile = new InvariantDeviceProfile();
+ mTestProfile.numRows = 5;
+ mTestProfile.numColumns = 5;
+ mContext = RuntimeEnvironment.application;
+
+ mCalendarHeaderEntry =
+ createWidgetsHeaderEntry("com.example.android.Calendar", "Calendar", 2);
+ mCalendarContentEntry =
+ createWidgetsContentEntry("com.example.android.Calendar", "Calendar", 2);
+ mCameraHeaderEntry = createWidgetsHeaderEntry("com.example.android.Camera", "Camera", 11);
+ mCameraContentEntry = createWidgetsContentEntry("com.example.android.Camera", "Camera", 11);
+ mClockHeaderEntry = createWidgetsHeaderEntry("com.example.android.Clock", "Clock", 3);
+ mClockContentEntry = createWidgetsContentEntry("com.example.android.Clock", "Clock", 3);
+
+
+ mSimpleWidgetsSearchAlgorithm = new SimpleWidgetsSearchAlgorithm(mDataProvider);
+ doReturn(Collections.EMPTY_LIST).when(mDataProvider).getAllWidgets();
}
@Test
- public void doSearch_shouldQueryPipeline() {
- mSimpleWidgetsSearchAlgorithm.doSearch("abc", mSearchCallback);
+ public void filter_shouldMatchOnAppName() {
+ doReturn(List.of(mCalendarHeaderEntry, mCalendarContentEntry, mCameraHeaderEntry,
+ mCameraContentEntry, mClockHeaderEntry, mClockContentEntry))
+ .when(mDataProvider)
+ .getAllWidgets();
- verify(mSearchPipeline).query(eq("abc"), any());
+ assertEquals(List.of(
+ new WidgetsListSearchHeaderEntry(
+ mCalendarHeaderEntry.mPkgItem,
+ mCalendarHeaderEntry.mTitleSectionName,
+ mCalendarHeaderEntry.mWidgets),
+ mCalendarContentEntry,
+ new WidgetsListSearchHeaderEntry(
+ mCameraHeaderEntry.mPkgItem,
+ mCameraHeaderEntry.mTitleSectionName,
+ mCameraHeaderEntry.mWidgets),
+ mCameraContentEntry),
+ SimpleWidgetsSearchAlgorithm.getFilteredWidgets(mDataProvider, "Ca"));
}
@Test
- public void doSearch_shouldInformSearchCallbackOnQueryResult() {
- ArrayList<WidgetsListBaseEntry> baseEntries = new ArrayList<>();
+ public void filter_shouldMatchOnWidgetLabel() {
+ doReturn(List.of(mCalendarHeaderEntry, mCalendarContentEntry, mCameraHeaderEntry,
+ mCameraContentEntry))
+ .when(mDataProvider)
+ .getAllWidgets();
- mSimpleWidgetsSearchAlgorithm.doSearch("abc", mSearchCallback);
+ assertEquals(List.of(
+ new WidgetsListSearchHeaderEntry(
+ mCalendarHeaderEntry.mPkgItem,
+ mCalendarHeaderEntry.mTitleSectionName,
+ mCalendarHeaderEntry.mWidgets.subList(1, 2)),
+ new WidgetsListContentEntry(
+ mCalendarHeaderEntry.mPkgItem,
+ mCalendarHeaderEntry.mTitleSectionName,
+ mCalendarHeaderEntry.mWidgets.subList(1, 2)),
+ new WidgetsListSearchHeaderEntry(
+ mCameraHeaderEntry.mPkgItem,
+ mCameraHeaderEntry.mTitleSectionName,
+ mCameraHeaderEntry.mWidgets.subList(1, 3)),
+ new WidgetsListContentEntry(
+ mCameraHeaderEntry.mPkgItem,
+ mCameraHeaderEntry.mTitleSectionName,
+ mCameraHeaderEntry.mWidgets.subList(1, 3))),
+ SimpleWidgetsSearchAlgorithm.getFilteredWidgets(mDataProvider, "Widget1"));
+ }
- verify(mSearchPipeline).query(eq("abc"), mConsumerCaptor.capture());
- mConsumerCaptor.getValue().accept(baseEntries);
+ @Test
+ public void doSearch_shouldInformCallback() {
+ doReturn(List.of(mCalendarHeaderEntry, mCalendarContentEntry, mCameraHeaderEntry,
+ mCameraContentEntry, mClockHeaderEntry, mClockContentEntry))
+ .when(mDataProvider)
+ .getAllWidgets();
+ mSimpleWidgetsSearchAlgorithm.doSearch("Ca", mSearchCallback);
shadowOf(getMainLooper()).idle();
- // Verify SearchCallback#onSearchResult receives a query token along with the search
- // results. The query token is the original query string concatenated with the query
- // timestamp.
- verify(mSearchCallback).onSearchResult(matches("abc\t\\d*"), eq(baseEntries));
+ verify(mSearchCallback).onSearchResult(
+ matches("Ca"), argThat(a -> a != null && !a.isEmpty()));
+ }
+
+ private WidgetsListHeaderEntry createWidgetsHeaderEntry(String packageName, String appName,
+ int numOfWidgets) {
+ List<WidgetItem> widgetItems = generateWidgetItems(packageName, numOfWidgets);
+ PackageItemInfo pInfo = createPackageItemInfo(packageName, appName,
+ widgetItems.get(0).user);
+
+ return new WidgetsListHeaderEntry(pInfo, /* titleSectionName= */ "", widgetItems);
+ }
+
+ private WidgetsListContentEntry createWidgetsContentEntry(String packageName, String appName,
+ int numOfWidgets) {
+ List<WidgetItem> widgetItems = generateWidgetItems(packageName, numOfWidgets);
+ PackageItemInfo pInfo = createPackageItemInfo(packageName, appName,
+ widgetItems.get(0).user);
+
+ return new WidgetsListContentEntry(pInfo, /* titleSectionName= */ "", widgetItems);
+ }
+
+ private PackageItemInfo createPackageItemInfo(String packageName, String appName,
+ UserHandle userHandle) {
+ PackageItemInfo pInfo = new PackageItemInfo(packageName);
+ pInfo.title = appName;
+ pInfo.user = userHandle;
+ pInfo.bitmap = BitmapInfo.of(Bitmap.createBitmap(10, 10, Bitmap.Config.ALPHA_8), 0);
+ return pInfo;
+ }
+
+ private List<WidgetItem> generateWidgetItems(String packageName, int numOfWidgets) {
+ ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
+ ArrayList<WidgetItem> widgetItems = new ArrayList<>();
+ for (int i = 0; i < numOfWidgets; i++) {
+ ComponentName cn = ComponentName.createRelative(packageName, ".SampleWidget" + i);
+ AppWidgetProviderInfo widgetInfo = new AppWidgetProviderInfo();
+ widgetInfo.provider = cn;
+ ReflectionHelpers.setField(widgetInfo, "providerInfo",
+ packageManager.addReceiverIfNotPresent(cn));
+
+ WidgetItem widgetItem = new WidgetItem(
+ LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
+ mTestProfile, mIconCache);
+ widgetItems.add(widgetItem);
+ }
+ return widgetItems;
}
}
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchPipelineTest.java b/robolectric_tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchPipelineTest.java
deleted file mode 100644
index 17ededd..0000000
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchPipelineTest.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.widget.picker.search;
-
-import static android.os.Looper.getMainLooper;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.robolectric.Shadows.shadowOf;
-
-import android.appwidget.AppWidgetProviderInfo;
-import android.content.ComponentName;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.os.UserHandle;
-
-import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.icons.BitmapInfo;
-import com.android.launcher3.icons.ComponentWithLabel;
-import com.android.launcher3.icons.IconCache;
-import com.android.launcher3.model.WidgetItem;
-import com.android.launcher3.model.data.PackageItemInfo;
-import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
-import com.android.launcher3.widget.model.WidgetsListContentEntry;
-import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
-import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.shadows.ShadowPackageManager;
-import org.robolectric.util.ReflectionHelpers;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@RunWith(RobolectricTestRunner.class)
-public class SimpleWidgetsSearchPipelineTest {
- @Mock private IconCache mIconCache;
-
- private InvariantDeviceProfile mTestProfile;
- private WidgetsListHeaderEntry mCalendarHeaderEntry;
- private WidgetsListContentEntry mCalendarContentEntry;
- private WidgetsListHeaderEntry mCameraHeaderEntry;
- private WidgetsListContentEntry mCameraContentEntry;
- private WidgetsListHeaderEntry mClockHeaderEntry;
- private WidgetsListContentEntry mClockContentEntry;
- private Context mContext;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- doAnswer(invocation -> {
- ComponentWithLabel componentWithLabel = (ComponentWithLabel) invocation.getArgument(0);
- return componentWithLabel.getComponent().getShortClassName();
- }).when(mIconCache).getTitleNoCache(any());
- mTestProfile = new InvariantDeviceProfile();
- mTestProfile.numRows = 5;
- mTestProfile.numColumns = 5;
- mContext = RuntimeEnvironment.application;
-
- mCalendarHeaderEntry =
- createWidgetsHeaderEntry("com.example.android.Calendar", "Calendar", 2);
- mCalendarContentEntry =
- createWidgetsContentEntry("com.example.android.Calendar", "Calendar", 2);
- mCameraHeaderEntry = createWidgetsHeaderEntry("com.example.android.Camera", "Camera", 11);
- mCameraContentEntry = createWidgetsContentEntry("com.example.android.Camera", "Camera", 11);
- mClockHeaderEntry = createWidgetsHeaderEntry("com.example.android.Clock", "Clock", 3);
- mClockContentEntry = createWidgetsContentEntry("com.example.android.Clock", "Clock", 3);
- }
-
- @Test
- public void query_shouldMatchOnAppName() {
- SimpleWidgetsSearchPipeline pipeline = new SimpleWidgetsSearchPipeline(
- List.of(mCalendarHeaderEntry, mCalendarContentEntry, mCameraHeaderEntry,
- mCameraContentEntry, mClockHeaderEntry, mClockContentEntry));
-
- pipeline.query("Ca", results ->
- assertEquals(results,
- List.of(
- new WidgetsListSearchHeaderEntry(
- mCalendarHeaderEntry.mPkgItem,
- mCalendarHeaderEntry.mTitleSectionName,
- mCalendarHeaderEntry.mWidgets),
- mCalendarContentEntry,
- new WidgetsListSearchHeaderEntry(
- mCameraHeaderEntry.mPkgItem,
- mCameraHeaderEntry.mTitleSectionName,
- mCameraHeaderEntry.mWidgets),
- mCameraContentEntry)));
- shadowOf(getMainLooper()).idle();
- }
-
- @Test
- public void query_shouldMatchOnWidgetLabel() {
- SimpleWidgetsSearchPipeline pipeline = new SimpleWidgetsSearchPipeline(
- List.of(mCalendarHeaderEntry, mCalendarContentEntry, mCameraHeaderEntry,
- mCameraContentEntry));
-
- pipeline.query("Widget1", results ->
- assertEquals(results,
- List.of(
- new WidgetsListSearchHeaderEntry(
- mCalendarHeaderEntry.mPkgItem,
- mCalendarHeaderEntry.mTitleSectionName,
- mCalendarHeaderEntry.mWidgets.subList(1, 2)),
- new WidgetsListContentEntry(
- mCalendarHeaderEntry.mPkgItem,
- mCalendarHeaderEntry.mTitleSectionName,
- mCalendarHeaderEntry.mWidgets.subList(1, 2)),
- new WidgetsListSearchHeaderEntry(
- mCameraHeaderEntry.mPkgItem,
- mCameraHeaderEntry.mTitleSectionName,
- mCameraHeaderEntry.mWidgets.subList(1, 3)),
- new WidgetsListContentEntry(
- mCameraHeaderEntry.mPkgItem,
- mCameraHeaderEntry.mTitleSectionName,
- mCameraHeaderEntry.mWidgets.subList(1, 3)))));
- shadowOf(getMainLooper()).idle();
- }
-
- private WidgetsListHeaderEntry createWidgetsHeaderEntry(String packageName, String appName,
- int numOfWidgets) {
- List<WidgetItem> widgetItems = generateWidgetItems(packageName, numOfWidgets);
- PackageItemInfo pInfo = createPackageItemInfo(packageName, appName,
- widgetItems.get(0).user);
-
- return new WidgetsListHeaderEntry(pInfo, /* titleSectionName= */ "", widgetItems);
- }
-
- private WidgetsListContentEntry createWidgetsContentEntry(String packageName, String appName,
- int numOfWidgets) {
- List<WidgetItem> widgetItems = generateWidgetItems(packageName, numOfWidgets);
- PackageItemInfo pInfo = createPackageItemInfo(packageName, appName,
- widgetItems.get(0).user);
-
- return new WidgetsListContentEntry(pInfo, /* titleSectionName= */ "", widgetItems);
- }
-
- private PackageItemInfo createPackageItemInfo(String packageName, String appName,
- UserHandle userHandle) {
- PackageItemInfo pInfo = new PackageItemInfo(packageName);
- pInfo.title = appName;
- pInfo.user = userHandle;
- pInfo.bitmap = BitmapInfo.of(Bitmap.createBitmap(10, 10, Bitmap.Config.ALPHA_8), 0);
- return pInfo;
- }
-
- private List<WidgetItem> generateWidgetItems(String packageName, int numOfWidgets) {
- ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
- ArrayList<WidgetItem> widgetItems = new ArrayList<>();
- for (int i = 0; i < numOfWidgets; i++) {
- ComponentName cn = ComponentName.createRelative(packageName, ".SampleWidget" + i);
- AppWidgetProviderInfo widgetInfo = new AppWidgetProviderInfo();
- widgetInfo.provider = cn;
- ReflectionHelpers.setField(widgetInfo, "providerInfo",
- packageManager.addReceiverIfNotPresent(cn));
-
- WidgetItem widgetItem = new WidgetItem(
- LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
- mTestProfile, mIconCache);
- widgetItems.add(widgetItem);
- }
- return widgetItems;
- }
-}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index d13884a..a4257a2 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -169,7 +169,7 @@
onWidgetsBound();
mSearchAndRecommendationViewHolder.mSearchBar.initialize(
- mLauncher.getPopupDataProvider().getAllWidgets(), /* searchModeListener= */ this);
+ mLauncher.getPopupDataProvider(), /* searchModeListener= */ this);
}
@Override
diff --git a/src/com/android/launcher3/widget/picker/search/LauncherWidgetsSearchBar.java b/src/com/android/launcher3/widget/picker/search/LauncherWidgetsSearchBar.java
index 56a08b1..42f1bb2 100644
--- a/src/com/android/launcher3/widget/picker/search/LauncherWidgetsSearchBar.java
+++ b/src/com/android/launcher3/widget/picker/search/LauncherWidgetsSearchBar.java
@@ -26,10 +26,7 @@
import com.android.launcher3.ExtendedEditText;
import com.android.launcher3.R;
-import com.android.launcher3.search.SearchAlgorithm;
-import com.android.launcher3.widget.model.WidgetsListBaseEntry;
-
-import java.util.List;
+import com.android.launcher3.popup.PopupDataProvider;
/**
* View for a search bar with an edit text with a cancel button.
@@ -54,12 +51,10 @@
}
@Override
- public void initialize(List<WidgetsListBaseEntry> allWidgets,
- SearchModeListener searchModeListener) {
- SearchAlgorithm<WidgetsListBaseEntry> algo =
- new SimpleWidgetsSearchAlgorithm(new SimpleWidgetsSearchPipeline(allWidgets));
+ public void initialize(PopupDataProvider dataProvider, SearchModeListener searchModeListener) {
mController = new WidgetsSearchBarController(
- algo, mEditText, mCancelButton, searchModeListener);
+ new SimpleWidgetsSearchAlgorithm(dataProvider),
+ mEditText, mCancelButton, searchModeListener);
}
@Override
diff --git a/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithm.java b/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithm.java
index 15d2454..9be3b5f 100644
--- a/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithm.java
+++ b/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithm.java
@@ -16,42 +16,41 @@
package com.android.launcher3.widget.picker.search;
-import android.os.Handler;
-import android.util.Log;
+import static com.android.launcher3.search.StringMatcherUtility.matches;
+import android.os.Handler;
+
+import com.android.launcher3.model.WidgetItem;
+import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.search.SearchAlgorithm;
import com.android.launcher3.search.SearchCallback;
+import com.android.launcher3.search.StringMatcherUtility.StringMatcher;
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
+import com.android.launcher3.widget.model.WidgetsListContentEntry;
+import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
+import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry;
import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
/**
* Implementation of {@link SearchAlgorithm} that posts a task to query on the main thread.
*/
public final class SimpleWidgetsSearchAlgorithm implements SearchAlgorithm<WidgetsListBaseEntry> {
- private static final boolean DEBUG = false;
- private static final String TAG = "SimpleWidgetsSearchAlgo";
- private static final String DELIM = "\t";
-
private final Handler mResultHandler;
- private final WidgetsPickerSearchPipeline mSearchPipeline;
+ private final PopupDataProvider mDataProvider;
- public SimpleWidgetsSearchAlgorithm(WidgetsPickerSearchPipeline searchPipeline) {
+ public SimpleWidgetsSearchAlgorithm(PopupDataProvider dataProvider) {
mResultHandler = new Handler();
- mSearchPipeline = searchPipeline;
+ mDataProvider = dataProvider;
}
@Override
public void doSearch(String query, SearchCallback<WidgetsListBaseEntry> callback) {
- long startTime = System.currentTimeMillis();
- String queryToken = query + DELIM + startTime;
- if (DEBUG) {
- Log.d(TAG, "doSearch queryToken:" + queryToken);
- }
- mSearchPipeline.query(query,
- results -> mResultHandler.post(
- () -> callback.onSearchResult(queryToken, new ArrayList(results))));
+ ArrayList<WidgetsListBaseEntry> result = getFilteredWidgets(mDataProvider, query);
+ mResultHandler.post(() -> callback.onSearchResult(query, result));
}
@Override
@@ -60,4 +59,36 @@
mResultHandler.removeCallbacksAndMessages(/*token= */null);
}
}
+
+ /**
+ * Returns entries for all matched widgets
+ */
+ public static ArrayList<WidgetsListBaseEntry> getFilteredWidgets(
+ PopupDataProvider dataProvider, String input) {
+ ArrayList<WidgetsListBaseEntry> results = new ArrayList<>();
+ dataProvider.getAllWidgets().stream()
+ .filter(entry -> entry instanceof WidgetsListHeaderEntry)
+ .forEach(headerEntry -> {
+ List<WidgetItem> matchedWidgetItems = filterWidgetItems(
+ input, headerEntry.mPkgItem.title.toString(), headerEntry.mWidgets);
+ if (matchedWidgetItems.size() > 0) {
+ results.add(new WidgetsListSearchHeaderEntry(headerEntry.mPkgItem,
+ headerEntry.mTitleSectionName, matchedWidgetItems));
+ results.add(new WidgetsListContentEntry(headerEntry.mPkgItem,
+ headerEntry.mTitleSectionName, matchedWidgetItems));
+ }
+ });
+ return results;
+ }
+
+ private static List<WidgetItem> filterWidgetItems(String query, String packageTitle,
+ List<WidgetItem> items) {
+ StringMatcher matcher = StringMatcher.getInstance();
+ if (matches(query, packageTitle, matcher)) {
+ return items;
+ }
+ return items.stream()
+ .filter(item -> matches(query, item.label, matcher))
+ .collect(Collectors.toList());
+ }
}
diff --git a/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchPipeline.java b/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchPipeline.java
deleted file mode 100644
index 5222e8e..0000000
--- a/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchPipeline.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.widget.picker.search;
-
-import static com.android.launcher3.search.StringMatcherUtility.matches;
-
-import com.android.launcher3.model.WidgetItem;
-import com.android.launcher3.search.StringMatcherUtility.StringMatcher;
-import com.android.launcher3.widget.model.WidgetsListBaseEntry;
-import com.android.launcher3.widget.model.WidgetsListContentEntry;
-import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
-import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Consumer;
-import java.util.stream.Collectors;
-
-/**
- * Implementation of {@link WidgetsPickerSearchPipeline} that performs search by prefix matching on
- * app names and widget labels.
- */
-public final class SimpleWidgetsSearchPipeline implements WidgetsPickerSearchPipeline {
-
- private final List<WidgetsListBaseEntry> mAllEntries;
-
- public SimpleWidgetsSearchPipeline(List<WidgetsListBaseEntry> allEntries) {
- mAllEntries = allEntries;
- }
-
- @Override
- public void query(String input, Consumer<List<WidgetsListBaseEntry>> callback) {
- ArrayList<WidgetsListBaseEntry> results = new ArrayList<>();
- mAllEntries.stream().filter(entry -> entry instanceof WidgetsListHeaderEntry)
- .forEach(headerEntry -> {
- List<WidgetItem> matchedWidgetItems = filterWidgetItems(
- input, headerEntry.mPkgItem.title.toString(), headerEntry.mWidgets);
- if (matchedWidgetItems.size() > 0) {
- results.add(new WidgetsListSearchHeaderEntry(headerEntry.mPkgItem,
- headerEntry.mTitleSectionName, matchedWidgetItems));
- results.add(new WidgetsListContentEntry(headerEntry.mPkgItem,
- headerEntry.mTitleSectionName, matchedWidgetItems));
- }
- });
- callback.accept(results);
- }
-
- private List<WidgetItem> filterWidgetItems(String query, String packageTitle,
- List<WidgetItem> items) {
- StringMatcher matcher = StringMatcher.getInstance();
- if (matches(query, packageTitle, matcher)) {
- return items;
- }
- return items.stream()
- .filter(item -> matches(query, item.label, matcher))
- .collect(Collectors.toList());
- }
-}
diff --git a/src/com/android/launcher3/widget/picker/search/WidgetsPickerSearchPipeline.java b/src/com/android/launcher3/widget/picker/search/WidgetsPickerSearchPipeline.java
deleted file mode 100644
index d12782c..0000000
--- a/src/com/android/launcher3/widget/picker/search/WidgetsPickerSearchPipeline.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.widget.picker.search;
-
-import com.android.launcher3.widget.model.WidgetsListBaseEntry;
-
-import java.util.List;
-import java.util.function.Consumer;
-
-/**
- * An interface for a pipeline to handle widgets search.
- */
-public interface WidgetsPickerSearchPipeline {
-
- /**
- * Performs a search query asynchronically. Invokes {@code callback} when the search is
- * complete.
- */
- void query(String input, Consumer<List<WidgetsListBaseEntry>> callback);
-
- /**
- * Cancels any ongoing search request.
- */
- default void cancel() {};
-
- /**
- * Cleans up after search is no longer needed.
- */
- default void destroy() {};
-}
diff --git a/src/com/android/launcher3/widget/picker/search/WidgetsSearchBar.java b/src/com/android/launcher3/widget/picker/search/WidgetsSearchBar.java
index 3ac82c0..0ac47ce 100644
--- a/src/com/android/launcher3/widget/picker/search/WidgetsSearchBar.java
+++ b/src/com/android/launcher3/widget/picker/search/WidgetsSearchBar.java
@@ -16,9 +16,7 @@
package com.android.launcher3.widget.picker.search;
-import com.android.launcher3.widget.model.WidgetsListBaseEntry;
-
-import java.util.List;
+import com.android.launcher3.popup.PopupDataProvider;
/**
* Interface for a widgets picker search bar.
@@ -27,7 +25,7 @@
/**
* Attaches a controller to the search bar which interacts with {@code searchModeListener}.
*/
- void initialize(List<WidgetsListBaseEntry> allWidgets, SearchModeListener searchModeListener);
+ void initialize(PopupDataProvider dataProvider, SearchModeListener searchModeListener);
/**
* Clears search bar.