feat(search): simplify permissions handling

This commit is contained in:
SuperDragonXD
2025-07-26 18:38:22 +08:00
parent ccafdec7cc
commit e94658f424
4 changed files with 33 additions and 32 deletions

View File

@@ -0,0 +1,7 @@
package app.lawnchair.search.algorithms.engine
import android.content.Context
interface SearchPermission {
fun checkPermission(context: Context): Boolean
}

View File

@@ -1,11 +1,14 @@
package app.lawnchair.search.algorithms.engine.provider
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.provider.ContactsContract
import android.util.Log
import app.lawnchair.preferences.PreferenceManager
import app.lawnchair.preferences2.PreferenceManager2
import app.lawnchair.search.algorithms.data.ContactInfo
import app.lawnchair.search.algorithms.engine.SearchPermission
import app.lawnchair.search.algorithms.engine.SearchProvider
import app.lawnchair.search.algorithms.engine.SearchResult
import com.patrykmichalik.opto.core.firstBlocking
@@ -18,7 +21,7 @@ import kotlinx.serialization.json.buildJsonArray
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.put
object ContactsSearchProvider : SearchProvider {
object ContactsSearchProvider : SearchProvider, SearchPermission {
override val id: String = "contacts"
override fun search(
@@ -28,7 +31,7 @@ object ContactsSearchProvider : SearchProvider {
val prefs = PreferenceManager.getInstance(context)
val prefs2 = PreferenceManager2.getInstance(context)
val permissionsGranted = true // TODO: replace with real permission check
val permissionsGranted = checkPermission(context)
if (query.isBlank() || !prefs.searchResultPeople.get() || !permissionsGranted) {
emit(emptyList())
return@flow
@@ -45,6 +48,10 @@ object ContactsSearchProvider : SearchProvider {
emit(searchResults)
}
override fun checkPermission(context: Context): Boolean {
return context.checkSelfPermission(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED
}
private suspend fun findContactsByName(context: Context, query: String, max: Int): List<ContactInfo> {
try {
if (query.isEmpty() || query.isBlank() || max <= 0) return emptyList()

View File

@@ -1,14 +1,19 @@
package app.lawnchair.search.algorithms.engine.provider
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.database.Cursor
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import app.lawnchair.preferences.PreferenceManager
import app.lawnchair.preferences2.PreferenceManager2
import app.lawnchair.search.algorithms.data.FileInfo
import app.lawnchair.search.algorithms.data.FolderInfo
import app.lawnchair.search.algorithms.data.IFileInfo
import app.lawnchair.search.algorithms.engine.SearchPermission
import app.lawnchair.search.algorithms.engine.SearchProvider
import app.lawnchair.search.algorithms.engine.SearchResult
import app.lawnchair.util.exists
@@ -23,7 +28,7 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.withContext
import okio.Path.Companion.toPath
object FileSearchProvider : SearchProvider {
object FileSearchProvider : SearchProvider, SearchPermission {
override val id = "Files"
override fun search(
@@ -33,7 +38,7 @@ object FileSearchProvider : SearchProvider {
val prefs = PreferenceManager.getInstance(context)
val prefs2 = PreferenceManager2.getInstance(context)
val permissionsGranted = true // TODO: Replace with real permission check, to be added later
val permissionsGranted = checkPermission(context)
if (query.isBlank() || !prefs.searchResultFiles.get() || !permissionsGranted) {
emit(emptyList())
return@flow
@@ -54,6 +59,16 @@ object FileSearchProvider : SearchProvider {
emit(searchResults)
}
override fun checkPermission(context: Context): Boolean {
// TODO: improve granularity of permissions
return when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU ->
Environment.isExternalStorageManager() || context.checkSelfPermission(Manifest.permission.READ_MEDIA_IMAGES) == PackageManager.PERMISSION_GRANTED
Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> Environment.isExternalStorageManager()
else -> context.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
}
}
private suspend fun queryFilesInMediaStore(
context: Context,
uri: Uri = MediaStore.Files.getContentUri("external"),

View File

@@ -9,39 +9,11 @@ import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.Settings
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import app.lawnchair.preferences.PreferenceManager
private const val TAG: String = "PackagePermissionManager"
fun requestContactPermissionGranted(context: Context, prefs: PreferenceManager): Boolean {
val isGranted = contactPermissionGranted(context)
if (!isGranted) {
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
val uri: Uri = Uri.fromParts("package", context.packageName, null)
intent.data = uri
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
if (intent.resolveActivity(context.packageManager) != null) {
context.startActivity(intent)
} else {
Log.e(TAG, "No activity found to handle application details settings intent")
}
prefs.searchResultPeople.set(false)
}
return isGranted
}
fun contactPermissionGranted(context: Context): Boolean {
return context.checkSelfPermission(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED
}
fun checkAndRequestFilesPermission(context: Context, prefs: PreferenceManager): Boolean {
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> {