From 0a4069171123ed4beef4829cde5137ab5c9c6021 Mon Sep 17 00:00:00 2001 From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com> Date: Mon, 28 Jul 2025 23:16:42 +0800 Subject: [PATCH] fix(search): Correct regressions found during final testing --- lawnchair/res/values/strings.xml | 2 ++ .../search/adapter/SearchTargetFactory.kt | 13 +++++++--- .../LawnchairLocalSearchAlgorithm.kt | 5 ++-- .../search/algorithms/engine/SearchResult.kt | 1 + .../algorithms/engine/SectionBuilder.kt | 1 + .../provider/web/CustomWebSearchProvider.kt | 2 +- .../components/search/FileSearchProvider.kt | 24 +++++++++++++------ .../search/SearchProviderPreference.kt | 2 +- .../app/lawnchair/util/FileAccessManager.kt | 1 + platform_frameworks_libs_systemui | 2 +- 10 files changed, 38 insertions(+), 15 deletions(-) diff --git a/lawnchair/res/values/strings.xml b/lawnchair/res/values/strings.xml index b1eb6010b1..667afb9079 100644 --- a/lawnchair/res/values/strings.xml +++ b/lawnchair/res/values/strings.xml @@ -796,6 +796,8 @@ Calculator + Search on + Media, files, and more Contacts and more Via %1$s diff --git a/lawnchair/src/app/lawnchair/search/adapter/SearchTargetFactory.kt b/lawnchair/src/app/lawnchair/search/adapter/SearchTargetFactory.kt index 1abe6de13d..e06e316ee3 100644 --- a/lawnchair/src/app/lawnchair/search/adapter/SearchTargetFactory.kt +++ b/lawnchair/src/app/lawnchair/search/adapter/SearchTargetFactory.kt @@ -238,16 +238,23 @@ class SearchTargetFactory( fun createWebSearchActionTarget( query: String, - providerName: String, // The actual display name, not an ID - searchUrl: String, // The final, pre-formatted search URL + providerName: String, + searchUrl: String, @DrawableRes providerIconRes: Int, + tintIcon: Boolean = false, ): SearchTargetCompat { val id = "browser:$query:$providerName" val browserIntent = Intent(Intent.ACTION_VIEW, searchUrl.toUri()) val title = context.getString(R.string.all_apps_search_on_web_message, providerName) + val icon = Icon.createWithResource(context, providerIconRes).apply { + if (tintIcon) { + setTint(ColorTokens.TextColorSecondary.resolveColor(context)) + } + } + val action = SearchActionCompat.Builder(id, title) - .setIcon(Icon.createWithResource(context, providerIconRes)) + .setIcon(icon) .setIntent(browserIntent) .build() diff --git a/lawnchair/src/app/lawnchair/search/algorithms/LawnchairLocalSearchAlgorithm.kt b/lawnchair/src/app/lawnchair/search/algorithms/LawnchairLocalSearchAlgorithm.kt index 13ba5164e1..02341227e4 100644 --- a/lawnchair/src/app/lawnchair/search/algorithms/LawnchairLocalSearchAlgorithm.kt +++ b/lawnchair/src/app/lawnchair/search/algorithms/LawnchairLocalSearchAlgorithm.kt @@ -147,7 +147,7 @@ class LawnchairLocalSearchAlgorithm(context: Context) : LawnchairSearchAlgorithm val webProvider = provider.configure(context) val providerName = if (webProvider is CustomWebSearchProvider) { - webProvider.getDisplayName(context.getString(webProvider.label)) + webProvider.getDisplayName() } else { context.getString(webProvider.label) } @@ -158,6 +158,7 @@ class LawnchairLocalSearchAlgorithm(context: Context) : LawnchairSearchAlgorithm providerName = providerName, searchUrl = webProvider.getSearchUrl(query), providerIconRes = webProvider.iconRes, + tintIcon = webProvider is CustomWebSearchProvider, ), ) } @@ -174,8 +175,8 @@ class LawnchairLocalSearchAlgorithm(context: Context) : LawnchairSearchAlgorithm private val sectionBuilders: List = listOf( AppsAndShortcutsSectionBuilder, - WebSuggestionsSectionBuilder, CalculationSectionBuilder, + WebSuggestionsSectionBuilder, ContactsSectionBuilder, FilesSectionBuilder, SettingsSectionBuilder, diff --git a/lawnchair/src/app/lawnchair/search/algorithms/engine/SearchResult.kt b/lawnchair/src/app/lawnchair/search/algorithms/engine/SearchResult.kt index a38e45d8c6..cdf6d6c685 100644 --- a/lawnchair/src/app/lawnchair/search/algorithms/engine/SearchResult.kt +++ b/lawnchair/src/app/lawnchair/search/algorithms/engine/SearchResult.kt @@ -30,6 +30,7 @@ sealed class SearchResult { val providerName: String, val searchUrl: String, @DrawableRes val providerIconRes: Int, + val tintIcon: Boolean = false, ) : Action() data class EmptyState( @StringRes val titleRes: Int, diff --git a/lawnchair/src/app/lawnchair/search/algorithms/engine/SectionBuilder.kt b/lawnchair/src/app/lawnchair/search/algorithms/engine/SectionBuilder.kt index 448303eba2..3885e6a91f 100644 --- a/lawnchair/src/app/lawnchair/search/algorithms/engine/SectionBuilder.kt +++ b/lawnchair/src/app/lawnchair/search/algorithms/engine/SectionBuilder.kt @@ -176,6 +176,7 @@ object ActionsSectionBuilder : SectionBuilder { providerName = webSearch.first().providerName, searchUrl = webSearch.first().searchUrl, providerIconRes = webSearch.first().providerIconRes, + tintIcon = webSearch.first().tintIcon, ).let { targets.add(it) } diff --git a/lawnchair/src/app/lawnchair/search/algorithms/engine/provider/web/CustomWebSearchProvider.kt b/lawnchair/src/app/lawnchair/search/algorithms/engine/provider/web/CustomWebSearchProvider.kt index c00e0cbc6e..9e0e12274f 100644 --- a/lawnchair/src/app/lawnchair/search/algorithms/engine/provider/web/CustomWebSearchProvider.kt +++ b/lawnchair/src/app/lawnchair/search/algorithms/engine/provider/web/CustomWebSearchProvider.kt @@ -44,7 +44,7 @@ object CustomWebSearchProvider : WebSearchProvider { private var displayName: String = "" private val okHttpClient = OkHttpClient() - fun getDisplayName(getDisplayNamedefault: String): String = displayName + fun getDisplayName(): String = displayName override fun configure(context: Context): WebSearchProvider { val prefs = PreferenceManager2.getInstance(context) diff --git a/lawnchair/src/app/lawnchair/ui/preferences/components/search/FileSearchProvider.kt b/lawnchair/src/app/lawnchair/ui/preferences/components/search/FileSearchProvider.kt index ec388bc2a9..e2c75bff92 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/components/search/FileSearchProvider.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/components/search/FileSearchProvider.kt @@ -21,6 +21,7 @@ import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.ripple import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -81,6 +82,10 @@ fun FileSearchProvider( val mainAdapter = prefs.searchResultFilesToggle.getAdapter() val hasAnyPermissions by viewModel.hasAnyPermissions.collectAsStateWithLifecycle() + LaunchedEffect(Unit) { + viewModel.refreshAccessStates() + } + LifecycleResumeEffect(Unit) { viewModel.refreshAccessStates() onPauseOrDispose {} @@ -93,18 +98,21 @@ fun FileSearchProvider( enabled = hasAnyPermissions, modifier = modifier, ) - PreferenceGroup { + PreferenceGroup( + heading = stringResource(R.string.search_pref_files_search_on), + ) { val allFilesAccessState by viewModel.allFilesAccessState.collectAsStateWithLifecycle() + val allFilesAccessAdapter = prefs.searchResultAllFiles.getAdapter() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { ManageExternalStorageSetting( accessState = allFilesAccessState, - adapter = prefs.searchResultAllFiles.getAdapter(), + adapter = allFilesAccessAdapter, onPermissionRequest = viewModel::refreshAccessStates, ) } else { GenericAccessSetting( - adapter = prefs.searchResultAllFiles.getAdapter(), + adapter = allFilesAccessAdapter, requiredPermission = android.Manifest.permission.READ_EXTERNAL_STORAGE, switchEnabled = { allFilesAccessState != FileAccessState.Denied }, label = stringResource(R.string.search_pref_result_all_files_title), @@ -122,6 +130,7 @@ fun FileSearchProvider( accessState = visualMediaAccessState, adapter = prefs.searchResultVisualMedia.getAdapter(), onPermissionRequest = viewModel::refreshAccessStates, + alwaysEnabled = allFilesAccessAdapter.state.value && allFilesAccessState == FileAccessState.Full, ) GenericAccessSetting( @@ -132,6 +141,7 @@ fun FileSearchProvider( permissionTitle = stringResource(R.string.permissions_music_audio), permissionDescription = stringResource(R.string.permissions_music_audio_description), onPermissionResult = { viewModel.refreshAccessStates() }, + alwaysEnabled = allFilesAccessAdapter.state.value && allFilesAccessState == FileAccessState.Full, ) } } @@ -182,7 +192,7 @@ private fun ManageExternalStorageSetting( showPermissionDialog = true } }, - switchEnabled = !isPlayStoreFlavor(), + switchEnabled = !isPlayStoreFlavor() && (accessState != FileAccessState.Denied), modifier = modifier, ) } @@ -190,8 +200,8 @@ private fun ManageExternalStorageSetting( if (showPermissionDialog) { if (!isPlayStoreFlavor()) { PermissionDialog( - title = stringResource(R.string.permissions_photos_videos), - text = stringResource(R.string.permissions_photos_videos_description), + title = stringResource(R.string.permissions_manage_storage), + text = stringResource(R.string.permissions_manage_storage_description), isPermanentlyDenied = true, onConfirm = { }, onDismiss = { showPermissionDialog = false }, @@ -273,7 +283,7 @@ private fun VisualMediaSetting( PermissionDialog( title = stringResource(R.string.permissions_photos_videos), text = stringResource(R.string.permissions_photos_videos_description), - isPermanentlyDenied = !permissionState.shouldShowRationale && !permissionState.allPermissionsGranted, + isPermanentlyDenied = permissionState.allPermissionsGranted, onConfirm = { permissionState.launchMultiplePermissionRequest() }, onDismiss = { showPermissionDialog = false }, onGoToSettings = { context.openAppPermissionSettings() }, diff --git a/lawnchair/src/app/lawnchair/ui/preferences/components/search/SearchProviderPreference.kt b/lawnchair/src/app/lawnchair/ui/preferences/components/search/SearchProviderPreference.kt index 75ed95c186..f93308b23a 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/components/search/SearchProviderPreference.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/components/search/SearchProviderPreference.kt @@ -157,7 +157,7 @@ fun ContactsSearchProvider( PermissionDialog( title = stringResource(R.string.warn_contact_permission_title), text = stringResource(id = R.string.warn_contact_permission_content), - isPermanentlyDenied = !contactsPermissionState.status.isGranted && !contactsPermissionState.status.shouldShowRationale, + isPermanentlyDenied = contactsPermissionState.status.shouldShowRationale, onConfirm = { contactsPermissionState.launchPermissionRequest() }, onDismiss = { backDispatcher?.onBackPressed() diff --git a/lawnchair/src/app/lawnchair/util/FileAccessManager.kt b/lawnchair/src/app/lawnchair/util/FileAccessManager.kt index cb3f1a3c56..bfd864444e 100644 --- a/lawnchair/src/app/lawnchair/util/FileAccessManager.kt +++ b/lawnchair/src/app/lawnchair/util/FileAccessManager.kt @@ -102,6 +102,7 @@ class FileAccessManager private constructor(private val context: Context) : Safe _allFilesAccessState.value = getCurrentAllFilesAccessState() _visualMediaAccessState.value = getCurrentVisualMediaState() _audioAccessState.value = getCurrentAudioState() + _hasAnyPermission.value = hasAnyPermissions() } private fun hasAnyPermissions(): Boolean { diff --git a/platform_frameworks_libs_systemui b/platform_frameworks_libs_systemui index efa9b01922..970a3b2f14 160000 --- a/platform_frameworks_libs_systemui +++ b/platform_frameworks_libs_systemui @@ -1 +1 @@ -Subproject commit efa9b019229547bfa0cb07fe07a10e76af62866b +Subproject commit 970a3b2f1407c585c57f08245a35e416c465ab37