Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 04e9f39f authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Simplifying all-apps seach pipeline

Bug: 183607616
Test: Verified on device
Change-Id: Id7ded3c244b747a577cdfcf298db6dddf19fa4eb
parent 8a5e0c8e
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -234,7 +234,6 @@ public class QuickstepLauncher extends BaseQuickstepLauncher {
    @Override
    public void onDestroy() {
        super.onDestroy();
        getAppsView().getSearchUiManager().destroySearch();
        mHotseatPredictionController.destroy();
    }

+0 −5
Original line number Diff line number Diff line
@@ -48,11 +48,6 @@ public interface SearchUiManager {
     */
    float getScrollRangeDelta(Rect insets);

    /**
     * Called when activity is destroyed. Used to close search system services
     */
    default void destroySearch() { }

    /**
     * @return the edit text object
     */
+1 −2
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.ExtendedEditText;
import com.android.launcher3.Insettable;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItem;
@@ -136,7 +135,7 @@ public class AppsSearchContainerLayout extends ExtendedEditText
        mApps = appsView.getApps();
        mAppsView = appsView;
        mSearchBarController.initialize(
                new DefaultAppSearchAlgorithm(mLauncher, LauncherAppState.getInstance(mLauncher)),
                new DefaultAppSearchAlgorithm(mLauncher),
                this, mLauncher, this);
    }

+0 −85
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.allapps.search;

import android.content.Context;
import android.os.CancellationSignal;

import com.android.launcher3.LauncherAppState;
import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItem;
import com.android.launcher3.model.AllAppsList;
import com.android.launcher3.model.BaseModelUpdateTask;
import com.android.launcher3.model.BgDataModel;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.search.StringMatcherUtility;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

/**
 * A device search section for handling app searches
 */
public class AppsSearchPipeline implements SearchPipeline {

    private static final int MAX_RESULTS_COUNT = 5;

    private final LauncherAppState mLauncherAppState;

    public AppsSearchPipeline(Context context, LauncherAppState launcherAppState) {
        mLauncherAppState = launcherAppState;
    }

    @Override
    public void query(String input, Consumer<ArrayList<AdapterItem>> callback,
            CancellationSignal cancellationSignal) {
        mLauncherAppState.getModel().enqueueModelUpdateTask(new BaseModelUpdateTask() {
            @Override
            public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
                List<AppInfo> matchingResults = getTitleMatchResult(apps.data, input);
                callback.accept(getAdapterItems(matchingResults));
            }
        });
    }

    /**
     * Filters {@link AppInfo}s matching specified query
     */
    public static ArrayList<AppInfo> getTitleMatchResult(List<AppInfo> apps, String query) {
        // Do an intersection of the words in the query and each title, and filter out all the
        // apps that don't match all of the words in the query.
        final String queryTextLower = query.toLowerCase();
        final ArrayList<AppInfo> result = new ArrayList<>();
        StringMatcherUtility.StringMatcher matcher =
                StringMatcherUtility.StringMatcher.getInstance();
        for (AppInfo info : apps) {
            if (StringMatcherUtility.matches(queryTextLower, info.title.toString(), matcher)) {
                result.add(info);
            }
        }
        return result;
    }

    private ArrayList<AdapterItem> getAdapterItems(List<AppInfo> matchingApps) {
        ArrayList<AdapterItem> items = new ArrayList<>();
        for (int i = 0; i < matchingApps.size() && i < MAX_RESULTS_COUNT; i++) {
            AdapterItem appItem = AdapterItem.asApp(i, "", matchingApps.get(i), i);
            items.add(appItem);
        }

        return items;
    }
}
+52 −11
Original line number Diff line number Diff line
@@ -15,25 +15,39 @@
 */
package com.android.launcher3.allapps.search;

import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;

import android.content.Context;
import android.os.Handler;

import androidx.annotation.AnyThread;

import com.android.launcher3.LauncherAppState;
import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItem;
import com.android.launcher3.model.AllAppsList;
import com.android.launcher3.model.BaseModelUpdateTask;
import com.android.launcher3.model.BgDataModel;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.search.SearchAlgorithm;
import com.android.launcher3.search.SearchCallback;
import com.android.launcher3.search.StringMatcherUtility;

import java.util.ArrayList;
import java.util.List;

/**
 * The default search implementation.
 */
public class DefaultAppSearchAlgorithm implements SearchAlgorithm<AdapterItem> {

    protected final Handler mResultHandler;
    private final AppsSearchPipeline mAppsSearchPipeline;
    private static final int MAX_RESULTS_COUNT = 5;

    private final LauncherAppState mAppState;
    private final Handler mResultHandler;

    public DefaultAppSearchAlgorithm(Context context, LauncherAppState launcherAppState) {
        mResultHandler = new Handler();
        mAppsSearchPipeline = new AppsSearchPipeline(context, launcherAppState);
    public DefaultAppSearchAlgorithm(Context context) {
        mAppState = LauncherAppState.getInstance(context);
        mResultHandler = new Handler(MAIN_EXECUTOR.getLooper());
    }

    @Override
@@ -44,11 +58,38 @@ public class DefaultAppSearchAlgorithm implements SearchAlgorithm<AdapterItem> {
    }

    @Override
    public void doSearch(final String query,
            final SearchCallback<AdapterItem> callback) {
        mAppsSearchPipeline.query(query,
                results -> mResultHandler.post(
                        () -> callback.onSearchResult(query, results)),
                null);
    public void doSearch(String query, SearchCallback<AdapterItem> callback) {
        mAppState.getModel().enqueueModelUpdateTask(new BaseModelUpdateTask() {
            @Override
            public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
                ArrayList<AdapterItem> result = getTitleMatchResult(apps.data, query);
                mResultHandler.post(() -> callback.onSearchResult(query, result));
            }
        });
    }

    /**
     * Filters {@link AppInfo}s matching specified query
     */
    @AnyThread
    public static ArrayList<AdapterItem> getTitleMatchResult(List<AppInfo> apps, String query) {
        // Do an intersection of the words in the query and each title, and filter out all the
        // apps that don't match all of the words in the query.
        final String queryTextLower = query.toLowerCase();
        final ArrayList<AdapterItem> result = new ArrayList<>();
        StringMatcherUtility.StringMatcher matcher =
                StringMatcherUtility.StringMatcher.getInstance();

        int resultCount = 0;
        int total = apps.size();
        for (int i = 0; i < total && resultCount < MAX_RESULTS_COUNT; i++) {
            AppInfo info = apps.get(i);
            if (StringMatcherUtility.matches(queryTextLower, info.title.toString(), matcher)) {
                AdapterItem appItem = AdapterItem.asApp(resultCount, "", info, resultCount);
                result.add(appItem);
                resultCount++;
            }
        }
        return result;
    }
}
Loading