From c5d859f9905efb138357e26d25da6bd93f9bcbeb Mon Sep 17 00:00:00 2001 From: Aunali321 Date: Tue, 15 Aug 2023 00:07:29 +0530 Subject: [PATCH] feat: add settings to select default installer --- .../domain/manager/PreferencesManager.kt | 10 +++ .../screen/settings/AdvancedSettingsScreen.kt | 77 +++++++++++++++++++ .../screen/settings/GeneralSettingsScreen.kt | 7 +- .../ui/viewmodel/AdvancedSettingsViewModel.kt | 6 +- .../ui/viewmodel/InstallerViewModel.kt | 24 +++++- app/src/main/res/values/strings.xml | 5 ++ 6 files changed, 121 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/app/revanced/manager/domain/manager/PreferencesManager.kt b/app/src/main/java/app/revanced/manager/domain/manager/PreferencesManager.kt index 34d7af6..4856273 100644 --- a/app/src/main/java/app/revanced/manager/domain/manager/PreferencesManager.kt +++ b/app/src/main/java/app/revanced/manager/domain/manager/PreferencesManager.kt @@ -1,12 +1,21 @@ package app.revanced.manager.domain.manager import android.content.Context +import app.revanced.manager.R import app.revanced.manager.domain.manager.base.BasePreferencesManager import app.revanced.manager.ui.theme.Theme class PreferencesManager( context: Context ) : BasePreferencesManager(context, "settings") { + + enum class InstallerManager(val displayName: Int) { + DEFAULT(R.string.default_installer), + SHIZUKU(R.string.shizuku_installer), + ROOT(R.string.root_installer), + MAGISK(R.string.magisk_installer), + } + val dynamicColor = booleanPreference("dynamic_color", true) val theme = enumPreference("theme", Theme.SYSTEM) @@ -18,6 +27,7 @@ class PreferencesManager( val keystorePass = stringPreference("keystore_pass", KeystoreManager.DEFAULT) val preferSplits = booleanPreference("prefer_splits", false) + val installer = enumPreference("installer", InstallerManager.DEFAULT) val showAutoUpdatesDialog = booleanPreference("show_auto_updates_dialog", true) val managerAutoUpdates = booleanPreference("manager_auto_updates", false) diff --git a/app/src/main/java/app/revanced/manager/ui/screen/settings/AdvancedSettingsScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/settings/AdvancedSettingsScreen.kt index e390332..15aceb1 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/settings/AdvancedSettingsScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/settings/AdvancedSettingsScreen.kt @@ -5,18 +5,24 @@ import android.os.Build import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Http import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.FilledTonalButton import androidx.compose.material3.Icon import androidx.compose.material3.ListItem import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.RadioButton import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TextButton @@ -26,6 +32,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource @@ -33,10 +40,12 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.core.content.getSystemService import app.revanced.manager.R +import app.revanced.manager.domain.manager.PreferencesManager import app.revanced.manager.ui.component.AppTopBar import app.revanced.manager.ui.component.GroupHeader import app.revanced.manager.ui.viewmodel.AdvancedSettingsViewModel import org.koin.androidx.compose.getViewModel +import org.koin.compose.koinInject @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -44,7 +53,9 @@ fun AdvancedSettingsScreen( onBackClick: () -> Unit, vm: AdvancedSettingsViewModel = getViewModel() ) { + val prefs = vm.prefs val context = LocalContext.current + var showInstallerPicker by rememberSaveable { mutableStateOf(false) } val memoryLimit = remember { val activityManager = context.getSystemService()!! context.getString( @@ -54,6 +65,13 @@ fun AdvancedSettingsScreen( ) } + if (showInstallerPicker) { + InstallerPicker( + onDismiss = { showInstallerPicker = false }, + onConfirm = { vm.setInstaller(it) } + ) + } + Scaffold( topBar = { AppTopBar( @@ -99,6 +117,26 @@ fun AdvancedSettingsScreen( } ) + val installer by prefs.installer.getAsState() + GroupHeader(stringResource(R.string.installer)) + ListItem( + modifier = Modifier.clickable { showInstallerPicker = true }, + headlineContent = { Text(stringResource(R.string.installer)) }, + supportingContent = { Text(stringResource(R.string.installer_description)) }, + trailingContent = { + FilledTonalButton( + colors = ButtonDefaults.filledTonalButtonColors( + containerColor = MaterialTheme.colorScheme.primaryContainer, + ), + onClick = { + showInstallerPicker = true + } + ) { + Text(stringResource(installer.displayName)) + } + } + ) + GroupHeader(stringResource(R.string.device)) ListItem( headlineContent = { Text(stringResource(R.string.device_model)) }, @@ -172,4 +210,43 @@ private fun APIUrlDialog(currentUrl: String, onSubmit: (String?) -> Unit) { } } ) +} + +@Composable +private fun InstallerPicker( + onDismiss: () -> Unit, + onConfirm: (PreferencesManager.InstallerManager) -> Unit, + prefs: PreferencesManager = koinInject() +) { + var selectedInstaller by rememberSaveable { mutableStateOf(prefs.installer.getBlocking()) } + + AlertDialog( + onDismissRequest = onDismiss, + title = { Text(stringResource(R.string.installer)) }, + text = { + Column { + PreferencesManager.InstallerManager.values().forEach { + Row( + modifier = Modifier + .fillMaxWidth() + .clickable { selectedInstaller = it }, + verticalAlignment = Alignment.CenterVertically + ) { + RadioButton( + selected = selectedInstaller == it, + onClick = { selectedInstaller = it }) + Text(stringResource(it.displayName)) + } + } + } + }, + confirmButton = { + Button(onClick = { + onConfirm(selectedInstaller) + onDismiss() + }) { + Text(stringResource(R.string.apply)) + } + } + ) } \ No newline at end of file diff --git a/app/src/main/java/app/revanced/manager/ui/screen/settings/GeneralSettingsScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/settings/GeneralSettingsScreen.kt index 6838f92..da1501a 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/settings/GeneralSettingsScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/settings/GeneralSettingsScreen.kt @@ -1,7 +1,6 @@ package app.revanced.manager.ui.screen.settings import android.os.Build -import androidx.annotation.StringRes import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.rememberScrollState @@ -23,7 +22,6 @@ import app.revanced.manager.ui.component.GroupHeader import app.revanced.manager.ui.component.settings.BooleanItem import app.revanced.manager.ui.theme.Theme import app.revanced.manager.ui.viewmodel.SettingsViewModel -import kotlinx.coroutines.launch import org.koin.compose.koinInject @OptIn(ExperimentalMaterial3Api::class) @@ -65,7 +63,10 @@ fun GeneralSettingsScreen( headlineContent = { Text(stringResource(R.string.theme)) }, supportingContent = { Text(stringResource(R.string.theme_description)) }, trailingContent = { - Button( + FilledTonalButton( + colors = ButtonDefaults.filledTonalButtonColors( + containerColor = MaterialTheme.colorScheme.primaryContainer, + ), onClick = { showThemePicker = true } diff --git a/app/src/main/java/app/revanced/manager/ui/viewmodel/AdvancedSettingsViewModel.kt b/app/src/main/java/app/revanced/manager/ui/viewmodel/AdvancedSettingsViewModel.kt index 6b08400..4c88c85 100644 --- a/app/src/main/java/app/revanced/manager/ui/viewmodel/AdvancedSettingsViewModel.kt +++ b/app/src/main/java/app/revanced/manager/ui/viewmodel/AdvancedSettingsViewModel.kt @@ -12,7 +12,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch class AdvancedSettingsViewModel( - prefs: PreferencesManager, + val prefs: PreferencesManager, private val app: Application, private val patchBundleRepository: PatchBundleRepository ) : ViewModel() { @@ -34,4 +34,8 @@ class AdvancedSettingsViewModel( fun resetBundles() = viewModelScope.launch { patchBundleRepository.reset() } + + fun setInstaller(installer: PreferencesManager.InstallerManager) = viewModelScope.launch { + prefs.installer.update(installer) + } } \ No newline at end of file diff --git a/app/src/main/java/app/revanced/manager/ui/viewmodel/InstallerViewModel.kt b/app/src/main/java/app/revanced/manager/ui/viewmodel/InstallerViewModel.kt index cd5e057..5b1878d 100644 --- a/app/src/main/java/app/revanced/manager/ui/viewmodel/InstallerViewModel.kt +++ b/app/src/main/java/app/revanced/manager/ui/viewmodel/InstallerViewModel.kt @@ -20,6 +20,7 @@ import androidx.work.WorkInfo import androidx.work.WorkManager import app.revanced.manager.domain.manager.KeystoreManager import app.revanced.manager.R +import app.revanced.manager.domain.manager.PreferencesManager import app.revanced.manager.domain.worker.WorkerRepository import app.revanced.manager.patcher.worker.PatcherProgressManager import app.revanced.manager.patcher.worker.PatcherWorker @@ -52,6 +53,7 @@ class InstallerViewModel(input: Destination.Installer) : ViewModel(), KoinCompon private val pm: PM by inject() private val workerRepository: WorkerRepository by inject() + val prefs: PreferencesManager by inject() val packageName: String = input.selectedApp.packageName private val outputFile = File(app.cacheDir, "output.apk") private val signedFile = File(app.cacheDir, "signed.apk").also { if (it.exists()) it.delete() } @@ -62,6 +64,7 @@ class InstallerViewModel(input: Destination.Installer) : ViewModel(), KoinCompon var installedPackageName by mutableStateOf(null) private set val appButtonText by derivedStateOf { if (installedPackageName == null) R.string.install_app else R.string.open_app } + private val selectedInstaller by derivedStateOf { prefs.installer.getBlocking() } private val workManager = WorkManager.getInstance(app) @@ -124,7 +127,7 @@ class InstallerViewModel(input: Destination.Installer) : ViewModel(), KoinCompon } } } - + init { app.registerReceiver(installBroadcastReceiver, IntentFilter().apply { addAction(InstallService.APP_INSTALL_ACTION) @@ -189,9 +192,22 @@ class InstallerViewModel(input: Destination.Installer) : ViewModel(), KoinCompon isInstalling = true try { if (!signApk()) return@launch -// -// pm.installApp(listOf(signedFile)) - ShizukuApi.installPackage(signedFile) + + when (selectedInstaller) { + PreferencesManager.InstallerManager.DEFAULT -> { + pm.installApp(listOf(signedFile)) + } + PreferencesManager.InstallerManager.SHIZUKU -> { + ShizukuApi.installPackage(signedFile) + } + PreferencesManager.InstallerManager.ROOT -> { + // RootApi.installPackage(signedFile) + } + PreferencesManager.InstallerManager.MAGISK -> { + // MagiskApi.installPackage(signedFile) + } + } + } finally { isInstalling = false } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 263d3a3..58f4e19 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -233,4 +233,9 @@ Shizuku service available Shizuku service not connected Some functions unavailable + Choose the default installer + Default + Shizuku + Root + Magisk \ No newline at end of file