mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-23 11:05:59 +00:00
Fix Managed configurations bugs, add search bar (#198)
This commit is contained in:
@@ -602,7 +602,7 @@ fun Home(vm: MyViewModel, onLock: () -> Unit) {
|
||||
}
|
||||
composable<ManagedConfiguration> {
|
||||
ManagedConfigurationScreen(
|
||||
it.toRoute(), vm.appRestrictions, vm::getAppRestrictions, vm::setAppRestrictions,
|
||||
it.toRoute(), vm.appRestrictions, vm::setAppRestrictions,
|
||||
vm::clearAppRestrictions, ::navigateUp
|
||||
)
|
||||
}
|
||||
|
||||
@@ -518,12 +518,11 @@ class MyViewModel(application: Application): AndroidViewModel(application) {
|
||||
|
||||
@RequiresApi(23)
|
||||
fun getAppRestrictions(name: String) {
|
||||
val rm = application.getSystemService(Context.RESTRICTIONS_SERVICE) as RestrictionsManager
|
||||
val rm = application.getSystemService(RestrictionsManager::class.java)
|
||||
val bundle = DPM.getApplicationRestrictions(DAR, name)
|
||||
println(bundle.keySet())
|
||||
appRestrictions.value = rm.getManifestRestrictions(name).mapNotNull {
|
||||
appRestrictions.value = rm.getManifestRestrictions(name)?.mapNotNull {
|
||||
transformRestrictionEntry(it)
|
||||
}.map {
|
||||
}?.map {
|
||||
if (bundle.containsKey(it.key)) {
|
||||
when (it) {
|
||||
is AppRestriction.BooleanItem -> it.value = bundle.getBoolean(it.key)
|
||||
@@ -534,17 +533,16 @@ class MyViewModel(application: Application): AndroidViewModel(application) {
|
||||
}
|
||||
}
|
||||
it
|
||||
}
|
||||
} ?: emptyList()
|
||||
}
|
||||
|
||||
@RequiresApi(23)
|
||||
fun setAppRestrictions(name: String, item: AppRestriction) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
appRestrictions.value = emptyList()
|
||||
DPM.setApplicationRestrictions(
|
||||
DAR, name,
|
||||
transformAppRestriction(appRestrictions.value.filter { it.key != item.key }.plus(item))
|
||||
val bundle = transformAppRestriction(
|
||||
appRestrictions.value.filter { it.key != item.key }.plus(item)
|
||||
)
|
||||
DPM.setApplicationRestrictions(DAR, name, bundle)
|
||||
getAppRestrictions(name)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.icons.automirrored.filled.List
|
||||
import androidx.compose.material.icons.outlined.Clear
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
@@ -122,15 +123,12 @@ fun AppChooserScreen(
|
||||
keyboardActions = KeyboardActions { focusMgr.clearFocus() },
|
||||
placeholder = { Text(stringResource(R.string.search)) },
|
||||
trailingIcon = {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.close_fill0),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.clickable {
|
||||
focusMgr.clearFocus()
|
||||
IconButton({
|
||||
query = ""
|
||||
searchMode = false
|
||||
}) {
|
||||
Icon(Icons.Outlined.Clear, null)
|
||||
}
|
||||
)
|
||||
},
|
||||
textStyle = typography.bodyLarge,
|
||||
modifier = Modifier.fillMaxWidth().focusRequester(fr)
|
||||
|
||||
@@ -40,7 +40,9 @@ import androidx.compose.material.icons.filled.Check
|
||||
import androidx.compose.material.icons.filled.Clear
|
||||
import androidx.compose.material.icons.filled.MoreVert
|
||||
import androidx.compose.material.icons.outlined.CheckCircle
|
||||
import androidx.compose.material.icons.outlined.Clear
|
||||
import androidx.compose.material.icons.outlined.Delete
|
||||
import androidx.compose.material.icons.outlined.Search
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.AlertDialogDefaults
|
||||
import androidx.compose.material3.Button
|
||||
@@ -79,6 +81,8 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
@@ -258,7 +262,11 @@ fun ApplicationDetailsScreen(
|
||||
var dialog by rememberSaveable { mutableIntStateOf(0) } // 1: clear storage, 2: uninstall
|
||||
val info = vm.getAppInfo(packageName)
|
||||
val status by vm.appStatus.collectAsStateWithLifecycle()
|
||||
LaunchedEffect(Unit) { vm.getAppStatus(packageName) }
|
||||
val appRestrictions by vm.appRestrictions.collectAsStateWithLifecycle()
|
||||
LaunchedEffect(Unit) {
|
||||
vm.getAppStatus(packageName)
|
||||
vm.getAppRestrictions(packageName)
|
||||
}
|
||||
MySmallTitleScaffold(R.string.place_holder, onNavigateUp, 0.dp) {
|
||||
Column(Modifier.align(Alignment.CenterHorizontally).padding(top = 16.dp), horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Image(rememberDrawablePainter(info.icon), null, Modifier.size(50.dp))
|
||||
@@ -295,7 +303,7 @@ fun ApplicationDetailsScreen(
|
||||
state = status.keepUninstalled,
|
||||
onCheckedChange = { vm.adSetPackageKu(packageName, it) }
|
||||
)
|
||||
if (VERSION.SDK_INT >= 23) {
|
||||
if (VERSION.SDK_INT >= 23 && appRestrictions.isNotEmpty()) {
|
||||
FunctionItem(R.string.managed_configuration, icon = R.drawable.description_fill0) {
|
||||
onNavigate(ManagedConfiguration(packageName))
|
||||
}
|
||||
@@ -1003,35 +1011,74 @@ fun EditAppGroupScreen(
|
||||
@Composable
|
||||
fun ManagedConfigurationScreen(
|
||||
params: ManagedConfiguration, appRestrictions: StateFlow<List<AppRestriction>>,
|
||||
getRestriction: (String) -> Unit, setRestriction: (String, AppRestriction) -> Unit,
|
||||
clearRestriction: (String) -> Unit, navigateUp: () -> Unit
|
||||
setRestriction: (String, AppRestriction) -> Unit, clearRestriction: (String) -> Unit,
|
||||
navigateUp: () -> Unit
|
||||
) {
|
||||
val restrictions by appRestrictions.collectAsStateWithLifecycle()
|
||||
var dialog by remember { mutableIntStateOf(-1) }
|
||||
var clearRestrictionDialog by remember { mutableStateOf(false) }
|
||||
LaunchedEffect(Unit) {
|
||||
getRestriction(params.packageName)
|
||||
var searchMode by remember { mutableStateOf(false) }
|
||||
var searchKeyword by remember { mutableStateOf("") }
|
||||
val displayRestrictions = if (searchKeyword.isEmpty()) {
|
||||
restrictions
|
||||
} else {
|
||||
restrictions.filter {
|
||||
it.key.contentEquals(searchKeyword, true) ||
|
||||
it.title?.contains(searchKeyword, true) ?: true
|
||||
}
|
||||
}
|
||||
var dialog by remember { mutableStateOf<AppRestriction?>(null) }
|
||||
var clearRestrictionDialog by remember { mutableStateOf(false) }
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
{ Text(stringResource(R.string.managed_configuration)) },
|
||||
{
|
||||
if (searchMode) {
|
||||
val fr = remember { FocusRequester() }
|
||||
LaunchedEffect(Unit) {
|
||||
fr.requestFocus()
|
||||
}
|
||||
OutlinedTextField(
|
||||
searchKeyword, { searchKeyword = it },
|
||||
Modifier.fillMaxWidth().focusRequester(fr),
|
||||
textStyle = typography.bodyLarge,
|
||||
placeholder = { Text(stringResource(R.string.search)) },
|
||||
trailingIcon = {
|
||||
IconButton({
|
||||
searchKeyword = ""
|
||||
searchMode = false
|
||||
}) {
|
||||
Icon(Icons.Outlined.Clear, null)
|
||||
}
|
||||
},
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done)
|
||||
)
|
||||
} else {
|
||||
Text(stringResource(R.string.managed_configuration))
|
||||
}
|
||||
},
|
||||
navigationIcon = { NavIcon(navigateUp) },
|
||||
actions = {
|
||||
if (!searchMode) {
|
||||
IconButton({
|
||||
searchMode = true
|
||||
}) {
|
||||
Icon(Icons.Outlined.Search, null)
|
||||
}
|
||||
IconButton({
|
||||
clearRestrictionDialog = true
|
||||
}) {
|
||||
Icon(Icons.Outlined.Delete, null)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
},
|
||||
contentWindowInsets = adaptiveInsets()
|
||||
) { paddingValues ->
|
||||
LazyColumn(Modifier.padding(paddingValues)) {
|
||||
itemsIndexed(restrictions) { index, entry ->
|
||||
items(displayRestrictions, { it.key }) { entry ->
|
||||
Row(
|
||||
Modifier.fillMaxWidth().clickable {
|
||||
dialog = index
|
||||
dialog = entry
|
||||
}.padding(HorizontalPadding, 8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
@@ -1055,7 +1102,13 @@ fun ManagedConfigurationScreen(
|
||||
is AppRestriction.StringItem -> entry.value?.take(30)
|
||||
is AppRestriction.BooleanItem -> entry.value?.toString()
|
||||
is AppRestriction.ChoiceItem -> entry.value
|
||||
is AppRestriction.MultiSelectItem -> entry.value?.joinToString(limit = 30)
|
||||
is AppRestriction.MultiSelectItem -> {
|
||||
if (entry.value != null) {
|
||||
entry.entryValues
|
||||
.filter { entry.value?.contains(it) ?: false }
|
||||
.joinToString(limit = 30)
|
||||
} else null
|
||||
}
|
||||
}
|
||||
Text(
|
||||
text ?: "null", Modifier.alpha(0.7F),
|
||||
@@ -1070,8 +1123,8 @@ fun ManagedConfigurationScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dialog != -1) Dialog({
|
||||
dialog = -1
|
||||
if (dialog != null) Dialog({
|
||||
dialog = null
|
||||
}) {
|
||||
Surface(
|
||||
color = AlertDialogDefaults.containerColor,
|
||||
@@ -1079,11 +1132,11 @@ fun ManagedConfigurationScreen(
|
||||
tonalElevation = AlertDialogDefaults.TonalElevation,
|
||||
) {
|
||||
Column(Modifier.verticalScroll(rememberScrollState()).padding(12.dp)) {
|
||||
ManagedConfigurationDialog(restrictions[dialog]) {
|
||||
ManagedConfigurationDialog(dialog!!) {
|
||||
if (it != null) {
|
||||
setRestriction(params.packageName, it)
|
||||
}
|
||||
dialog = -1
|
||||
dialog = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user