From ed6908a5cd93ef966a2628f918c4c1b2e121ccff Mon Sep 17 00:00:00 2001 From: BinTianqi Date: Wed, 26 Nov 2025 13:11:33 +0800 Subject: [PATCH] Fix AppLock bug (#200, #201, #202) Fix Managed configuration item ordering (#198) Remove app from list after uninstall (#205) --- .../java/com/bintianqi/owndroid/AppLock.kt | 2 +- .../com/bintianqi/owndroid/MyViewModel.kt | 13 +++++++----- .../bintianqi/owndroid/dpm/Applications.kt | 20 +++++++++++++----- .../java/com/bintianqi/owndroid/dpm/System.kt | 21 +++++++++++++++---- app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 6 files changed, 43 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/com/bintianqi/owndroid/AppLock.kt b/app/src/main/java/com/bintianqi/owndroid/AppLock.kt index 9c64c20..88b59f5 100644 --- a/app/src/main/java/com/bintianqi/owndroid/AppLock.kt +++ b/app/src/main/java/com/bintianqi/owndroid/AppLock.kt @@ -84,7 +84,7 @@ fun AppLockDialog(onSucceed: () -> Unit, onDismiss: () -> Unit) = Dialog(onDismi } } } - Button(::unlock, Modifier.align(Alignment.End).padding(top = 8.dp), input.length >= 4) { + Button(::unlock, Modifier.align(Alignment.End).padding(top = 8.dp)) { Text(stringResource(R.string.unlock)) } } diff --git a/app/src/main/java/com/bintianqi/owndroid/MyViewModel.kt b/app/src/main/java/com/bintianqi/owndroid/MyViewModel.kt index 5bfdcca..6f02c1a 100644 --- a/app/src/main/java/com/bintianqi/owndroid/MyViewModel.kt +++ b/app/src/main/java/com/bintianqi/owndroid/MyViewModel.kt @@ -158,10 +158,10 @@ class MyViewModel(application: Application): AndroidViewModel(application) { return AppLockConfig(passwordHash?.ifEmpty { null }, SP.biometricsUnlock, SP.lockWhenLeaving) } fun setAppLockConfig(config: AppLockConfig) { - SP.lockPasswordHash = if (config.password == null) { - "" - } else { - config.password.hash() + if (config.password == null) { + SP.lockPasswordHash = "" + } else if (!config.password.isEmpty()) { + SP.lockPasswordHash = config.password.hash() } SP.biometricsUnlock = config.biometrics SP.lockWhenLeaving = config.whenLeaving @@ -359,8 +359,11 @@ class MyViewModel(application: Application): AndroidViewModel(application) { context.startActivity(intent.getParcelableExtra(Intent.EXTRA_INTENT) as Intent?) } else { context.unregisterReceiver(this) - if(statusExtra == PackageInstaller.STATUS_SUCCESS) { + if (statusExtra == PackageInstaller.STATUS_SUCCESS) { onComplete(null) + installedPackages.update { pkg -> + pkg.filter { it.name != packageName } + } } else { onComplete(parsePackageInstallerMessage(context, intent)) } diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/Applications.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/Applications.kt index 557adc4..fad0691 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/Applications.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/Applications.kt @@ -121,6 +121,7 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.serialization.Serializable import sh.calvin.reorderable.ReorderableItem import sh.calvin.reorderable.rememberReorderableLazyListState +import kotlin.collections.indexOf val String.isValidPackageName get() = Regex("""^(?:[a-zA-Z]\w*\.)+[a-zA-Z]\w*$""").matches(this) @@ -317,7 +318,10 @@ fun ApplicationDetailsScreen( } if(dialog == 1 && VERSION.SDK_INT >= 28) ClearAppStorageDialog(packageName, vm::clearAppData) { dialog = 0 } - if(dialog == 2) UninstallAppDialog(packageName, vm::uninstallPackage) { dialog = 0 } + if(dialog == 2) UninstallAppDialog(packageName, vm::uninstallPackage) { + dialog = 0 + if (it) onNavigateUp() + } } @Serializable object Suspend @@ -522,7 +526,8 @@ fun UninstallAppScreen( @Composable private fun UninstallAppDialog( - packageName: String, onUninstall: (String, (String?) -> Unit) -> Unit, onClose: () -> Unit + packageName: String, onUninstall: (String, (String?) -> Unit) -> Unit, + onClose: (Boolean) -> Unit ) { var uninstalling by rememberSaveable { mutableStateOf(false) } var errorMessage by rememberSaveable { mutableStateOf(null) } @@ -538,7 +543,7 @@ private fun UninstallAppDialog( uninstalling = true onUninstall(packageName) { uninstalling = false - if(it == null) onClose() else errorMessage = it + if (it == null) onClose(true) else errorMessage = it } }, enabled = !uninstalling, @@ -548,9 +553,11 @@ private fun UninstallAppDialog( } }, dismissButton = { - TextButton(onClose, enabled = !uninstalling) { Text(stringResource(R.string.cancel)) } + TextButton({ + onClose(false) + }, enabled = !uninstalling) { Text(stringResource(R.string.cancel)) } }, - onDismissRequest = onClose, + onDismissRequest = { onClose(false) }, properties = DialogProperties(false, false) ) } @@ -1176,6 +1183,9 @@ fun ManagedConfigurationDialog( value, restriction.entries.getOrNull(index), restriction.value?.contains(value) ?: false ) + }.sortedBy { entry -> + val index = restriction.value?.indexOf(entry.value) + if (index == null || index == -1) Int.MAX_VALUE else index } } else emptyList()).toTypedArray() ) diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/System.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/System.kt index 777e865..2ca218c 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/System.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/System.kt @@ -72,7 +72,6 @@ import androidx.compose.material3.PrimaryTabRow import androidx.compose.material3.Scaffold import androidx.compose.material3.Slider import androidx.compose.material3.Tab -import androidx.compose.material3.TabRow import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.TimePicker @@ -97,6 +96,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType @@ -181,7 +181,7 @@ fun SystemManagerScreen( if(VERSION.SDK_INT >= 31) { FunctionItem(R.string.nearby_streaming_policy, icon = R.drawable.share_fill0) { onNavigate(NearbyStreamingPolicy) } } - if (VERSION.SDK_INT >= 28 && privilege.device && !privilege.dhizuku) { + if (VERSION.SDK_INT >= 28 && privilege.device) { FunctionItem(R.string.lock_task_mode, icon = R.drawable.lock_fill0) { onNavigate(LockTaskMode) } } FunctionItem(R.string.ca_cert, icon = R.drawable.license_fill0) { onNavigate(CaCert) } @@ -1175,7 +1175,7 @@ fun LockTaskModeScreen( .fillMaxSize() .padding(paddingValues) ) { - TabRow(tabIndex) { + PrimaryTabRow(tabIndex) { Tab( tabIndex == 0, onClick = { coroutine.launch { pagerState.animateScrollToPage(0) } }, text = { Text(stringResource(R.string.start)) } @@ -1210,6 +1210,7 @@ private fun StartLockTaskMode( ) { val context = LocalContext.current val focusMgr = LocalFocusManager.current + val privilege by Privilege.status.collectAsStateWithLifecycle() var packageName by rememberSaveable { mutableStateOf("") } var activity by rememberSaveable { mutableStateOf("") } var specifyActivity by rememberSaveable { mutableStateOf(false) } @@ -1223,6 +1224,17 @@ private fun StartLockTaskMode( .verticalScroll(rememberScrollState()) ) { Spacer(Modifier.height(5.dp)) + if (privilege.dhizuku) Column( + Modifier + .fillMaxWidth().padding(vertical = 8.dp) + .background(colorScheme.errorContainer, RoundedCornerShape(10.dp)) + .padding(8.dp) + ) { + Text( + stringResource(R.string.start_lock_task_mode_not_supported), + color = colorScheme.onErrorContainer + ) + } PackageNameTextField(packageName, onChoosePackage) { packageName = it } Row( Modifier @@ -1252,10 +1264,11 @@ private fun StartLockTaskMode( if (!result) context.showOperationResultToast(false) }, enabled = packageName.isNotBlank() && (!specifyActivity || activity.isNotBlank()) + && !privilege.dhizuku ) { Text(stringResource(R.string.start)) } - Notes(R.string.info_start_lock_task_mode) + if (!privilege.dhizuku) Notes(R.string.info_start_lock_task_mode) } } diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 58fffd4..e494d21 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -173,6 +173,7 @@ 附近通知传输 在足够安全时启用 锁定任务模式 + Dhizuku模式下不支持启动锁定任务模式 应用未被允许 禁用全部 允许状态栏信息 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 36c4ef8..5e8682b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -201,6 +201,7 @@ Nearby notification streaming policy Same managed account only Lock task mode + Starting lock task mode is not supported under Dhizuku mode App is not allowed Disable all