fix: fix di

This commit is contained in:
CnC-Robert 2023-08-22 23:08:50 +02:00
parent 9503ebca69
commit 58c2d5023f
No known key found for this signature in database
GPG Key ID: C58ED617AEA8CB68
8 changed files with 80 additions and 95 deletions

View File

@ -3,6 +3,7 @@ package app.revanced.manager.di
import app.revanced.manager.network.service.GithubService import app.revanced.manager.network.service.GithubService
import app.revanced.manager.network.service.HttpService import app.revanced.manager.network.service.HttpService
import app.revanced.manager.network.service.ReVancedService import app.revanced.manager.network.service.ReVancedService
import app.revanced.manager.service.ShizukuService
import org.koin.core.module.dsl.singleOf import org.koin.core.module.dsl.singleOf
import org.koin.dsl.module import org.koin.dsl.module
@ -18,4 +19,5 @@ val serviceModule = module {
single { provideReVancedService(get()) } single { provideReVancedService(get()) }
singleOf(::HttpService) singleOf(::HttpService)
singleOf(::GithubService) singleOf(::GithubService)
singleOf(::ShizukuService)
} }

View File

@ -7,23 +7,21 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import app.revanced.manager.util.PM
import rikka.shizuku.Shizuku import rikka.shizuku.Shizuku
import java.io.File import java.io.File
class ShizukuApi( class ShizukuService(
private val app: Application private val app: Application,
private val pm: PM
) { ) {
var isBinderAvailable = false
var isPermissionGranted by mutableStateOf(false) var isPermissionGranted by mutableStateOf(false)
init { init {
Shizuku.addBinderReceivedListenerSticky { Shizuku.addBinderReceivedListenerSticky {
isBinderAvailable = true
isPermissionGranted = Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED isPermissionGranted = Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED
} }
Shizuku.addBinderDeadListener { Shizuku.addBinderDeadListener {
isBinderAvailable = false
isPermissionGranted = false isPermissionGranted = false
} }
} }
@ -37,7 +35,9 @@ class ShizukuApi(
app.startActivity(intent) app.startActivity(intent)
} }
fun isShizukuPermissionGranted() = isBinderAvailable && isPermissionGranted fun isShizukuInstalled() = pm.getPackageInfo(shizukuPackageName) != null
fun isShizukuInstalled() = Shizuku.pingBinder() companion object {
const val shizukuPackageName = "moe.shizuku.privileged.api"
}
} }

View File

@ -1,8 +1,6 @@
package app.revanced.manager.ui.component package app.revanced.manager.ui.component
import android.content.pm.PackageManager
import android.util.Log import android.util.Log
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@ -21,77 +19,65 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import app.revanced.manager.R import app.revanced.manager.R
import app.revanced.manager.service.ShizukuApi import app.revanced.manager.util.tag
import rikka.shizuku.Shizuku import rikka.shizuku.Shizuku
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun ShizukuCard( fun ShizukuCard(
shizukuApi: ShizukuApi onPermissionResult: (Int, Int) -> Unit,
) { ) {
val listener: (Int, Int) -> Unit = { _, grantResult ->
shizukuApi.isPermissionGranted = grantResult == PackageManager.PERMISSION_GRANTED
}
LaunchedEffect(Unit) {
Shizuku.addRequestPermissionResultListener(listener)
}
DisposableEffect(Unit) { DisposableEffect(Unit) {
Shizuku.addRequestPermissionResultListener(onPermissionResult)
onDispose { onDispose {
Shizuku.removeRequestPermissionResultListener(listener) Shizuku.removeRequestPermissionResultListener(onPermissionResult)
} }
} }
AnimatedVisibility(visible = !shizukuApi.isPermissionGranted) { Card(
Card( colors = CardDefaults.cardColors(
colors = CardDefaults.cardColors( MaterialTheme.colorScheme.errorContainer
MaterialTheme.colorScheme.errorContainer ),
), onClick = {
onClick = { Log.i(tag, "Requesting permission")
if (shizukuApi.isBinderAvailable && !shizukuApi.isPermissionGranted) { Shizuku.requestPermission(114514)
Log.i("ShizukuCard", "Requesting permission") },
Shizuku.requestPermission(114514) modifier = Modifier
} .fillMaxWidth()
}, .padding(16.dp)
.clip(RoundedCornerShape(24.dp))
.background(MaterialTheme.colorScheme.tertiaryContainer),
) {
Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(16.dp) .padding(16.dp),
.clip(RoundedCornerShape(24.dp)) verticalAlignment = Alignment.CenterVertically,
.background(MaterialTheme.colorScheme.tertiaryContainer), horizontalArrangement = Arrangement.spacedBy(16.dp)
) { ) {
Row( Icon(
modifier = Modifier imageVector = Icons.Default.Warning,
.fillMaxWidth() contentDescription = null,
.padding(16.dp), tint = MaterialTheme.colorScheme.onErrorContainer,
verticalAlignment = Alignment.CenterVertically, modifier = Modifier.size(24.dp)
horizontalArrangement = Arrangement.spacedBy(16.dp) )
) { Column {
Icon( Text(
imageVector = Icons.Default.Warning, text = stringResource(R.string.shizuku_unavailable),
contentDescription = null, style = MaterialTheme.typography.titleMedium
tint = MaterialTheme.colorScheme.onErrorContainer, )
modifier = Modifier.size(24.dp) Text(
text = stringResource(R.string.home_shizuku_warning),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onErrorContainer
) )
Column() {
Text(
text = stringResource(R.string.shizuku_unavailable),
style = MaterialTheme.typography.titleMedium
)
Text(
text = stringResource(R.string.home_shizuku_warning),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onErrorContainer
)
}
} }
} }
} }

View File

@ -1,8 +1,9 @@
package app.revanced.manager.ui.screen package app.revanced.manager.ui.screen
import android.content.pm.PackageManager
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
@ -39,12 +40,13 @@ fun InstalledAppsScreen(
verticalArrangement = installedApps?.let { if (it.isEmpty()) Arrangement.Center else Arrangement.Top } ?: Arrangement.Center verticalArrangement = installedApps?.let { if (it.isEmpty()) Arrangement.Center else Arrangement.Top } ?: Arrangement.Center
) { ) {
item { item {
if (viewModel.shizukuApi.isShizukuInstalled()) ShizukuCard(viewModel.shizukuApi) AnimatedVisibility(
visible = viewModel.shizukuService.isShizukuInstalled() && !viewModel.shizukuService.isPermissionGranted
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { ) {
Text( ShizukuCard(
text = stringResource(R.string.no_patched_apps_found), onPermissionResult = { _, grantResult ->
style = MaterialTheme.typography.titleLarge viewModel.shizukuService.isPermissionGranted = grantResult == PackageManager.PERMISSION_GRANTED
}
) )
} }
} }

View File

@ -1,9 +1,7 @@
package app.revanced.manager.ui.screen.settings package app.revanced.manager.ui.screen.settings
import android.app.ActivityManager import android.app.ActivityManager
import android.content.Context
import android.os.Build import android.os.Build
import android.widget.Toast
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@ -43,12 +41,11 @@ import androidx.compose.ui.unit.dp
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import app.revanced.manager.R import app.revanced.manager.R
import app.revanced.manager.domain.manager.PreferencesManager import app.revanced.manager.domain.manager.PreferencesManager
import app.revanced.manager.service.ShizukuApi
import app.revanced.manager.ui.component.AppTopBar import app.revanced.manager.ui.component.AppTopBar
import app.revanced.manager.ui.component.GroupHeader import app.revanced.manager.ui.component.GroupHeader
import app.revanced.manager.ui.viewmodel.AdvancedSettingsViewModel import app.revanced.manager.ui.viewmodel.AdvancedSettingsViewModel
import app.revanced.manager.util.toast
import org.koin.androidx.compose.getViewModel import org.koin.androidx.compose.getViewModel
import org.koin.compose.koinInject
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
@ -69,9 +66,15 @@ fun AdvancedSettingsScreen(
if (showInstallerPicker) { if (showInstallerPicker) {
InstallerPicker( InstallerPicker(
currentInstaller = prefs.defaultInstaller.getAsState().value,
onDismiss = { showInstallerPicker = false }, onDismiss = { showInstallerPicker = false },
onConfirm = { vm.setInstaller(it) }, onConfirm = {
viewModel = vm if (it == PreferencesManager.InstallerManager.SHIZUKU && !vm.shizukuService.isPermissionGranted) {
context.toast(context.getString(R.string.shizuku_unavailable))
return@InstallerPicker
}
vm.setInstaller(it)
}
) )
} }
@ -184,15 +187,14 @@ private fun APIUrlDialog(currentUrl: String, onSubmit: (String?) -> Unit) {
@Composable @Composable
private fun InstallerPicker( private fun InstallerPicker(
currentInstaller: PreferencesManager.InstallerManager,
onDismiss: () -> Unit, onDismiss: () -> Unit,
onConfirm: (PreferencesManager.InstallerManager) -> Unit, onConfirm: (PreferencesManager.InstallerManager) -> Unit,
prefs: PreferencesManager = koinInject(),
viewModel: AdvancedSettingsViewModel
) { ) {
var selectedInstaller by rememberSaveable { mutableStateOf(prefs.defaultInstaller.getBlocking()) } var selectedInstaller by rememberSaveable { mutableStateOf(currentInstaller) }
val context: Context = LocalContext.current
AlertDialog(onDismissRequest = onDismiss, AlertDialog(
onDismissRequest = onDismiss,
title = { Text(stringResource(R.string.installer)) }, title = { Text(stringResource(R.string.installer)) },
text = { text = {
Column { Column {
@ -203,8 +205,7 @@ private fun InstallerPicker(
.clickable { selectedInstaller = it }, .clickable { selectedInstaller = it },
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
RadioButton(selected = selectedInstaller == it, RadioButton(selected = selectedInstaller == it, onClick = null)
onClick = { selectedInstaller = it })
Text(stringResource(it.displayName)) Text(stringResource(it.displayName))
} }
} }
@ -212,16 +213,11 @@ private fun InstallerPicker(
}, },
confirmButton = { confirmButton = {
Button(onClick = { Button(onClick = {
if (selectedInstaller == PreferencesManager.InstallerManager.SHIZUKU && viewModel.shizukuApi.isShizukuPermissionGranted()) {
Toast.makeText(
context, R.string.shizuku_unavailable, Toast.LENGTH_SHORT
).show()
return@Button
}
onConfirm(selectedInstaller) onConfirm(selectedInstaller)
onDismiss() onDismiss()
}) { }) {
Text(stringResource(R.string.apply)) Text(stringResource(R.string.apply))
} }
}) }
)
} }

View File

@ -7,17 +7,16 @@ import app.revanced.manager.R
import app.revanced.manager.domain.manager.PreferencesManager import app.revanced.manager.domain.manager.PreferencesManager
import app.revanced.manager.domain.repository.PatchBundleRepository import app.revanced.manager.domain.repository.PatchBundleRepository
import app.revanced.manager.domain.bundles.RemotePatchBundle import app.revanced.manager.domain.bundles.RemotePatchBundle
import app.revanced.manager.service.ShizukuApi import app.revanced.manager.service.ShizukuService
import app.revanced.manager.util.uiSafe import app.revanced.manager.util.uiSafe
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.koin.compose.koinInject
class AdvancedSettingsViewModel( class AdvancedSettingsViewModel(
val prefs: PreferencesManager, val prefs: PreferencesManager,
private val app: Application, private val app: Application,
private val patchBundleRepository: PatchBundleRepository, private val patchBundleRepository: PatchBundleRepository,
val shizukuApi: ShizukuApi val shizukuService: ShizukuService
) : ViewModel() { ) : ViewModel() {
val apiUrl = prefs.api val apiUrl = prefs.api

View File

@ -5,7 +5,7 @@ import androidx.compose.runtime.mutableStateMapOf
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import app.revanced.manager.domain.repository.InstalledAppRepository import app.revanced.manager.domain.repository.InstalledAppRepository
import app.revanced.manager.service.ShizukuApi import app.revanced.manager.service.ShizukuService
import app.revanced.manager.util.PM import app.revanced.manager.util.PM
import app.revanced.manager.util.collectEach import app.revanced.manager.util.collectEach
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -16,7 +16,7 @@ import kotlinx.coroutines.withContext
class InstalledAppsViewModel( class InstalledAppsViewModel(
private val installedAppsRepository: InstalledAppRepository, private val installedAppsRepository: InstalledAppRepository,
private val pm: PM, private val pm: PM,
val shizukuApi: ShizukuApi val shizukuService: ShizukuService
) : ViewModel() { ) : ViewModel() {
val apps = installedAppsRepository.getAll().flowOn(Dispatchers.IO) val apps = installedAppsRepository.getAll().flowOn(Dispatchers.IO)

View File

@ -28,7 +28,7 @@ import app.revanced.manager.patcher.worker.PatcherProgressManager
import app.revanced.manager.patcher.worker.PatcherWorker import app.revanced.manager.patcher.worker.PatcherWorker
import app.revanced.manager.patcher.worker.Step import app.revanced.manager.patcher.worker.Step
import app.revanced.manager.service.InstallService import app.revanced.manager.service.InstallService
import app.revanced.manager.service.ShizukuApi import app.revanced.manager.service.ShizukuService
import app.revanced.manager.service.UninstallService import app.revanced.manager.service.UninstallService
import app.revanced.manager.ui.destination.Destination import app.revanced.manager.ui.destination.Destination
import app.revanced.manager.util.PM import app.revanced.manager.util.PM
@ -56,7 +56,7 @@ class InstallerViewModel(input: Destination.Installer) : ViewModel(), KoinCompon
private val workerRepository: WorkerRepository by inject() private val workerRepository: WorkerRepository by inject()
private val installedAppReceiver: InstalledAppRepository by inject() private val installedAppReceiver: InstalledAppRepository by inject()
private val shizukuApi: ShizukuApi by inject() private val shizukuService: ShizukuService by inject()
val prefs: PreferencesManager by inject() val prefs: PreferencesManager by inject()
val packageName: String = input.selectedApp.packageName val packageName: String = input.selectedApp.packageName
private val outputFile = File(app.cacheDir, "output.apk") private val outputFile = File(app.cacheDir, "output.apk")
@ -210,7 +210,7 @@ class InstallerViewModel(input: Destination.Installer) : ViewModel(), KoinCompon
pm.installApp(listOf(signedFile)) pm.installApp(listOf(signedFile))
} }
PreferencesManager.InstallerManager.SHIZUKU -> { PreferencesManager.InstallerManager.SHIZUKU -> {
shizukuApi.installPackage(signedFile) shizukuService.installPackage(signedFile)
} }
PreferencesManager.InstallerManager.ROOT -> { PreferencesManager.InstallerManager.ROOT -> {
// RootApi.installPackage(signedFile) // RootApi.installPackage(signedFile)