Optimize start/stop lock task mode flow

Optimize Package selector
This commit is contained in:
BinTianqi
2024-12-21 20:07:32 +08:00
parent 873896ec10
commit 84c1dff9e6
16 changed files with 216 additions and 285 deletions

View File

@@ -50,7 +50,6 @@ import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableIntState
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
@@ -74,37 +73,37 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat.startActivity
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.bintianqi.owndroid.InstallAppActivity
import com.bintianqi.owndroid.MyViewModel
import com.bintianqi.owndroid.PackageInstallerReceiver
import com.bintianqi.owndroid.R
import com.bintianqi.owndroid.fileUriFlow
import com.bintianqi.owndroid.getFile
import com.bintianqi.owndroid.selectedPackage
import com.bintianqi.owndroid.ui.Animations
import com.bintianqi.owndroid.ui.FunctionItem
import com.bintianqi.owndroid.ui.InfoCard
import com.bintianqi.owndroid.ui.Information
import com.bintianqi.owndroid.ui.ListItem
import com.bintianqi.owndroid.ui.NavIcon
import com.bintianqi.owndroid.ui.RadioButtonItem
import com.bintianqi.owndroid.ui.FunctionItem
import com.bintianqi.owndroid.ui.SwitchItem
import java.util.concurrent.Executors
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ApplicationManage(navCtrl:NavHostController, dialogStatus: MutableIntState) {
fun ApplicationManage(navCtrl:NavHostController, vm: MyViewModel) {
val focusMgr = LocalFocusManager.current
val localNavCtrl = rememberNavController()
var pkgName by rememberSaveable { mutableStateOf("") }
val updatePackage by selectedPackage.collectAsState()
val updatePackage by vm.selectedPackage.collectAsStateWithLifecycle()
LaunchedEffect(updatePackage) {
if(updatePackage != "") {
pkgName = updatePackage
selectedPackage.value = ""
vm.selectedPackage.value = ""
}
}
Scaffold(
@@ -145,9 +144,7 @@ fun ApplicationManage(navCtrl:NavHostController, dialogStatus: MutableIntState)
popEnterTransition = Animations.navHostPopEnterTransition,
popExitTransition = Animations.navHostPopExitTransition
) {
composable(route = "Home") {
Home(localNavCtrl, pkgName, dialogStatus)
}
composable(route = "Home") { Home(localNavCtrl, pkgName) }
composable(route = "UserControlDisabled") { UserCtrlDisabledPkg(pkgName) }
composable(route = "PermissionManage") { PermissionManage(pkgName) }
composable(route = "CrossProfilePackage") { CrossProfilePkg(pkgName) }
@@ -160,23 +157,11 @@ fun ApplicationManage(navCtrl:NavHostController, dialogStatus: MutableIntState)
composable(route = "UninstallApp") { UninstallApp(pkgName) }
}
}
when(dialogStatus.intValue) {
0 -> {}
1 -> EnableSystemAppDialog(dialogStatus, pkgName)
2 -> ClearAppDataDialog(dialogStatus, pkgName)
3 -> DefaultDialerAppDialog(dialogStatus, pkgName)
}
LaunchedEffect(dialogStatus.intValue) {
focusMgr.clearFocus()
}
}
@Composable
private fun Home(
navCtrl:NavHostController,
pkgName: String,
dialogStatus: MutableIntState
) {
private fun Home(navCtrl:NavHostController, pkgName: String) {
var dialogStatus by remember { mutableIntStateOf(0) }
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
@@ -190,7 +175,6 @@ private fun Home(
hide = dpm.isApplicationHidden(receiver, pkgName)
var blockUninstall by remember { mutableStateOf(false) }
blockUninstall = dpm.isUninstallBlocked(receiver,pkgName)
var appControlDialog by remember { mutableStateOf(false) }
var appControlAction by remember { mutableIntStateOf(0) }
val focusMgr = LocalFocusManager.current
val appControl: (Boolean) -> Unit = {
@@ -226,20 +210,20 @@ private fun Home(
title = R.string.suspend, desc = "", icon = R.drawable.block_fill0,
state = suspend,
onCheckedChange = { appControlAction = 1; appControl(it) },
onClickBlank = { appControlAction = 1; appControlDialog = true }
onClickBlank = { appControlAction = 1; dialogStatus = 4 }
)
}
SwitchItem(
title = R.string.hide, desc = stringResource(R.string.isapphidden_desc), icon = R.drawable.visibility_off_fill0,
state = hide,
onCheckedChange = { appControlAction = 2; appControl(it) },
onClickBlank = { appControlAction = 2; appControlDialog = true }
onClickBlank = { appControlAction = 2; dialogStatus = 4 }
)
SwitchItem(
title = R.string.block_uninstall, desc = "", icon = R.drawable.delete_forever_fill0,
state = blockUninstall,
onCheckedChange = { appControlAction = 3; appControl(it) },
onClickBlank = { appControlAction = 3; appControlDialog = true }
onClickBlank = { appControlAction = 3; dialogStatus = 4 }
)
if((VERSION.SDK_INT >= 33 && profileOwner) || (VERSION.SDK_INT >= 30 && deviceOwner)) {
FunctionItem(R.string.ucd, "", R.drawable.do_not_touch_fill0) { navCtrl.navigate("UserControlDisabled") }
@@ -259,32 +243,124 @@ private fun Home(
FunctionItem(R.string.permitted_accessibility_services, "", R.drawable.settings_accessibility_fill0) { navCtrl.navigate("Accessibility") }
FunctionItem(R.string.permitted_ime, "", R.drawable.keyboard_fill0) { navCtrl.navigate("IME") }
FunctionItem(R.string.enable_system_app, "", R.drawable.enable_fill0) {
if(pkgName != "") dialogStatus.intValue = 1
if(pkgName != "") dialogStatus = 1
}
if(VERSION.SDK_INT >= 28 && deviceOwner) {
FunctionItem(R.string.keep_uninstalled_packages, "", R.drawable.delete_fill0) { navCtrl.navigate("KeepUninstalled") }
}
if(VERSION.SDK_INT >= 28) {
FunctionItem(R.string.clear_app_storage, "", R.drawable.mop_fill0) {
if(pkgName != "") dialogStatus.intValue = 2
if(pkgName != "") dialogStatus = 2
}
}
FunctionItem(R.string.install_app, "", R.drawable.install_mobile_fill0) { navCtrl.navigate("InstallApp") }
FunctionItem(R.string.uninstall_app, "", R.drawable.delete_fill0) { navCtrl.navigate("UninstallApp") }
if(VERSION.SDK_INT >= 34 && (deviceOwner || dpm.isOrgProfile(receiver))) {
FunctionItem(R.string.set_default_dialer, "", R.drawable.call_fill0) {
if(pkgName != "") dialogStatus.intValue = 3
if(pkgName != "") dialogStatus = 3
}
}
Spacer(Modifier.padding(vertical = 30.dp))
LaunchedEffect(Unit) { fileUriFlow.value = Uri.parse("") }
}
if(appControlDialog) {
if(dialogStatus == 1) AlertDialog(
title = { Text(stringResource(R.string.enable_system_app)) },
text = {
Text(stringResource(R.string.enable_system_app_desc) + "\n" + pkgName)
},
onDismissRequest = { dialogStatus = 0 },
dismissButton = {
TextButton(onClick = { dialogStatus = 0 }) {
Text(stringResource(R.string.cancel))
}
},
confirmButton = {
TextButton(
onClick = {
try {
dpm.enableSystemApp(receiver, pkgName)
Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show()
} catch(_: IllegalArgumentException) {
Toast.makeText(context, R.string.failed, Toast.LENGTH_SHORT).show()
}
dialogStatus = 0
}
) {
Text(stringResource(R.string.confirm))
}
},
modifier = Modifier.fillMaxWidth()
)
if(dialogStatus == 2 && VERSION.SDK_INT >= 28) AlertDialog(
title = { Text(text = stringResource(R.string.clear_app_storage)) },
text = {
Text(stringResource(R.string.app_storage_will_be_cleared) + "\n" + pkgName)
},
confirmButton = {
TextButton(
onClick = {
val executor = Executors.newCachedThreadPool()
val onClear = DevicePolicyManager.OnClearApplicationUserDataListener { pkg: String, succeed: Boolean ->
Looper.prepare()
val toastText =
if(pkg!="") { "$pkg\n" }else{ "" } +
context.getString(R.string.clear_data) +
context.getString(if(succeed) R.string.success else R.string.failed )
Toast.makeText(context, toastText, Toast.LENGTH_SHORT).show()
Looper.loop()
}
dpm.clearApplicationUserData(receiver, pkgName, executor, onClear)
dialogStatus = 0
},
colors = ButtonDefaults.textButtonColors(contentColor = colorScheme.error)
) {
Text(text = stringResource(R.string.clear))
}
},
dismissButton = {
TextButton(
onClick = { dialogStatus = 0 }
) {
Text(text = stringResource(R.string.cancel))
}
},
onDismissRequest = { dialogStatus = 0 },
modifier = Modifier.fillMaxWidth()
)
if(dialogStatus == 3 && VERSION.SDK_INT >= 34) AlertDialog(
title = { Text(stringResource(R.string.set_default_dialer)) },
text = {
Text(stringResource(R.string.app_will_be_default_dialer) + "\n" + pkgName)
},
onDismissRequest = { dialogStatus = 0 },
dismissButton = {
TextButton(onClick = { dialogStatus = 0 }) {
Text(stringResource(R.string.cancel))
}
},
confirmButton = {
TextButton(
onClick = {
try{
dpm.setDefaultDialerApplication(pkgName)
Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show()
} catch(_: IllegalArgumentException) {
Toast.makeText(context, R.string.failed, Toast.LENGTH_SHORT).show()
}
dialogStatus = 0
}
) {
Text(stringResource(R.string.confirm))
}
},
modifier = Modifier.fillMaxWidth()
)
if(dialogStatus == 4) {
LaunchedEffect(Unit) {
focusMgr.clearFocus()
}
AlertDialog(
onDismissRequest = { appControlDialog = false },
onDismissRequest = { dialogStatus = 0 },
title = {
Text(
text = stringResource(
@@ -316,7 +392,7 @@ private fun Home(
TextButton(
onClick = {
appControl(true)
appControlDialog = false
dialogStatus = 0
}
) {
Text(text = stringResource(R.string.enable))
@@ -326,7 +402,7 @@ private fun Home(
TextButton(
onClick = {
appControl(false)
appControlDialog = false
dialogStatus = 0
}
) {
Text(text = stringResource(R.string.disable))
@@ -334,6 +410,7 @@ private fun Home(
}
)
}
LaunchedEffect(dialogStatus) { focusMgr.clearFocus() }
}
@@ -697,9 +774,7 @@ private fun PermittedAccessibility(pkgName: String) {
}
}
}
Information {
Text(stringResource(R.string.system_accessibility_always_allowed))
}
InfoCard(R.string.system_accessibility_always_allowed)
Spacer(Modifier.padding(vertical = 30.dp))
}
}
@@ -755,9 +830,7 @@ private fun PermittedIME(pkgName: String) {
}
}
}
Information {
Text(stringResource(R.string.system_ime_always_allowed))
}
InfoCard(R.string.system_ime_always_allowed)
Spacer(Modifier.padding(vertical = 30.dp))
}
}
@@ -892,117 +965,3 @@ private fun InstallApp() {
}
}
}
@SuppressLint("NewApi")
@Composable
private fun ClearAppDataDialog(status: MutableIntState, pkgName: String) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
AlertDialog(
title = { Text(text = stringResource(R.string.clear_app_storage)) },
text = {
Text(stringResource(R.string.app_storage_will_be_cleared) + "\n" + pkgName)
},
confirmButton = {
TextButton(
onClick = {
val executor = Executors.newCachedThreadPool()
val onClear = DevicePolicyManager.OnClearApplicationUserDataListener { pkg: String, succeed: Boolean ->
Looper.prepare()
val toastText =
if(pkg!="") { "$pkg\n" }else{ "" } +
context.getString(R.string.clear_data) +
context.getString(if(succeed) R.string.success else R.string.failed )
Toast.makeText(context, toastText, Toast.LENGTH_SHORT).show()
Looper.loop()
}
dpm.clearApplicationUserData(receiver, pkgName, executor, onClear)
status.intValue = 0
},
colors = ButtonDefaults.textButtonColors(contentColor = colorScheme.error)
) {
Text(text = stringResource(R.string.clear))
}
},
dismissButton = {
TextButton(
onClick = { status.intValue = 0 }
) {
Text(text = stringResource(R.string.cancel))
}
},
onDismissRequest = { status.intValue = 0 },
modifier = Modifier.fillMaxWidth()
)
}
@SuppressLint("NewApi")
@Composable
private fun DefaultDialerAppDialog(status: MutableIntState, pkgName: String) {
val context = LocalContext.current
val dpm = context.getDPM()
AlertDialog(
title = { Text(stringResource(R.string.set_default_dialer)) },
text = {
Text(stringResource(R.string.app_will_be_default_dialer) + "\n" + pkgName)
},
onDismissRequest = { status.intValue = 0 },
dismissButton = {
TextButton(onClick = { status.intValue = 0 }) {
Text(stringResource(R.string.cancel))
}
},
confirmButton = {
TextButton(
onClick = {
try{
dpm.setDefaultDialerApplication(pkgName)
Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show()
}catch(_: IllegalArgumentException) {
Toast.makeText(context, R.string.failed, Toast.LENGTH_SHORT).show()
}
status.intValue = 0
}
) {
Text(stringResource(R.string.confirm))
}
},
modifier = Modifier.fillMaxWidth()
)
}
@Composable
private fun EnableSystemAppDialog(status: MutableIntState, pkgName: String) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
AlertDialog(
title = { Text(stringResource(R.string.enable_system_app)) },
text = {
Text(stringResource(R.string.enable_system_app_desc) + "\n" + pkgName)
},
onDismissRequest = { status.intValue = 0 },
dismissButton = {
TextButton(onClick = { status.intValue = 0 }) {
Text(stringResource(R.string.cancel))
}
},
confirmButton = {
TextButton(
onClick = {
try {
dpm.enableSystemApp(receiver, pkgName)
Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show()
} catch(_: IllegalArgumentException) {
Toast.makeText(context, R.string.failed, Toast.LENGTH_SHORT).show()
}
status.intValue = 0
}
) {
Text(stringResource(R.string.confirm))
}
},
modifier = Modifier.fillMaxWidth()
)
}