diff --git a/lawnchair/src/app/lawnchair/allapps/AllAppsSearchInput.kt b/lawnchair/src/app/lawnchair/allapps/AllAppsSearchInput.kt index dfdfcbb417..c7ae7ca319 100644 --- a/lawnchair/src/app/lawnchair/allapps/AllAppsSearchInput.kt +++ b/lawnchair/src/app/lawnchair/allapps/AllAppsSearchInput.kt @@ -90,7 +90,7 @@ class AllAppsSearchInput(context: Context, attrs: AttributeSet?) : input = ViewCompat.requireViewById(this, R.id.input) with(input) { - if (prefs2.performLocalSearch.firstBlocking()) { + if (prefs2.searchAlgorithm.firstBlocking() != LawnchairSearchAlgorithm.APP_SEARCH) { setHint(R.string.all_apps_device_search_hint) } else { setHint(R.string.all_apps_search_bar_hint) diff --git a/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt b/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt index ae1c827cf2..7d0e2c1257 100644 --- a/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt +++ b/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt @@ -45,6 +45,7 @@ import com.android.launcher3.InvariantDeviceProfile import com.android.launcher3.LauncherAppState import com.android.launcher3.R import com.android.launcher3.graphics.IconShape as L3IconShape +import app.lawnchair.search.algorithms.LawnchairSearchAlgorithm import com.android.launcher3.util.DynamicResource import com.android.launcher3.util.MainThreadInitializedObject import com.patrykmichalik.opto.core.PreferenceManager @@ -269,6 +270,12 @@ class PreferenceManager2 private constructor(private val context: Context) : Pre onSet = { reloadHelper.recreate() }, ) + val searchAlgorithm = preference( + key = stringPreferencesKey(name = "search_algorithm"), + defaultValue = LawnchairSearchAlgorithm.APP_SEARCH, + onSet = { reloadHelper.recreate() }, + ) + val showSuggestedAppsInDrawer = preference( key = booleanPreferencesKey(name = "show_suggested_apps_at_drawer_top"), defaultValue = context.resources.getBoolean(R.bool.config_default_show_suggested_apps_at_drawer_top), @@ -296,11 +303,6 @@ class PreferenceManager2 private constructor(private val context: Context) : Pre defaultValue = context.resources.getBoolean(R.bool.config_default_auto_show_keyboard_in_drawer), ) - val performLocalSearch = preference( - key = booleanPreferencesKey(name = "performLocalSearch"), - defaultValue = context.resources.getBoolean(R.bool.config_default_perform_wide_search), - ) - val workspaceTextColor = preference( key = stringPreferencesKey(name = "workspace_text_color"), defaultValue = ColorMode.AUTO, diff --git a/lawnchair/src/app/lawnchair/search/algorithms/LawnchairSearchAlgorithm.kt b/lawnchair/src/app/lawnchair/search/algorithms/LawnchairSearchAlgorithm.kt index 2a9bea6164..9bde5521e2 100644 --- a/lawnchair/src/app/lawnchair/search/algorithms/LawnchairSearchAlgorithm.kt +++ b/lawnchair/src/app/lawnchair/search/algorithms/LawnchairSearchAlgorithm.kt @@ -24,6 +24,7 @@ import com.android.launcher3.BuildConfig import com.android.launcher3.Utilities import com.android.launcher3.allapps.BaseAllAppsAdapter import com.android.launcher3.search.SearchAlgorithm +import com.patrykmichalik.opto.core.firstBlocking import com.patrykmichalik.opto.core.onEach import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -141,6 +142,10 @@ sealed class LawnchairSearchAlgorithm( companion object { + const val APP_SEARCH = "appSearch" + const val LOCAL_SEARCH = "localSearch" + const val ASI_SEARCH = "globalSearch" + private var ranCompatibilityCheck = false fun isASISearchEnabled(context: Context): Boolean { @@ -155,21 +160,16 @@ sealed class LawnchairSearchAlgorithm( return prefs.deviceSearch.get() } - fun isLocalSearchEnabled(context: Context): Boolean { + + fun create(context: Context): LawnchairSearchAlgorithm { val prefs = PreferenceManager2.getInstance(context) - val coroutineScope = CoroutineScope(context = Dispatchers.IO) - var enableLocalSearch = false + val searchAlgorithm = prefs.searchAlgorithm.firstBlocking() - prefs.performLocalSearch.onEach(launchIn = coroutineScope) { - enableLocalSearch = it + return when { + searchAlgorithm == ASI_SEARCH && isASISearchEnabled(context) -> LawnchairASISearchAlgorithm(context) + searchAlgorithm == LOCAL_SEARCH -> LawnchairLocalSearchAlgorithm(context) + else -> LawnchairAppSearchAlgorithm(context) } - return enableLocalSearch - } - - fun create(context: Context): LawnchairSearchAlgorithm = when { - isASISearchEnabled(context) -> LawnchairASISearchAlgorithm(context) - isLocalSearchEnabled(context) -> LawnchairLocalSearchAlgorithm(context) - else -> LawnchairAppSearchAlgorithm(context) } } } diff --git a/lawnchair/src/app/lawnchair/ui/preferences/components/HiddenAppsInSearchPreference.kt b/lawnchair/src/app/lawnchair/ui/preferences/components/HiddenAppsInSearchPreference.kt index 6090a4a277..d5f957092b 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/components/HiddenAppsInSearchPreference.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/components/HiddenAppsInSearchPreference.kt @@ -1,10 +1,12 @@ package app.lawnchair.ui.preferences.components import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource import app.lawnchair.preferences.getAdapter import app.lawnchair.preferences2.preferenceManager2 import app.lawnchair.ui.preferences.components.controls.ListPreference import app.lawnchair.ui.preferences.components.controls.ListPreferenceEntry +import com.android.launcher3.R import kotlinx.collections.immutable.toPersistentList object HiddenAppsInSearch { @@ -14,9 +16,9 @@ object HiddenAppsInSearch { } val hiddenAppsInSearchEntries = sequenceOf( - ListPreferenceEntry(HiddenAppsInSearch.NEVER) { "Never" }, - ListPreferenceEntry(HiddenAppsInSearch.IF_NAME_TYPED) { "If Full Name is Typed" }, - ListPreferenceEntry(HiddenAppsInSearch.ALWAYS) { "Always" }, + ListPreferenceEntry(HiddenAppsInSearch.NEVER) { stringResource(R.string.hidden_apps_show_never) }, + ListPreferenceEntry(HiddenAppsInSearch.IF_NAME_TYPED) { stringResource(R.string.hidden_apps_show_name_typed) }, + ListPreferenceEntry(HiddenAppsInSearch.ALWAYS) { stringResource(R.string.hidden_apps_show_always) }, ) .toPersistentList() @@ -25,6 +27,6 @@ fun HiddenAppsInSearchPreference() { ListPreference( adapter = preferenceManager2().hiddenAppsInSearch.getAdapter(), entries = hiddenAppsInSearchEntries, - label = "Show Hidden Apps in Search Results", + label = stringResource(R.string.show_hidden_apps_in_search_results), ) } diff --git a/lawnchair/src/app/lawnchair/ui/preferences/destinations/ExperimentalFeaturesPreferences.kt b/lawnchair/src/app/lawnchair/ui/preferences/destinations/ExperimentalFeaturesPreferences.kt index 572f4e4e23..37a2d7c4ef 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/destinations/ExperimentalFeaturesPreferences.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/destinations/ExperimentalFeaturesPreferences.kt @@ -42,11 +42,6 @@ fun ExperimentalFeaturesPreferences( label = stringResource(id = R.string.always_reload_icons_label), description = stringResource(id = R.string.always_reload_icons_description), ) - SwitchPreference( - adapter = prefs2.performLocalSearch.getAdapter(), - label = stringResource(id = R.string.perform_wide_search_title), - description = stringResource(id = R.string.perform_wide_search_description), - ) SwitchPreference( adapter = prefs.recentsActionLocked.getAdapter(), label = stringResource(id = R.string.recents_lock_unlock), diff --git a/lawnchair/src/app/lawnchair/ui/preferences/destinations/SearchPreferences.kt b/lawnchair/src/app/lawnchair/ui/preferences/destinations/SearchPreferences.kt index 39ccc1822c..cea01d1ac7 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/destinations/SearchPreferences.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/destinations/SearchPreferences.kt @@ -2,6 +2,7 @@ package app.lawnchair.ui.preferences.destinations import android.content.Context import android.os.Build +import androidx.compose.animation.AnimatedVisibility import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState @@ -19,8 +20,11 @@ import app.lawnchair.preferences.not import app.lawnchair.preferences.preferenceManager import app.lawnchair.preferences2.PreferenceManager2 import app.lawnchair.preferences2.preferenceManager2 +import app.lawnchair.search.algorithms.LawnchairSearchAlgorithm import app.lawnchair.ui.preferences.components.HiddenAppsInSearchPreference import app.lawnchair.ui.preferences.components.SearchSuggestionPreference +import app.lawnchair.ui.preferences.components.controls.ListPreference +import app.lawnchair.ui.preferences.components.controls.ListPreferenceEntry import app.lawnchair.ui.preferences.components.controls.MainSwitchPreference import app.lawnchair.ui.preferences.components.controls.SliderPreference import app.lawnchair.ui.preferences.components.controls.SwitchPreference @@ -28,12 +32,11 @@ import app.lawnchair.ui.preferences.components.layout.ExpandAndShrink import app.lawnchair.ui.preferences.components.layout.PreferenceGroup import app.lawnchair.ui.preferences.components.layout.PreferenceLayout import app.lawnchair.util.checkAndRequestFilesPermission -import app.lawnchair.util.contactPermissionGranted import app.lawnchair.util.filesAndStorageGranted -import app.lawnchair.util.requestContactPermissionGranted import com.android.launcher3.R import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.rememberPermissionState +import kotlinx.collections.immutable.toPersistentList @Composable fun SearchPreferences() { @@ -57,13 +60,14 @@ fun SearchPreferences() { adapter = prefs2.autoShowKeyboardInDrawer.getAdapter(), label = stringResource(id = R.string.pref_search_auto_show_keyboard), ) + SearchProvider( + context = context + ) } - val isLocalSearch = prefs2.performLocalSearch.getAdapter().state.value - val isASISearch = prefs.deviceSearch.getAdapter().state.value - PreferenceGroup(heading = stringResource(id = R.string.show_search_result_types)) { - if (!isASISearch) { + val searchAlgorithm = preferenceManager2().searchAlgorithm.getAdapter().state.value + if (searchAlgorithm != LawnchairSearchAlgorithm.ASI_SEARCH) { @OptIn(ExperimentalPermissionsApi::class) SearchSuggestionPreference( adapter = prefs.searchResultApps.getAdapter(), @@ -79,15 +83,15 @@ fun SearchPreferences() { ) } } - when { - isLocalSearch -> { + when (searchAlgorithm) { + LawnchairSearchAlgorithm.LOCAL_SEARCH -> { LocalSearchSettings( prefs = prefs, prefs2 = prefs2, context = context, ) } - isASISearch -> { + LawnchairSearchAlgorithm.ASI_SEARCH -> { ASISearchSettings(prefs) } } @@ -112,6 +116,29 @@ private fun ASISearchSettings(prefs: PreferenceManager) { ) } +@Composable +private fun SearchProvider( + context: Context +) { + val searchAlgorithmEntries = sequenceOf( + ListPreferenceEntry(LawnchairSearchAlgorithm.APP_SEARCH) { stringResource(R.string.search_algorithm_app_search) }, + ListPreferenceEntry(LawnchairSearchAlgorithm.LOCAL_SEARCH) { stringResource(R.string.search_algorithm_global_search_on_device) }, + ListPreferenceEntry(LawnchairSearchAlgorithm.ASI_SEARCH) { stringResource(R.string.search_algorithm_global_search_via_asi) }, + ).filter { + when (it.value) { + LawnchairSearchAlgorithm.ASI_SEARCH -> LawnchairSearchAlgorithm.isASISearchEnabled(context) + else -> true + } + }.toPersistentList() + + ListPreference( + adapter = preferenceManager2().searchAlgorithm.getAdapter(), + entries = searchAlgorithmEntries, + label = stringResource(R.string.app_search_algorithm), + ) +} + + @OptIn(ExperimentalPermissionsApi::class) @Composable private fun LocalSearchSettings( diff --git a/res/values/strings.xml b/res/values/strings.xml index f3a1ae8eea..0da53586e8 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -448,4 +448,12 @@ Failed: %1$s Use Multiple Lines + Always + If Full Name is Typed + Never + Show Hidden Apps in Search Results + App Search + Global Search (on-device) + Global Search (via ASI) + Search Algorithm