From cb1ba36514660f08a406b3c63475bfb37d71efa6 Mon Sep 17 00:00:00 2001 From: Nullptr <52071314+Dr-TSNG@users.noreply.github.com> Date: Thu, 7 Jul 2022 01:23:30 +0800 Subject: [PATCH] Type safe preferences & Change topbar style --- .../java/org/lsposed/lspatch/Constants.kt | 5 --- .../main/java/org/lsposed/lspatch/Patcher.kt | 9 ++--- .../org/lsposed/lspatch/config/Configs.kt | 35 +++++++++++++++++ .../org/lsposed/lspatch/config/MyKeyStore.kt | 38 +++++-------------- .../lspatch/ui/component/CenterTopBar.kt | 27 +++++++++++++ .../lspatch/ui/component/settings/Switch.kt | 3 +- .../org/lsposed/lspatch/ui/page/HomeScreen.kt | 21 ++-------- .../org/lsposed/lspatch/ui/page/LogsScreen.kt | 13 ++----- .../lsposed/lspatch/ui/page/ManageScreen.kt | 21 +++------- .../org/lsposed/lspatch/ui/page/RepoScreen.kt | 13 ++----- .../lsposed/lspatch/ui/page/SettingsScreen.kt | 22 +++++++---- .../lspatch/ui/page/manage/AppManagePage.kt | 8 ++-- .../lspatch/ui/util/MultiDelegateState.kt | 31 +++++++++++++++ .../org/lsposed/lspatch/ui/util/Preview.kt | 7 ++++ .../lspatch/ui/viewmodel/NewPatchViewModel.kt | 1 - .../ui/viewmodel/manage/AppManageViewModel.kt | 9 +---- .../lsposed/lspatch/util/LSPPackageManager.kt | 8 ++-- manager/src/main/res/values/strings.xml | 1 + 18 files changed, 157 insertions(+), 115 deletions(-) create mode 100644 manager/src/main/java/org/lsposed/lspatch/config/Configs.kt create mode 100644 manager/src/main/java/org/lsposed/lspatch/ui/component/CenterTopBar.kt create mode 100644 manager/src/main/java/org/lsposed/lspatch/ui/util/MultiDelegateState.kt create mode 100644 manager/src/main/java/org/lsposed/lspatch/ui/util/Preview.kt diff --git a/manager/src/main/java/org/lsposed/lspatch/Constants.kt b/manager/src/main/java/org/lsposed/lspatch/Constants.kt index b7e4a52..6223a36 100644 --- a/manager/src/main/java/org/lsposed/lspatch/Constants.kt +++ b/manager/src/main/java/org/lsposed/lspatch/Constants.kt @@ -3,9 +3,4 @@ package org.lsposed.lspatch object Constants { const val PATCH_FILE_SUFFIX = "-lspatched.apk" - - const val PREFS_KEYSTORE_PASSWORD = "keystore_password" - const val PREFS_KEYSTORE_ALIAS = "keystore_alias" - const val PREFS_KEYSTORE_ALIAS_PASSWORD = "keystore_alias_password" - const val PREFS_STORAGE_DIRECTORY = "storage_directory" } diff --git a/manager/src/main/java/org/lsposed/lspatch/Patcher.kt b/manager/src/main/java/org/lsposed/lspatch/Patcher.kt index b48c998..28ddda4 100644 --- a/manager/src/main/java/org/lsposed/lspatch/Patcher.kt +++ b/manager/src/main/java/org/lsposed/lspatch/Patcher.kt @@ -5,7 +5,7 @@ import androidx.documentfile.provider.DocumentFile import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.lsposed.lspatch.Constants.PATCH_FILE_SUFFIX -import org.lsposed.lspatch.Constants.PREFS_STORAGE_DIRECTORY +import org.lsposed.lspatch.config.Configs import org.lsposed.lspatch.config.MyKeyStore import org.lsposed.lspatch.share.PatchConfig import org.lsposed.patch.LSPatch @@ -15,7 +15,6 @@ import java.io.IOException object Patcher { class Options( - private val verbose: Boolean, private val config: PatchConfig, private val apkPaths: List, private val embeddedModules: List? @@ -30,12 +29,12 @@ object Patcher { add("--v2"); add(config.v2.toString()) if (config.useManager) add("--manager") if (config.overrideVersionCode) add("-r") - if (verbose) add("-v") + if (Configs.detailPatchLogs) add("-v") embeddedModules?.forEach { add("-m"); add(it) } if (!MyKeyStore.useDefault) { - addAll(arrayOf("-k", MyKeyStore.file.path, MyKeyStore.password, MyKeyStore.alias, MyKeyStore.aliasPassword)) + addAll(arrayOf("-k", MyKeyStore.file.path, Configs.keyStorePassword, Configs.keyStoreAlias, Configs.keyStoreAliasPassword)) } }.toTypedArray() } @@ -45,7 +44,7 @@ object Patcher { withContext(Dispatchers.IO) { LSPatch(logger, *options.toStringArray()).doCommandLine() - val uri = lspApp.prefs.getString(PREFS_STORAGE_DIRECTORY, null)?.toUri() + val uri = Configs.storageDirectory?.toUri() ?: throw IOException("Uri is null") val root = DocumentFile.fromTreeUri(lspApp, uri) ?: throw IOException("DocumentFile is null") diff --git a/manager/src/main/java/org/lsposed/lspatch/config/Configs.kt b/manager/src/main/java/org/lsposed/lspatch/config/Configs.kt new file mode 100644 index 0000000..0f7cb8e --- /dev/null +++ b/manager/src/main/java/org/lsposed/lspatch/config/Configs.kt @@ -0,0 +1,35 @@ +package org.lsposed.lspatch.config + +import org.lsposed.lspatch.lspApp +import org.lsposed.lspatch.ui.util.delegateStateOf +import org.lsposed.lspatch.ui.util.getValue +import org.lsposed.lspatch.ui.util.setValue + +object Configs { + + private const val PREFS_KEYSTORE_PASSWORD = "keystore_password" + private const val PREFS_KEYSTORE_ALIAS = "keystore_alias" + private const val PREFS_KEYSTORE_ALIAS_PASSWORD = "keystore_alias_password" + private const val PREFS_STORAGE_DIRECTORY = "storage_directory" + private const val PREFS_DETAIL_PATCH_LOGS = "detail_patch_logs" + + var keyStorePassword by delegateStateOf(lspApp.prefs.getString(PREFS_KEYSTORE_PASSWORD, "123456")!!) { + lspApp.prefs.edit().putString(PREFS_KEYSTORE_PASSWORD, it).apply() + } + + var keyStoreAlias by delegateStateOf(lspApp.prefs.getString(PREFS_KEYSTORE_ALIAS, "key0")!!) { + lspApp.prefs.edit().putString(PREFS_KEYSTORE_ALIAS, it).apply() + } + + var keyStoreAliasPassword by delegateStateOf(lspApp.prefs.getString(PREFS_KEYSTORE_ALIAS_PASSWORD, "123456")!!) { + lspApp.prefs.edit().putString(PREFS_KEYSTORE_ALIAS_PASSWORD, it).apply() + } + + var storageDirectory by delegateStateOf(lspApp.prefs.getString(PREFS_STORAGE_DIRECTORY, null)) { + lspApp.prefs.edit().putString(PREFS_STORAGE_DIRECTORY, it).apply() + } + + var detailPatchLogs by delegateStateOf(lspApp.prefs.getBoolean(PREFS_DETAIL_PATCH_LOGS, true)) { + lspApp.prefs.edit().putBoolean(PREFS_DETAIL_PATCH_LOGS, it).apply() + } +} diff --git a/manager/src/main/java/org/lsposed/lspatch/config/MyKeyStore.kt b/manager/src/main/java/org/lsposed/lspatch/config/MyKeyStore.kt index 3e7b1c3..b8cacdb 100644 --- a/manager/src/main/java/org/lsposed/lspatch/config/MyKeyStore.kt +++ b/manager/src/main/java/org/lsposed/lspatch/config/MyKeyStore.kt @@ -1,56 +1,38 @@ package org.lsposed.lspatch.config -import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import org.lsposed.lspatch.Constants.PREFS_KEYSTORE_ALIAS -import org.lsposed.lspatch.Constants.PREFS_KEYSTORE_ALIAS_PASSWORD -import org.lsposed.lspatch.Constants.PREFS_KEYSTORE_PASSWORD import org.lsposed.lspatch.lspApp import java.io.File object MyKeyStore { val file = File("${lspApp.filesDir}/keystore.bks") - val tmpFile = File("${lspApp.filesDir}/keystore.bks.tmp") - val password: String - get() = lspApp.prefs.getString("keystore_password", "123456")!! - - val alias: String - get() = lspApp.prefs.getString("keystore_alias", "key0")!! - - val aliasPassword: String - get() = lspApp.prefs.getString("keystore_alias_password", "123456")!! - - private var mUseDefault by mutableStateOf(!file.exists()) - val useDefault by derivedStateOf { mUseDefault } + var useDefault by mutableStateOf(!file.exists()) + private set suspend fun reset() { withContext(Dispatchers.IO) { file.delete() - lspApp.prefs.edit() - .putString(PREFS_KEYSTORE_PASSWORD, "123456") - .putString(PREFS_KEYSTORE_ALIAS, "key0") - .putString(PREFS_KEYSTORE_ALIAS_PASSWORD, "123456") - .apply() - mUseDefault = true + Configs.keyStorePassword = "123456" + Configs.keyStoreAlias = "key0" + Configs.keyStoreAliasPassword = "123456" + useDefault = true } } suspend fun setCustom(password: String, alias: String, aliasPassword: String) { withContext(Dispatchers.IO) { tmpFile.renameTo(file) - lspApp.prefs.edit() - .putString(PREFS_KEYSTORE_PASSWORD, password) - .putString(PREFS_KEYSTORE_ALIAS, alias) - .putString(PREFS_KEYSTORE_ALIAS_PASSWORD, aliasPassword) - .apply() - mUseDefault = false + Configs.keyStorePassword = password + Configs.keyStoreAlias = alias + Configs.keyStoreAliasPassword = aliasPassword + useDefault = false } } } diff --git a/manager/src/main/java/org/lsposed/lspatch/ui/component/CenterTopBar.kt b/manager/src/main/java/org/lsposed/lspatch/ui/component/CenterTopBar.kt new file mode 100644 index 0000000..350fabf --- /dev/null +++ b/manager/src/main/java/org/lsposed/lspatch/ui/component/CenterTopBar.kt @@ -0,0 +1,27 @@ +package org.lsposed.lspatch.ui.component + +import androidx.compose.material3.CenterAlignedTopAppBar +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import org.lsposed.lspatch.ui.util.SampleStringProvider + +@Preview +@Composable +fun CenterTopBar(@PreviewParameter(SampleStringProvider::class, 1) text: String) { + CenterAlignedTopAppBar( + title = { + Text( + text = text, + color = MaterialTheme.colorScheme.primary, + fontWeight = FontWeight.Bold, + fontFamily = FontFamily.Monospace, + style = MaterialTheme.typography.titleMedium + ) + } + ) +} diff --git a/manager/src/main/java/org/lsposed/lspatch/ui/component/settings/Switch.kt b/manager/src/main/java/org/lsposed/lspatch/ui/component/settings/Switch.kt index 48a790a..43ffd49 100644 --- a/manager/src/main/java/org/lsposed/lspatch/ui/component/settings/Switch.kt +++ b/manager/src/main/java/org/lsposed/lspatch/ui/component/settings/Switch.kt @@ -1,5 +1,6 @@ package org.lsposed.lspatch.ui.component.settings +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope import androidx.compose.material.icons.Icons @@ -21,7 +22,7 @@ fun SettingsSwitch( desc: String? = null, extraContent: (@Composable ColumnScope.() -> Unit)? = null ) { - SettingsSlot(modifier, enabled, onClick, icon, title, desc, extraContent) { + SettingsSlot(modifier.clickable(onClick = onClick), enabled, onClick, icon, title, desc, extraContent) { Switch(checked = checked, onCheckedChange = { onClick() }) } } diff --git a/manager/src/main/java/org/lsposed/lspatch/ui/page/HomeScreen.kt b/manager/src/main/java/org/lsposed/lspatch/ui/page/HomeScreen.kt index e2bba09..209d6a7 100644 --- a/manager/src/main/java/org/lsposed/lspatch/ui/page/HomeScreen.kt +++ b/manager/src/main/java/org/lsposed/lspatch/ui/page/HomeScreen.kt @@ -30,6 +30,7 @@ import com.ramcosta.composedestinations.annotation.RootNavGraph import kotlinx.coroutines.launch import org.lsposed.lspatch.R import org.lsposed.lspatch.share.LSPConfig +import org.lsposed.lspatch.ui.component.CenterTopBar import org.lsposed.lspatch.ui.util.HtmlText import org.lsposed.lspatch.ui.util.LocalSnackbarHost import org.lsposed.lspatch.util.ShizukuApi @@ -40,7 +41,9 @@ import rikka.shizuku.Shizuku @Destination @Composable fun HomeScreen() { - Scaffold(topBar = { TopBar() }) { innerPadding -> + Scaffold( + topBar = { CenterTopBar(stringResource(R.string.app_name)) } + ) { innerPadding -> Column( modifier = Modifier .padding(innerPadding) @@ -56,22 +59,6 @@ fun HomeScreen() { } } -@Preview -@Composable -private fun TopBar() { - CenterAlignedTopAppBar( - title = { - Text( - text = stringResource(R.string.app_name), - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold, - fontFamily = FontFamily.Monospace, - style = MaterialTheme.typography.titleMedium - ) - } - ) -} - private val listener: (Int, Int) -> Unit = { _, grantResult -> ShizukuApi.isPermissionGranted = grantResult == PackageManager.PERMISSION_GRANTED } diff --git a/manager/src/main/java/org/lsposed/lspatch/ui/page/LogsScreen.kt b/manager/src/main/java/org/lsposed/lspatch/ui/page/LogsScreen.kt index 3204c3b..5249043 100644 --- a/manager/src/main/java/org/lsposed/lspatch/ui/page/LogsScreen.kt +++ b/manager/src/main/java/org/lsposed/lspatch/ui/page/LogsScreen.kt @@ -4,19 +4,21 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Scaffold -import androidx.compose.material3.SmallTopAppBar import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import com.ramcosta.composedestinations.annotation.Destination +import org.lsposed.lspatch.ui.component.CenterTopBar @OptIn(ExperimentalMaterial3Api::class) @Destination @Composable fun LogsScreen() { - Scaffold(topBar = { TopBar() }) { innerPadding -> + Scaffold( + topBar = { CenterTopBar(stringResource(BottomBarDestination.Logs.label)) } + ) { innerPadding -> Text( modifier = Modifier .padding(innerPadding) @@ -26,10 +28,3 @@ fun LogsScreen() { ) } } - -@Composable -private fun TopBar() { - SmallTopAppBar( - title = { Text(stringResource(BottomBarDestination.Logs.label)) } - ) -} diff --git a/manager/src/main/java/org/lsposed/lspatch/ui/page/ManageScreen.kt b/manager/src/main/java/org/lsposed/lspatch/ui/page/ManageScreen.kt index b335901..3c7846b 100644 --- a/manager/src/main/java/org/lsposed/lspatch/ui/page/ManageScreen.kt +++ b/manager/src/main/java/org/lsposed/lspatch/ui/page/ManageScreen.kt @@ -4,7 +4,6 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.material3.* -import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier @@ -18,6 +17,7 @@ import com.ramcosta.composedestinations.navigation.DestinationsNavigator import com.ramcosta.composedestinations.result.ResultRecipient import kotlinx.coroutines.launch import org.lsposed.lspatch.R +import org.lsposed.lspatch.ui.component.CenterTopBar import org.lsposed.lspatch.ui.page.destinations.SelectAppsScreenDestination import org.lsposed.lspatch.ui.page.manage.AppManageBody import org.lsposed.lspatch.ui.page.manage.AppManageFab @@ -33,23 +33,21 @@ fun ManageScreen( val scope = rememberCoroutineScope() val pagerState = rememberPagerState() Scaffold( - topBar = { TopBar() }, + topBar = { CenterTopBar(stringResource(BottomBarDestination.Manage.label)) }, floatingActionButton = { if (pagerState.currentPage == 0) AppManageFab(navigator) } ) { innerPadding -> Box(Modifier.padding(innerPadding)) { Column { TabRow( - selectedTabIndex = pagerState.currentPage, - indicator = { tabPositions -> - TabRowDefaults.Indicator(Modifier.tabIndicatorOffset(tabPositions[pagerState.currentPage])) - } + contentColor = MaterialTheme.colorScheme.secondary, + selectedTabIndex = pagerState.currentPage ) { Tab( selected = pagerState.currentPage == 0, onClick = { scope.launch { pagerState.animateScrollToPage(0) } } ) { Text( - modifier = Modifier.padding(vertical = 12.dp), + modifier = Modifier.padding(vertical = 16.dp), text = stringResource(R.string.apps) ) } @@ -58,7 +56,7 @@ fun ManageScreen( onClick = { scope.launch { pagerState.animateScrollToPage(1) } } ) { Text( - modifier = Modifier.padding(vertical = 12.dp), + modifier = Modifier.padding(vertical = 16.dp), text = stringResource(R.string.modules) ) } @@ -74,10 +72,3 @@ fun ManageScreen( } } } - -@Composable -private fun TopBar() { - SmallTopAppBar( - title = { Text(stringResource(BottomBarDestination.Manage.label)) } - ) -} diff --git a/manager/src/main/java/org/lsposed/lspatch/ui/page/RepoScreen.kt b/manager/src/main/java/org/lsposed/lspatch/ui/page/RepoScreen.kt index 67c55a0..60e5d89 100644 --- a/manager/src/main/java/org/lsposed/lspatch/ui/page/RepoScreen.kt +++ b/manager/src/main/java/org/lsposed/lspatch/ui/page/RepoScreen.kt @@ -4,19 +4,21 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Scaffold -import androidx.compose.material3.SmallTopAppBar import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import com.ramcosta.composedestinations.annotation.Destination +import org.lsposed.lspatch.ui.component.CenterTopBar @OptIn(ExperimentalMaterial3Api::class) @Destination @Composable fun RepoScreen() { - Scaffold(topBar = { TopBar() }) { innerPadding -> + Scaffold( + topBar = { CenterTopBar(stringResource(BottomBarDestination.Repo.label)) } + ) { innerPadding -> Text( modifier = Modifier .padding(innerPadding) @@ -26,10 +28,3 @@ fun RepoScreen() { ) } } - -@Composable -private fun TopBar() { - SmallTopAppBar( - title = { Text(stringResource(BottomBarDestination.Repo.label)) } - ) -} diff --git a/manager/src/main/java/org/lsposed/lspatch/ui/page/SettingsScreen.kt b/manager/src/main/java/org/lsposed/lspatch/ui/page/SettingsScreen.kt index b190ea9..ff34e05 100644 --- a/manager/src/main/java/org/lsposed/lspatch/ui/page/SettingsScreen.kt +++ b/manager/src/main/java/org/lsposed/lspatch/ui/page/SettingsScreen.kt @@ -25,8 +25,11 @@ import androidx.compose.ui.unit.dp import com.ramcosta.composedestinations.annotation.Destination import kotlinx.coroutines.launch import org.lsposed.lspatch.R +import org.lsposed.lspatch.config.Configs import org.lsposed.lspatch.config.MyKeyStore +import org.lsposed.lspatch.ui.component.CenterTopBar import org.lsposed.lspatch.ui.component.settings.SettingsItem +import org.lsposed.lspatch.ui.component.settings.SettingsSwitch import java.io.IOException import java.security.GeneralSecurityException import java.security.KeyStore @@ -36,7 +39,7 @@ import java.security.KeyStore @Composable fun SettingsScreen() { Scaffold( - topBar = { TopBar() } + topBar = { CenterTopBar(stringResource(BottomBarDestination.Settings.label)) } ) { innerPadding -> Column( modifier = Modifier @@ -44,17 +47,11 @@ fun SettingsScreen() { .verticalScroll(rememberScrollState()) ) { KeyStore() + DetailPatchLogs() } } } -@Composable -private fun TopBar() { - SmallTopAppBar( - title = { Text(stringResource(R.string.screen_settings)) } - ) -} - @Composable private fun KeyStore() { val context = LocalContext.current @@ -227,3 +224,12 @@ private fun KeyStore() { ) } } + +@Composable +private fun DetailPatchLogs() { + SettingsSwitch( + checked = Configs.detailPatchLogs, + onClick = { Configs.detailPatchLogs = !Configs.detailPatchLogs }, + title = stringResource(R.string.settings_detail_patch_logs) + ) +} diff --git a/manager/src/main/java/org/lsposed/lspatch/ui/page/manage/AppManagePage.kt b/manager/src/main/java/org/lsposed/lspatch/ui/page/manage/AppManagePage.kt index 6ce7b05..ea50970 100644 --- a/manager/src/main/java/org/lsposed/lspatch/ui/page/manage/AppManagePage.kt +++ b/manager/src/main/java/org/lsposed/lspatch/ui/page/manage/AppManagePage.kt @@ -35,9 +35,9 @@ import com.ramcosta.composedestinations.navigation.DestinationsNavigator import com.ramcosta.composedestinations.result.NavResult import com.ramcosta.composedestinations.result.ResultRecipient import kotlinx.coroutines.launch -import org.lsposed.lspatch.Constants import org.lsposed.lspatch.R import org.lsposed.lspatch.config.ConfigManager +import org.lsposed.lspatch.config.Configs import org.lsposed.lspatch.database.entity.Module import org.lsposed.lspatch.lspApp import org.lsposed.lspatch.share.LSPConfig @@ -232,7 +232,7 @@ fun AppManageFab(navigator: DestinationsNavigator) { val uri = it.data?.data ?: throw IOException("No data") val takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION context.contentResolver.takePersistableUriPermission(uri, takeFlags) - lspApp.prefs.edit().putString(Constants.PREFS_STORAGE_DIRECTORY, uri.toString()).apply() + Configs.storageDirectory = uri.toString() Log.i(TAG, "Storage directory: ${uri.path}") showNewPatchDialog = true } catch (e: Exception) { @@ -325,7 +325,7 @@ fun AppManageFab(navigator: DestinationsNavigator) { FloatingActionButton( content = { Icon(Icons.Filled.Add, stringResource(R.string.add)) }, onClick = { - val uri = lspApp.prefs.getString(Constants.PREFS_STORAGE_DIRECTORY, null)?.toUri() + val uri = Configs.storageDirectory?.toUri() if (uri == null) { shouldSelectDirectory = true } else { @@ -337,7 +337,7 @@ fun AppManageFab(navigator: DestinationsNavigator) { showNewPatchDialog = true }.onFailure { Log.w(TAG, "Failed to take persistable permission for saved uri", it) - lspApp.prefs.edit().putString(Constants.PREFS_STORAGE_DIRECTORY, null).apply() + Configs.storageDirectory = null shouldSelectDirectory = true } } diff --git a/manager/src/main/java/org/lsposed/lspatch/ui/util/MultiDelegateState.kt b/manager/src/main/java/org/lsposed/lspatch/ui/util/MultiDelegateState.kt new file mode 100644 index 0000000..4121904 --- /dev/null +++ b/manager/src/main/java/org/lsposed/lspatch/ui/util/MultiDelegateState.kt @@ -0,0 +1,31 @@ +package org.lsposed.lspatch.ui.util + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import kotlin.reflect.KProperty + +class DelegateState(initial: T, private val sideEffectSetter: (T) -> Unit) { + private var snapshot by mutableStateOf(initial) + + var value: T + get() = snapshot + set(value) { + snapshot = value + sideEffectSetter(snapshot) + } + + operator fun component1(): T = value + + operator fun component2(): (T) -> Unit = { value = it } +} + +fun delegateStateOf(initial: T, sideEffectSetter: (T) -> Unit) = DelegateState(initial, sideEffectSetter) + +@Suppress("NOTHING_TO_INLINE") +inline operator fun DelegateState.getValue(thisObj: Any?, property: KProperty<*>): T = value + +@Suppress("NOTHING_TO_INLINE") +inline operator fun DelegateState.setValue(thisObj: Any?, property: KProperty<*>, value: T) { + this.value = value +} diff --git a/manager/src/main/java/org/lsposed/lspatch/ui/util/Preview.kt b/manager/src/main/java/org/lsposed/lspatch/ui/util/Preview.kt new file mode 100644 index 0000000..5afca8c --- /dev/null +++ b/manager/src/main/java/org/lsposed/lspatch/ui/util/Preview.kt @@ -0,0 +1,7 @@ +package org.lsposed.lspatch.ui.util + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider + +class SampleStringProvider : PreviewParameterProvider { + override val values: Sequence = sequenceOf("Hello", "World") +} diff --git a/manager/src/main/java/org/lsposed/lspatch/ui/viewmodel/NewPatchViewModel.kt b/manager/src/main/java/org/lsposed/lspatch/ui/viewmodel/NewPatchViewModel.kt index 0dfee95..295d46b 100644 --- a/manager/src/main/java/org/lsposed/lspatch/ui/viewmodel/NewPatchViewModel.kt +++ b/manager/src/main/java/org/lsposed/lspatch/ui/viewmodel/NewPatchViewModel.kt @@ -89,7 +89,6 @@ class NewPatchViewModel : ViewModel() { Log.d(TAG, "Submit patch") if (useManager) embeddedModules = emptyList() patchOptions = Patcher.Options( - verbose = true, config = PatchConfig(useManager, debuggable, overrideVersionCode, sign[0], sign[1], sigBypassLevel, null, null), apkPaths = listOf(patchApp.app.sourceDir) + (patchApp.app.splitSourceDirs ?: emptyArray()), embeddedModules = embeddedModules.flatMap { listOf(it.app.sourceDir) + (it.app.splitSourceDirs ?: emptyArray()) } diff --git a/manager/src/main/java/org/lsposed/lspatch/ui/viewmodel/manage/AppManageViewModel.kt b/manager/src/main/java/org/lsposed/lspatch/ui/viewmodel/manage/AppManageViewModel.kt index 324f6d2..f10f713 100644 --- a/manager/src/main/java/org/lsposed/lspatch/ui/viewmodel/manage/AppManageViewModel.kt +++ b/manager/src/main/java/org/lsposed/lspatch/ui/viewmodel/manage/AppManageViewModel.kt @@ -96,14 +96,7 @@ class AppManageViewModel : ViewModel() { } } } - Patcher.patch( - logger, Patcher.Options( - verbose = true, - config = config, - apkPaths = patchPaths, - embeddedModules = embeddedModulePaths - ) - ) + Patcher.patch(logger, Patcher.Options(config, patchPaths, embeddedModulePaths)) val (status, message) = LSPPackageManager.install() if (status != PackageInstaller.STATUS_SUCCESS) throw RuntimeException(message) } diff --git a/manager/src/main/java/org/lsposed/lspatch/util/LSPPackageManager.kt b/manager/src/main/java/org/lsposed/lspatch/util/LSPPackageManager.kt index eda68c8..301f0a1 100644 --- a/manager/src/main/java/org/lsposed/lspatch/util/LSPPackageManager.kt +++ b/manager/src/main/java/org/lsposed/lspatch/util/LSPPackageManager.kt @@ -18,8 +18,8 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import kotlinx.parcelize.Parcelize import org.lsposed.lspatch.Constants.PATCH_FILE_SUFFIX -import org.lsposed.lspatch.Constants.PREFS_STORAGE_DIRECTORY import org.lsposed.lspatch.config.ConfigManager +import org.lsposed.lspatch.config.Configs import org.lsposed.lspatch.lspApp import org.lsposed.patch.util.ManifestParser import java.io.File @@ -86,10 +86,8 @@ object LSPPackageManager { flags = flags or 0x00000004 /* PackageManager.INSTALL_ALLOW_TEST */ or 0x00000002 /* PackageManager.INSTALL_REPLACE_EXISTING */ HiddenApiBridge.PackageInstaller_SessionParams_installFlags(params, flags) ShizukuApi.createPackageInstallerSession(params).use { session -> - val uri = lspApp.prefs.getString(PREFS_STORAGE_DIRECTORY, null)?.toUri() - ?: throw IOException("Uri is null") - val root = DocumentFile.fromTreeUri(lspApp, uri) - ?: throw IOException("DocumentFile is null") + val uri = Configs.storageDirectory?.toUri() ?: throw IOException("Uri is null") + val root = DocumentFile.fromTreeUri(lspApp, uri) ?: throw IOException("DocumentFile is null") root.listFiles().forEach { file -> if (file.name?.endsWith(PATCH_FILE_SUFFIX) != true) return@forEach Log.d(TAG, "Add ${file.name}") diff --git a/manager/src/main/res/values/strings.xml b/manager/src/main/res/values/strings.xml index a397039..51e0db3 100644 --- a/manager/src/main/res/values/strings.xml +++ b/manager/src/main/res/values/strings.xml @@ -84,4 +84,5 @@ Wrong keystore password Wrong alias name Wrong alias password + Detail patch logs