Implement custom permission system for plugins
This commit is contained in:
@@ -4,5 +4,5 @@ import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.dsl.module
|
||||
|
||||
val servicesPluginsModule = module {
|
||||
single<PluginService> { PluginServiceImpl(androidContext(), get(), get()) }
|
||||
single<PluginService> { PluginServiceImpl(androidContext(), get()) }
|
||||
}
|
||||
@@ -13,8 +13,6 @@ import android.os.Build
|
||||
import android.util.Base64
|
||||
import android.util.Log
|
||||
import de.mm20.launcher2.ktx.tryStartActivity
|
||||
import de.mm20.launcher2.permissions.PermissionGroup
|
||||
import de.mm20.launcher2.permissions.PermissionsManager
|
||||
import de.mm20.launcher2.plugin.Plugin
|
||||
import de.mm20.launcher2.plugin.PluginPackage
|
||||
import de.mm20.launcher2.plugin.PluginRepository
|
||||
@@ -25,8 +23,6 @@ import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
@@ -50,8 +46,6 @@ interface PluginService {
|
||||
enabled: Boolean? = null,
|
||||
): Flow<List<PluginWithState>>
|
||||
|
||||
fun isPluginHostInstalled(): Flow<Boolean>
|
||||
|
||||
fun getPluginPackages(): Flow<List<PluginPackage>>
|
||||
fun getPluginPackage(packageName: String): Flow<PluginPackage?>
|
||||
suspend fun getPluginState(plugin: Plugin): PluginState?
|
||||
@@ -65,13 +59,10 @@ interface PluginService {
|
||||
internal class PluginServiceImpl(
|
||||
private val context: Context,
|
||||
private val repository: PluginRepository,
|
||||
private val permissionsManager: PermissionsManager,
|
||||
) : PluginService {
|
||||
|
||||
private val scope: CoroutineScope = CoroutineScope(Job() + Dispatchers.Default)
|
||||
|
||||
private val pluginHostInstalled = MutableStateFlow(false)
|
||||
|
||||
private val mutex = Mutex()
|
||||
|
||||
init {
|
||||
@@ -84,14 +75,6 @@ internal class PluginServiceImpl(
|
||||
addAction(Intent.ACTION_PACKAGE_CHANGED)
|
||||
addDataScheme("package")
|
||||
})
|
||||
|
||||
scope.launch {
|
||||
permissionsManager.hasPermission(PermissionGroup.Plugins).collectLatest {
|
||||
if (it) {
|
||||
refreshPlugins()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun enablePluginPackage(plugin: PluginPackage) {
|
||||
@@ -113,14 +96,6 @@ internal class PluginServiceImpl(
|
||||
private fun refreshPlugins() {
|
||||
Log.d("PluginService", "Refreshing plugins")
|
||||
scope.launch {
|
||||
try {
|
||||
val permission =
|
||||
context.packageManager.getPermissionInfo(PluginContract.Permission, 0)
|
||||
pluginHostInstalled.value = permission != null
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
pluginHostInstalled.value = false
|
||||
return@launch
|
||||
}
|
||||
mutex.withLock {
|
||||
val enabledPluginPackages =
|
||||
repository.findMany(enabled = true).first().map { it.packageName }.distinct()
|
||||
@@ -157,24 +132,25 @@ internal class PluginServiceImpl(
|
||||
}
|
||||
|
||||
override suspend fun getPluginState(plugin: Plugin): PluginState {
|
||||
val bundle = withContext(Dispatchers.IO) {
|
||||
context.contentResolver.call(
|
||||
Uri.Builder()
|
||||
.scheme("content")
|
||||
.authority(plugin.authority)
|
||||
.build(),
|
||||
PluginContract.Methods.GetState,
|
||||
null,
|
||||
null
|
||||
)
|
||||
} ?: return PluginState.Error
|
||||
val bundle =
|
||||
try {
|
||||
withContext(Dispatchers.IO) {
|
||||
context.contentResolver.call(
|
||||
Uri.Builder()
|
||||
.scheme("content")
|
||||
.authority(plugin.authority)
|
||||
.build(),
|
||||
PluginContract.Methods.GetState,
|
||||
null,
|
||||
null
|
||||
)
|
||||
} ?: return PluginState.Error
|
||||
} catch (e: SecurityException) {
|
||||
return PluginState.NoPermission
|
||||
}
|
||||
return PluginState.fromBundle(bundle) ?: PluginState.Error
|
||||
}
|
||||
|
||||
override fun isPluginHostInstalled(): Flow<Boolean> {
|
||||
return pluginHostInstalled
|
||||
}
|
||||
|
||||
override suspend fun getPluginIcon(plugin: Plugin): Drawable? {
|
||||
return withContext(Dispatchers.IO) {
|
||||
val info = try {
|
||||
|
||||
Reference in New Issue
Block a user