improve UI design

fix padding of SwitchItem and SubPageItem
application manager: move package name textfield to topbar
This commit is contained in:
BinTianqi
2024-08-13 14:28:24 +08:00
parent 439a75bb84
commit 3d000358c4
12 changed files with 196 additions and 240 deletions

View File

@@ -158,6 +158,7 @@ fun PackageSelector(navCtrl: NavHostController) {
} }
) )
}, },
textStyle = typography.bodyLarge,
modifier = Modifier.fillMaxWidth().focusRequester(fr) modifier = Modifier.fillMaxWidth().focusRequester(fr)
) )
} else { } else {
@@ -217,14 +218,12 @@ private fun PackageItem(pkg: PkgInfo, navCtrl: NavHostController) {
selectedPackage.value = pkg.pkgName selectedPackage.value = pkg.pkgName
navCtrl.navigateUp() navCtrl.navigateUp()
} }
.padding(vertical = 6.dp) .padding(horizontal = 8.dp, vertical = 10.dp)
) { ) {
Spacer(Modifier.padding(start = 15.dp))
Image( Image(
painter = rememberDrawablePainter(pkg.icon), contentDescription = "App icon", painter = rememberDrawablePainter(pkg.icon), contentDescription = "App icon",
modifier = Modifier.size(50.dp) modifier = Modifier.padding(start = 12.dp, end = 18.dp).size(40.dp)
) )
Spacer(Modifier.padding(start = 15.dp))
Column { Column {
Text(text = pkg.label, style = typography.titleLarge) Text(text = pkg.label, style = typography.titleLarge)
Text(text = pkg.pkgName, modifier = Modifier.alpha(0.8F)) Text(text = pkg.pkgName, modifier = Modifier.alpha(0.8F))

View File

@@ -55,7 +55,7 @@ fun AppSetting(navCtrl:NavHostController, materialYou: MutableState<Boolean>, bl
@Composable @Composable
private fun Home(navCtrl: NavHostController) { private fun Home(navCtrl: NavHostController) {
Column(modifier = Modifier.fillMaxSize().padding(start = 30.dp, end = 12.dp)) { Column(modifier = Modifier.fillMaxSize()) {
SubPageItem(R.string.options, "", R.drawable.tune_fill0) { navCtrl.navigate("Options") } SubPageItem(R.string.options, "", R.drawable.tune_fill0) { navCtrl.navigate("Options") }
SubPageItem(R.string.theme, "", R.drawable.format_paint_fill0) { navCtrl.navigate("Theme") } SubPageItem(R.string.theme, "", R.drawable.format_paint_fill0) { navCtrl.navigate("Theme") }
SubPageItem(R.string.security, "", R.drawable.lock_fill0) { navCtrl.navigate("Auth") } SubPageItem(R.string.security, "", R.drawable.lock_fill0) { navCtrl.navigate("Auth") }
@@ -67,7 +67,7 @@ private fun Home(navCtrl: NavHostController) {
@Composable @Composable
private fun Options() { private fun Options() {
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE) val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(start = 20.dp, end = 12.dp)) { Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
SwitchItem( SwitchItem(
R.string.show_dangerous_features, "", R.drawable.warning_fill0, R.string.show_dangerous_features, "", R.drawable.warning_fill0,
{ sharedPref.getBoolean("dangerous_features", false) }, { sharedPref.getBoolean("dangerous_features", false) },
@@ -79,7 +79,7 @@ private fun Options() {
@Composable @Composable
private fun ThemeSettings(materialYou:MutableState<Boolean>, blackTheme:MutableState<Boolean>) { private fun ThemeSettings(materialYou:MutableState<Boolean>, blackTheme:MutableState<Boolean>) {
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE) val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(start = 20.dp, end = 12.dp)) { Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
if(VERSION.SDK_INT>=31) { if(VERSION.SDK_INT>=31) {
SwitchItem( SwitchItem(
R.string.material_you_color, stringResource(R.string.dynamic_color_desc), null, R.string.material_you_color, stringResource(R.string.dynamic_color_desc), null,
@@ -107,7 +107,7 @@ private fun ThemeSettings(materialYou:MutableState<Boolean>, blackTheme:MutableS
private fun AuthSettings() { private fun AuthSettings() {
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE) val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
var auth by remember{ mutableStateOf(sharedPref.getBoolean("auth",false)) } var auth by remember{ mutableStateOf(sharedPref.getBoolean("auth",false)) }
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(start = 20.dp, end = 12.dp)) { Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
SwitchItem( SwitchItem(
R.string.lock_owndroid, "", null, R.string.lock_owndroid, "", null,
{ auth }, { auth },
@@ -133,11 +133,6 @@ private fun AuthSettings() {
{ sharedPref.getBoolean("protect_storage", false) }, { sharedPref.getBoolean("protect_storage", false) },
{ sharedPref.edit().putBoolean("protect_storage", it).apply() } { sharedPref.edit().putBoolean("protect_storage", it).apply() }
) )
Box(modifier = Modifier.offset(x = (-8).dp)) {
Information {
Text(text = stringResource(R.string.auth_on_start))
}
}
} }
} }
@@ -166,7 +161,8 @@ private fun Automation() {
SwitchItem( SwitchItem(
R.string.automation_debug, "", null, R.string.automation_debug, "", null,
{ sharedPref.getBoolean("automation_debug", false) }, { sharedPref.getBoolean("automation_debug", false) },
{ sharedPref.edit().putBoolean("automation_debug", it).apply() } { sharedPref.edit().putBoolean("automation_debug", it).apply() },
padding = false
) )
} }
} }
@@ -177,17 +173,14 @@ private fun About() {
val pkgInfo = context.packageManager.getPackageInfo(context.packageName,0) val pkgInfo = context.packageManager.getPackageInfo(context.packageName,0)
val verCode = pkgInfo.versionCode val verCode = pkgInfo.versionCode
val verName = pkgInfo.versionName val verName = pkgInfo.versionName
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) { Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
Spacer(Modifier.padding(vertical = 10.dp)) Spacer(Modifier.padding(vertical = 10.dp))
Text(text = stringResource(R.string.about), style = typography.headlineLarge) Text(text = stringResource(R.string.about), style = typography.headlineLarge, modifier = Modifier.padding(start = 26.dp))
Spacer(Modifier.padding(vertical = 5.dp)) Spacer(Modifier.padding(vertical = 5.dp))
Text(text = stringResource(R.string.app_name)+" v$verName ($verCode)") Text(text = stringResource(R.string.app_name)+" v$verName ($verCode)", modifier = Modifier.padding(start = 26.dp))
Text(text = stringResource(R.string.about_desc))
Spacer(Modifier.padding(vertical = 5.dp)) Spacer(Modifier.padding(vertical = 5.dp))
Column(modifier = Modifier.padding(start = 16.dp)) { SubPageItem(R.string.user_guide, "", R.drawable.open_in_new) { shareLink(context, "https://owndroid.pages.dev") }
SubPageItem(R.string.user_guide, "", R.drawable.open_in_new) { shareLink(context, "https://owndroid.pages.dev") } SubPageItem(R.string.source_code, "", R.drawable.open_in_new) { shareLink(context, "https://github.com/BinTianqi/OwnDroid") }
SubPageItem(R.string.source_code, "", R.drawable.open_in_new) { shareLink(context, "https://github.com/BinTianqi/OwnDroid") }
}
} }
} }

View File

@@ -10,6 +10,7 @@ import android.app.admin.PackagePolicy
import android.app.admin.PackagePolicy.PACKAGE_POLICY_ALLOWLIST import android.app.admin.PackagePolicy.PACKAGE_POLICY_ALLOWLIST
import android.app.admin.PackagePolicy.PACKAGE_POLICY_ALLOWLIST_AND_SYSTEM import android.app.admin.PackagePolicy.PACKAGE_POLICY_ALLOWLIST_AND_SYSTEM
import android.app.admin.PackagePolicy.PACKAGE_POLICY_BLOCKLIST import android.app.admin.PackagePolicy.PACKAGE_POLICY_BLOCKLIST
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager.NameNotFoundException import android.content.pm.PackageManager.NameNotFoundException
import android.net.Uri import android.net.Uri
@@ -38,7 +39,7 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.AlertDialog import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Card import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme.colorScheme import androidx.compose.material3.MaterialTheme.colorScheme
import androidx.compose.material3.MaterialTheme.typography import androidx.compose.material3.MaterialTheme.typography
@@ -47,10 +48,10 @@ import androidx.compose.material3.Switch
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
import androidx.compose.material3.TextField import androidx.compose.material3.TextField
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableIntState import androidx.compose.runtime.MutableIntState
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableIntStateOf
@@ -58,6 +59,7 @@ import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateMapOf import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@@ -72,12 +74,10 @@ import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.core.content.ContextCompat.startActivity import androidx.core.content.ContextCompat.startActivity
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import com.bintianqi.owndroid.InstallAppActivity import com.bintianqi.owndroid.InstallAppActivity
import com.bintianqi.owndroid.PackageInstallerReceiver import com.bintianqi.owndroid.PackageInstallerReceiver
@@ -88,22 +88,22 @@ import com.bintianqi.owndroid.selectedPackage
import com.bintianqi.owndroid.toText import com.bintianqi.owndroid.toText
import com.bintianqi.owndroid.ui.Animations import com.bintianqi.owndroid.ui.Animations
import com.bintianqi.owndroid.ui.Information import com.bintianqi.owndroid.ui.Information
import com.bintianqi.owndroid.ui.NavIcon
import com.bintianqi.owndroid.ui.RadioButtonItem import com.bintianqi.owndroid.ui.RadioButtonItem
import com.bintianqi.owndroid.ui.SubPageItem import com.bintianqi.owndroid.ui.SubPageItem
import com.bintianqi.owndroid.ui.SwitchItem import com.bintianqi.owndroid.ui.SwitchItem
import com.bintianqi.owndroid.ui.TopBar
import java.util.concurrent.Executors import java.util.concurrent.Executors
private var dialogConfirmButtonAction = {} private var dialogConfirmButtonAction = {}
private var dialogDismissButtonAction = {} private var dialogDismissButtonAction = {}
private var dialogGetStatus = { false } private var dialogGetStatus = { false }
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun ApplicationManage(navCtrl:NavHostController, dialogStatus: MutableIntState) { fun ApplicationManage(navCtrl:NavHostController, dialogStatus: MutableIntState) {
val focusMgr = LocalFocusManager.current val focusMgr = LocalFocusManager.current
val localNavCtrl = rememberNavController() val localNavCtrl = rememberNavController()
val backStackEntry by localNavCtrl.currentBackStackEntryAsState() var pkgName by rememberSaveable { mutableStateOf("") }
var pkgName by remember { mutableStateOf("") }
val updatePackage by selectedPackage.collectAsState() val updatePackage by selectedPackage.collectAsState()
LaunchedEffect(updatePackage) { LaunchedEffect(updatePackage) {
if(updatePackage != "") { if(updatePackage != "") {
@@ -111,91 +111,68 @@ fun ApplicationManage(navCtrl:NavHostController, dialogStatus: MutableIntState)
selectedPackage.value = "" selectedPackage.value = ""
} }
} }
val titleMap = mapOf(
"BlockUninstall" to R.string.block_uninstall,
"UserControlDisabled" to R.string.ucd,
"PermissionManage" to R.string.permission_manage,
"CrossProfilePackage" to R.string.cross_profile_package,
"CrossProfileWidget" to R.string.cross_profile_widget,
"CredentialManagePolicy" to R.string.credential_manage_policy,
"Accessibility" to R.string.permitted_accessibility_services,
"IME" to R.string.permitted_ime,
"KeepUninstalled" to R.string.keep_uninstalled_packages,
"InstallApp" to R.string.install_app,
"UninstallApp" to R.string.uninstall_app,
"ClearAppData" to R.string.clear_app_storage,
"DefaultDialer" to R.string.set_default_dialer,
)
val clearAppDataDialog = remember { mutableStateOf(false) }
val defaultDialerAppDialog = remember { mutableStateOf(false) }
val enableSystemAppDialog = remember { mutableStateOf(false) }
Scaffold( Scaffold(
topBar = { topBar = {
TopBar(backStackEntry, navCtrl, localNavCtrl) { TopAppBar(
Text(text = stringResource(titleMap[backStackEntry?.destination?.route] ?: R.string.app_manager)) title = {
} TextField(
value = pkgName,
onValueChange = { pkgName = it },
label = { Text(stringResource(R.string.package_name)) },
modifier = Modifier.fillMaxWidth(),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Ascii, imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
trailingIcon = {
Icon(painter = painterResource(R.drawable.checklist_fill0), contentDescription = null,
modifier = Modifier
.clip(RoundedCornerShape(50))
.clickable(onClick = {
focusMgr.clearFocus()
navCtrl.navigate("PackageSelector")
})
.padding(3.dp))
},
textStyle = typography.bodyLarge,
singleLine = true
)
},
navigationIcon = { NavIcon { navCtrl.navigateUp() } }
)
} }
) { paddingValues-> ) { paddingValues->
Column( NavHost(
modifier = Modifier.fillMaxSize().padding(top = paddingValues.calculateTopPadding()) modifier = Modifier.padding(top = paddingValues.calculateTopPadding()),
navController = localNavCtrl, startDestination = "Home",
enterTransition = Animations.navHostEnterTransition,
exitTransition = Animations.navHostExitTransition,
popEnterTransition = Animations.navHostPopEnterTransition,
popExitTransition = Animations.navHostPopExitTransition
) { ) {
if(backStackEntry?.destination?.route!="InstallApp") { composable(route = "Home") {
TextField( Home(localNavCtrl, pkgName, dialogStatus)
value = pkgName,
onValueChange = { pkgName = it },
label = { Text(stringResource(R.string.package_name)) },
modifier = Modifier.fillMaxWidth(),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Ascii, imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
trailingIcon = {
Icon(painter = painterResource(R.drawable.checklist_fill0), contentDescription = null,
modifier = Modifier
.clip(RoundedCornerShape(50))
.clickable(onClick = {
focusMgr.clearFocus()
navCtrl.navigate("PackageSelector")
})
.padding(3.dp))
},
singleLine = true
)
}
NavHost(
navController = localNavCtrl, startDestination = "Home",
enterTransition = Animations.navHostEnterTransition,
exitTransition = Animations.navHostExitTransition,
popEnterTransition = Animations.navHostPopEnterTransition,
popExitTransition = Animations.navHostPopExitTransition
) {
composable(route = "Home") {
Home(localNavCtrl, pkgName, dialogStatus, clearAppDataDialog, defaultDialerAppDialog, enableSystemAppDialog)
}
composable(route = "AlwaysOnVpn") { AlwaysOnVPNPackage(pkgName) }
composable(route = "UserControlDisabled") { UserCtrlDisabledPkg(pkgName) }
composable(route = "PermissionManage") { PermissionManage(pkgName) }
composable(route = "CrossProfilePackage") { CrossProfilePkg(pkgName) }
composable(route = "CrossProfileWidget") { CrossProfileWidget(pkgName) }
composable(route = "CredentialManagePolicy") { CredentialManagePolicy(pkgName) }
composable(route = "Accessibility") { PermittedAccessibility(pkgName) }
composable(route = "IME") { PermittedIME(pkgName) }
composable(route = "KeepUninstalled") { KeepUninstalledApp(pkgName) }
composable(route = "InstallApp") { InstallApp() }
composable(route = "UninstallApp") { UninstallApp(pkgName) }
} }
composable(route = "AlwaysOnVpn") { AlwaysOnVPNPackage(pkgName) }
composable(route = "UserControlDisabled") { UserCtrlDisabledPkg(pkgName) }
composable(route = "PermissionManage") { PermissionManage(pkgName) }
composable(route = "CrossProfilePackage") { CrossProfilePkg(pkgName) }
composable(route = "CrossProfileWidget") { CrossProfileWidget(pkgName) }
composable(route = "CredentialManagePolicy") { CredentialManagePolicy(pkgName) }
composable(route = "Accessibility") { PermittedAccessibility(pkgName) }
composable(route = "IME") { PermittedIME(pkgName) }
composable(route = "KeepUninstalled") { KeepUninstalledApp(pkgName) }
composable(route = "InstallApp") { InstallApp() }
composable(route = "UninstallApp") { UninstallApp(pkgName) }
} }
} }
if(dialogStatus.intValue!=0) { when(dialogStatus.intValue) {
LocalFocusManager.current.clearFocus() 0 -> {}
AppControlDialog(dialogStatus) 4 -> EnableSystemAppDialog(dialogStatus, pkgName)
5 -> ClearAppDataDialog(dialogStatus, pkgName)
6 -> DefaultDialerAppDialog(dialogStatus, pkgName)
else -> AppControlDialog(dialogStatus)
} }
if(clearAppDataDialog.value) { LaunchedEffect(dialogStatus.intValue) {
ClearAppDataDialog(clearAppDataDialog, pkgName) focusMgr.clearFocus()
}
if(defaultDialerAppDialog.value) {
DefaultDialerAppDialog(defaultDialerAppDialog, pkgName)
}
if(enableSystemAppDialog.value) {
EnableSystemAppDialog(enableSystemAppDialog, pkgName)
} }
} }
@@ -203,18 +180,16 @@ fun ApplicationManage(navCtrl:NavHostController, dialogStatus: MutableIntState)
private fun Home( private fun Home(
navCtrl:NavHostController, navCtrl:NavHostController,
pkgName: String, pkgName: String,
dialogStatus: MutableIntState, dialogStatus: MutableIntState
clearAppDataDialog: MutableState<Boolean>,
defaultDialerAppDialog: MutableState<Boolean>,
enableSystemAppDialog: MutableState<Boolean>
) { ) {
val context = LocalContext.current val context = LocalContext.current
val dpm = context.getDPM() val dpm = context.getDPM()
val receiver = context.getReceiver() val receiver = context.getReceiver()
val sharedPrefs = context.getSharedPreferences("data", Context.MODE_PRIVATE)
val deviceOwner = context.isDeviceOwner val deviceOwner = context.isDeviceOwner
val profileOwner = context.isProfileOwner val profileOwner = context.isProfileOwner
Column( Column(
modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(start = 30.dp, end = 12.dp) modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())
) { ) {
Spacer(Modifier.padding(vertical = 5.dp)) Spacer(Modifier.padding(vertical = 5.dp))
if(VERSION.SDK_INT >= 24 && profileOwner && dpm.isManagedProfile(receiver)) { if(VERSION.SDK_INT >= 24 && profileOwner && dpm.isManagedProfile(receiver)) {
@@ -225,7 +200,7 @@ private fun Home(
intent.setData(Uri.parse("package:$pkgName")) intent.setData(Uri.parse("package:$pkgName"))
startActivity(context, intent, null) startActivity(context, intent, null)
} }
if(VERSION.SDK_INT>=24 && (deviceOwner || profileOwner)) { if(VERSION.SDK_INT >= 24 && (deviceOwner || profileOwner)) {
val getSuspendStatus = { val getSuspendStatus = {
try{ dpm.isPackageSuspended(receiver, pkgName) } try{ dpm.isPackageSuspended(receiver, pkgName) }
catch(e:NameNotFoundException) { false } catch(e:NameNotFoundException) { false }
@@ -278,36 +253,42 @@ private fun Home(
if(VERSION.SDK_INT>=23&&(deviceOwner||profileOwner)) { if(VERSION.SDK_INT>=23&&(deviceOwner||profileOwner)) {
SubPageItem(R.string.permission_manage, "", R.drawable.key_fill0) { navCtrl.navigate("PermissionManage") } SubPageItem(R.string.permission_manage, "", R.drawable.key_fill0) { navCtrl.navigate("PermissionManage") }
} }
if(VERSION.SDK_INT>=30&&profileOwner&&dpm.isManagedProfile(receiver)) { if(VERSION.SDK_INT >= 30 && profileOwner && dpm.isManagedProfile(receiver)) {
SubPageItem(R.string.cross_profile_package, "", R.drawable.work_fill0) { navCtrl.navigate("CrossProfilePackage") } SubPageItem(R.string.cross_profile_package, "", R.drawable.work_fill0) { navCtrl.navigate("CrossProfilePackage") }
} }
if(profileOwner) { if(profileOwner) {
SubPageItem(R.string.cross_profile_widget, "", R.drawable.widgets_fill0) { navCtrl.navigate("CrossProfileWidget") } SubPageItem(R.string.cross_profile_widget, "", R.drawable.widgets_fill0) { navCtrl.navigate("CrossProfileWidget") }
} }
if(VERSION.SDK_INT>=34&&deviceOwner) { if(VERSION.SDK_INT >= 34 && deviceOwner) {
SubPageItem(R.string.credential_manage_policy, "", R.drawable.license_fill0) { navCtrl.navigate("CredentialManagePolicy") } SubPageItem(R.string.credential_manage_policy, "", R.drawable.license_fill0) { navCtrl.navigate("CredentialManagePolicy") }
} }
if(profileOwner||deviceOwner) { if(profileOwner || deviceOwner) {
SubPageItem(R.string.permitted_accessibility_services, "", R.drawable.settings_accessibility_fill0) { navCtrl.navigate("Accessibility") } SubPageItem(R.string.permitted_accessibility_services, "", R.drawable.settings_accessibility_fill0) { navCtrl.navigate("Accessibility") }
} }
if(deviceOwner||profileOwner) { if(deviceOwner || profileOwner) {
SubPageItem(R.string.permitted_ime, "", R.drawable.keyboard_fill0) { navCtrl.navigate("IME") } SubPageItem(R.string.permitted_ime, "", R.drawable.keyboard_fill0) { navCtrl.navigate("IME") }
} }
if(deviceOwner || profileOwner) { if(deviceOwner || profileOwner) {
SubPageItem(R.string.enable_system_app, "", R.drawable.enable_fill0) { enableSystemAppDialog.value = true } SubPageItem(R.string.enable_system_app, "", R.drawable.enable_fill0) {
} if(pkgName != "") dialogStatus.intValue = 4
if(VERSION.SDK_INT>=28&&deviceOwner) {
SubPageItem(R.string.keep_uninstalled_packages, "", R.drawable.delete_fill0) { navCtrl.navigate("KeepUninstalled") }
}
if(VERSION.SDK_INT>=28 && (deviceOwner || profileOwner)) {
SubPageItem(R.string.clear_app_storage, "", R.drawable.mop_fill0) {
if(pkgName != "") { clearAppDataDialog.value = true }
} }
} }
SubPageItem(R.string.install_app, "", R.drawable.install_mobile_fill0) { navCtrl.navigate("InstallApp") } if(VERSION.SDK_INT >= 28 && deviceOwner) {
SubPageItem(R.string.keep_uninstalled_packages, "", R.drawable.delete_fill0) { navCtrl.navigate("KeepUninstalled") }
}
if(VERSION.SDK_INT >= 28 && (deviceOwner || profileOwner)) {
SubPageItem(R.string.clear_app_storage, "", R.drawable.mop_fill0) {
if(pkgName != "") dialogStatus.intValue = 5
}
}
if(!sharedPrefs.getBoolean("dhizuku", false)) {
SubPageItem(R.string.install_app, "", R.drawable.install_mobile_fill0) { navCtrl.navigate("InstallApp") }
}
SubPageItem(R.string.uninstall_app, "", R.drawable.delete_fill0) { navCtrl.navigate("UninstallApp") } SubPageItem(R.string.uninstall_app, "", R.drawable.delete_fill0) { navCtrl.navigate("UninstallApp") }
if(VERSION.SDK_INT >= 34 && (deviceOwner || dpm.isOrgProfile(receiver))) { if(VERSION.SDK_INT >= 34 && (deviceOwner || dpm.isOrgProfile(receiver))) {
SubPageItem(R.string.set_default_dialer, "", R.drawable.call_fill0) { defaultDialerAppDialog.value = true } SubPageItem(R.string.set_default_dialer, "", R.drawable.call_fill0) {
if(pkgName != "") dialogStatus.intValue = 6
}
} }
Spacer(Modifier.padding(vertical = 30.dp)) Spacer(Modifier.padding(vertical = 30.dp))
LaunchedEffect(Unit) { fileUriFlow.value = Uri.parse("") } LaunchedEffect(Unit) { fileUriFlow.value = Uri.parse("") }
@@ -338,7 +319,7 @@ fun AlwaysOnVPNPackage(pkgName: String) {
Spacer(Modifier.padding(vertical = 10.dp)) Spacer(Modifier.padding(vertical = 10.dp))
Text(text = stringResource(R.string.always_on_vpn), style = typography.headlineLarge, modifier = Modifier.padding(vertical = 8.dp)) Text(text = stringResource(R.string.always_on_vpn), style = typography.headlineLarge, modifier = Modifier.padding(vertical = 8.dp))
Text(text = stringResource(R.string.current_app_is) + pkg, modifier = Modifier.padding(vertical = 8.dp)) Text(text = stringResource(R.string.current_app_is) + pkg, modifier = Modifier.padding(vertical = 8.dp))
SwitchItem(R.string.enable_lockdown, "", null, { lockdown }, { lockdown = it }) SwitchItem(R.string.enable_lockdown, "", null, { lockdown }, { lockdown = it }, padding = false)
Spacer(Modifier.padding(vertical = 5.dp)) Spacer(Modifier.padding(vertical = 5.dp))
Button( Button(
onClick = { setAlwaysOnVpn(pkgName, lockdown); refresh() }, onClick = { setAlwaysOnVpn(pkgName, lockdown); refresh() },
@@ -827,19 +808,13 @@ private fun PermittedIME(pkgName: String) {
Spacer(Modifier.padding(vertical = 10.dp)) Spacer(Modifier.padding(vertical = 10.dp))
Text(text = stringResource(R.string.permitted_ime), style = typography.headlineLarge) Text(text = stringResource(R.string.permitted_ime), style = typography.headlineLarge)
Spacer(Modifier.padding(vertical = 5.dp)) Spacer(Modifier.padding(vertical = 5.dp))
Row( SwitchItem(
horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically, R.string.allow_all, "", null, { allowAll },
modifier = Modifier.fillMaxWidth().padding(horizontal = 6.dp, vertical = 8.dp) {
) { dpm.setPermittedInputMethods(receiver, if(it) null else listOf())
Text(stringResource(R.string.allow_all), style = typography.titleLarge) refresh()
Switch( }, padding = false
checked = allowAll, )
onCheckedChange = {
dpm.setPermittedInputMethods(receiver, if(it) null else listOf())
refresh()
}
)
}
AnimatedVisibility(!allowAll) { AnimatedVisibility(!allowAll) {
Column { Column {
SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize()) { SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize()) {
@@ -963,6 +938,7 @@ private fun UninstallApp(pkgName: String) {
val pkgInstaller = context.getPI() val pkgInstaller = context.getPI()
pkgInstaller.uninstall(pkgName, intentSender) pkgInstaller.uninstall(pkgName, intentSender)
}, },
enabled = pkgName != "",
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text(stringResource(R.string.silent_uninstall)) Text(stringResource(R.string.silent_uninstall))
@@ -973,6 +949,7 @@ private fun UninstallApp(pkgName: String) {
intent.setData(Uri.parse("package:$pkgName")) intent.setData(Uri.parse("package:$pkgName"))
context.startActivity(intent) context.startActivity(intent)
}, },
enabled = pkgName != "",
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text(stringResource(R.string.request_uninstall)) Text(stringResource(R.string.request_uninstall))
@@ -1033,7 +1010,7 @@ private fun InstallApp() {
@SuppressLint("NewApi") @SuppressLint("NewApi")
@Composable @Composable
private fun ClearAppDataDialog(status: MutableState<Boolean>, pkgName: String) { private fun ClearAppDataDialog(status: MutableIntState, pkgName: String) {
val context = LocalContext.current val context = LocalContext.current
val dpm = context.getDPM() val dpm = context.getDPM()
val receiver = context.getReceiver() val receiver = context.getReceiver()
@@ -1056,7 +1033,7 @@ private fun ClearAppDataDialog(status: MutableState<Boolean>, pkgName: String) {
Looper.loop() Looper.loop()
} }
dpm.clearApplicationUserData(receiver, pkgName, executor, onClear) dpm.clearApplicationUserData(receiver, pkgName, executor, onClear)
status.value = false status.intValue = 0
}, },
colors = ButtonDefaults.textButtonColors(contentColor = colorScheme.error) colors = ButtonDefaults.textButtonColors(contentColor = colorScheme.error)
) { ) {
@@ -1065,19 +1042,19 @@ private fun ClearAppDataDialog(status: MutableState<Boolean>, pkgName: String) {
}, },
dismissButton = { dismissButton = {
TextButton( TextButton(
onClick = { status.value = false } onClick = { status.intValue = 0 }
) { ) {
Text(text = stringResource(R.string.cancel)) Text(text = stringResource(R.string.cancel))
} }
}, },
onDismissRequest = { status.value = false }, onDismissRequest = { status.intValue = 0 },
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) )
} }
@SuppressLint("NewApi") @SuppressLint("NewApi")
@Composable @Composable
private fun DefaultDialerAppDialog(status: MutableState<Boolean>, pkgName: String) { private fun DefaultDialerAppDialog(status: MutableIntState, pkgName: String) {
val context = LocalContext.current val context = LocalContext.current
val dpm = context.getDPM() val dpm = context.getDPM()
AlertDialog( AlertDialog(
@@ -1085,9 +1062,9 @@ private fun DefaultDialerAppDialog(status: MutableState<Boolean>, pkgName: Strin
text = { text = {
Text(stringResource(R.string.app_will_be_default_dialer) + "\n" + pkgName) Text(stringResource(R.string.app_will_be_default_dialer) + "\n" + pkgName)
}, },
onDismissRequest = { status.value = false }, onDismissRequest = { status.intValue = 0 },
dismissButton = { dismissButton = {
TextButton(onClick = { status.value = false }) { TextButton(onClick = { status.intValue = 0 }) {
Text(stringResource(R.string.cancel)) Text(stringResource(R.string.cancel))
} }
}, },
@@ -1100,7 +1077,7 @@ private fun DefaultDialerAppDialog(status: MutableState<Boolean>, pkgName: Strin
}catch(e:IllegalArgumentException) { }catch(e:IllegalArgumentException) {
Toast.makeText(context, R.string.failed, Toast.LENGTH_SHORT).show() Toast.makeText(context, R.string.failed, Toast.LENGTH_SHORT).show()
} }
status.value = false status.intValue = 0
} }
) { ) {
Text(stringResource(R.string.confirm)) Text(stringResource(R.string.confirm))
@@ -1111,7 +1088,7 @@ private fun DefaultDialerAppDialog(status: MutableState<Boolean>, pkgName: Strin
} }
@Composable @Composable
private fun EnableSystemAppDialog(status: MutableState<Boolean>, pkgName: String) { private fun EnableSystemAppDialog(status: MutableIntState, pkgName: String) {
val context = LocalContext.current val context = LocalContext.current
val dpm = context.getDPM() val dpm = context.getDPM()
val receiver = context.getReceiver() val receiver = context.getReceiver()
@@ -1120,9 +1097,9 @@ private fun EnableSystemAppDialog(status: MutableState<Boolean>, pkgName: String
text = { text = {
Text(stringResource(R.string.enable_system_app_desc) + "\n" + pkgName) Text(stringResource(R.string.enable_system_app_desc) + "\n" + pkgName)
}, },
onDismissRequest = { status.value = false }, onDismissRequest = { status.intValue = 0 },
dismissButton = { dismissButton = {
TextButton(onClick = { status.value = false }) { TextButton(onClick = { status.intValue = 0 }) {
Text(stringResource(R.string.cancel)) Text(stringResource(R.string.cancel))
} }
}, },
@@ -1135,7 +1112,7 @@ private fun EnableSystemAppDialog(status: MutableState<Boolean>, pkgName: String
} catch(e: IllegalArgumentException) { } catch(e: IllegalArgumentException) {
Toast.makeText(context, R.string.failed, Toast.LENGTH_SHORT).show() Toast.makeText(context, R.string.failed, Toast.LENGTH_SHORT).show()
} }
status.value = false status.intValue = 0
} }
) { ) {
Text(stringResource(R.string.confirm)) Text(stringResource(R.string.confirm))
@@ -1148,55 +1125,42 @@ private fun EnableSystemAppDialog(status: MutableState<Boolean>, pkgName: String
@Composable @Composable
private fun AppControlDialog(status: MutableIntState) { private fun AppControlDialog(status: MutableIntState) {
val enabled = dialogGetStatus() val enabled = dialogGetStatus()
Dialog( AlertDialog(
onDismissRequest = { status.intValue = 0 } onDismissRequest = { status.intValue = 0 },
) { title = {
Card( Text(
modifier = Modifier.fillMaxWidth() text = stringResource(
) { when(status.intValue) {
Column( 1 -> R.string.suspend
modifier = Modifier.fillMaxWidth().padding(15.dp) 2 -> R.string.hide
3 -> R.string.block_uninstall
4 -> R.string.always_on_vpn
else -> R.string.unknown
}
),
style = typography.headlineMedium,
modifier = Modifier.padding(start = 5.dp)
)
},
text = {
Text(
text = stringResource(R.string.current_status_is) + stringResource(if(enabled) R.string.enabled else R.string.disabled),
modifier = Modifier.padding(start = 5.dp, top = 5.dp, bottom = 5.dp)
)
},
confirmButton = {
TextButton(
onClick = { dialogConfirmButtonAction(); status.intValue = 0 }
) { ) {
Text( Text(text = stringResource(R.string.enable))
text = stringResource( }
when(status.intValue) { },
1 -> R.string.suspend dismissButton = {
2 -> R.string.hide TextButton(
3 -> R.string.block_uninstall onClick = { dialogDismissButtonAction(); status.intValue = 0 }
4 -> R.string.always_on_vpn ) {
else -> R.string.unknown Text(text = stringResource(R.string.disable))
}
),
style = typography.headlineMedium,
modifier = Modifier.padding(start = 5.dp)
)
Text(
text = stringResource(R.string.current_status_is) + stringResource(if(enabled) R.string.enabled else R.string.disabled),
modifier = Modifier.padding(start = 5.dp, top = 5.dp, bottom = 5.dp)
)
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
TextButton(
onClick = { status.intValue = 0 }
) {
Text(text = stringResource(R.string.cancel))
}
Row{
TextButton(
onClick = { dialogDismissButtonAction(); status.intValue = 0 }
) {
Text(text = stringResource(R.string.disable))
}
TextButton(
onClick = { dialogConfirmButtonAction(); status.intValue = 0 }
) {
Text(text = stringResource(R.string.enable))
}
}
}
} }
} }
} )
} }

View File

@@ -98,12 +98,12 @@ private fun Home(navCtrl: NavHostController) {
val receiver = context.getReceiver() val receiver = context.getReceiver()
val profileOwner = context.isProfileOwner val profileOwner = context.isProfileOwner
Column( Column(
modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(start = 30.dp, end = 12.dp) modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())
) { ) {
Text( Text(
text = stringResource(R.string.work_profile), text = stringResource(R.string.work_profile),
style = typography.headlineLarge, style = typography.headlineLarge,
modifier = Modifier.padding(top = 8.dp, bottom = 5.dp).offset(x = (-8).dp) modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 16.dp)
) )
if(VERSION.SDK_INT >= 30 && profileOwner && dpm.isManagedProfile(receiver)) { if(VERSION.SDK_INT >= 30 && profileOwner && dpm.isManagedProfile(receiver)) {
SubPageItem(R.string.org_owned_work_profile, "", R.drawable.corporate_fare_fill0) { navCtrl.navigate("OrgOwnedWorkProfile") } SubPageItem(R.string.org_owned_work_profile, "", R.drawable.corporate_fare_fill0) { navCtrl.navigate("OrgOwnedWorkProfile") }
@@ -195,7 +195,7 @@ private fun SuspendPersonalApp() {
SwitchItem( SwitchItem(
R.string.suspend_personal_app, "", null, R.string.suspend_personal_app, "", null,
{ dpm.getPersonalAppsSuspendedReasons(receiver)!=PERSONAL_APPS_NOT_SUSPENDED }, { dpm.getPersonalAppsSuspendedReasons(receiver)!=PERSONAL_APPS_NOT_SUSPENDED },
{ dpm.setPersonalAppsSuspended(receiver,it) } { dpm.setPersonalAppsSuspended(receiver,it) }, padding = false
) )
var time by remember { mutableStateOf("") } var time by remember { mutableStateOf("") }
time = dpm.getManagedProfileMaximumTimeOff(receiver).toString() time = dpm.getManagedProfileMaximumTimeOff(receiver).toString()

View File

@@ -157,11 +157,11 @@ private fun Home(navCtrl:NavHostController, scrollState: ScrollState, wifiMacDia
val receiver = context.getReceiver() val receiver = context.getReceiver()
val deviceOwner = context.isDeviceOwner val deviceOwner = context.isDeviceOwner
val profileOwner = context.isProfileOwner val profileOwner = context.isProfileOwner
Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState).padding(start = 30.dp, end = 12.dp)) { Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)) {
Text( Text(
text = stringResource(R.string.network), text = stringResource(R.string.network),
style = typography.headlineLarge, style = typography.headlineLarge,
modifier = Modifier.padding(top = 8.dp, bottom = 5.dp).offset(x = (-8).dp) modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 16.dp)
) )
if(VERSION.SDK_INT >= 24 && (deviceOwner || dpm.isOrgProfile(receiver))) { if(VERSION.SDK_INT >= 24 && (deviceOwner || dpm.isOrgProfile(receiver))) {
SubPageItem(R.string.wifi_mac_addr, "", R.drawable.wifi_fill0) { wifiMacDialog.value = true } SubPageItem(R.string.wifi_mac_addr, "", R.drawable.wifi_fill0) { wifiMacDialog.value = true }
@@ -200,7 +200,7 @@ private fun Switches() {
val dpm = context.getDPM() val dpm = context.getDPM()
val receiver = context.getReceiver() val receiver = context.getReceiver()
val deviceOwner = context.isDeviceOwner val deviceOwner = context.isDeviceOwner
Column(modifier = Modifier.fillMaxSize().padding(start = 20.dp, end = 12.dp)) { Column(modifier = Modifier.fillMaxSize()) {
Spacer(Modifier.padding(vertical = 5.dp)) Spacer(Modifier.padding(vertical = 5.dp))
if(VERSION.SDK_INT >= 33 && deviceOwner) { if(VERSION.SDK_INT >= 33 && deviceOwner) {
SwitchItem( SwitchItem(
@@ -547,7 +547,7 @@ private fun NetworkLog() {
Spacer(Modifier.padding(vertical = 5.dp)) Spacer(Modifier.padding(vertical = 5.dp))
Text(text = stringResource(R.string.developing)) Text(text = stringResource(R.string.developing))
Spacer(Modifier.padding(vertical = 5.dp)) Spacer(Modifier.padding(vertical = 5.dp))
SwitchItem(R.string.enable,"",null, {dpm.isNetworkLoggingEnabled(receiver) }, {dpm.setNetworkLoggingEnabled(receiver,it) }) SwitchItem(R.string.enable,"",null, {dpm.isNetworkLoggingEnabled(receiver) }, {dpm.setNetworkLoggingEnabled(receiver,it) }, padding = false)
Spacer(Modifier.padding(vertical = 5.dp)) Spacer(Modifier.padding(vertical = 5.dp))
Button( Button(
onClick = { onClick = {
@@ -630,7 +630,7 @@ private fun APN() {
Spacer(Modifier.padding(vertical = 5.dp)) Spacer(Modifier.padding(vertical = 5.dp))
Text(text = stringResource(id = R.string.developing)) Text(text = stringResource(id = R.string.developing))
Spacer(Modifier.padding(vertical = 5.dp)) Spacer(Modifier.padding(vertical = 5.dp))
SwitchItem(R.string.enable, "", null, { dpm.isOverrideApnEnabled(receiver) }, { dpm.setOverrideApnsEnabled(receiver,it) }) SwitchItem(R.string.enable, "", null, { dpm.isOverrideApnEnabled(receiver) }, { dpm.setOverrideApnsEnabled(receiver,it) }, padding = false)
Text(text = stringResource(R.string.total_apn_amount, setting.size)) Text(text = stringResource(R.string.total_apn_amount, setting.size))
if(setting.size>0) { if(setting.size>0) {
Text(text = stringResource(R.string.select_a_apn_or_create, setting.size)) Text(text = stringResource(R.string.select_a_apn_or_create, setting.size))

View File

@@ -96,7 +96,7 @@ fun Password(navCtrl: NavHostController) {
Scaffold( Scaffold(
topBar = { topBar = {
TopBar(backStackEntry,navCtrl,localNavCtrl) { TopBar(backStackEntry,navCtrl,localNavCtrl) {
if(backStackEntry?.destination?.route == "Home" && scrollState.maxValue > 80) { if(backStackEntry?.destination?.route == "Home" && scrollState.maxValue > 100) {
Text( Text(
text = stringResource(R.string.password_and_keyguard), text = stringResource(R.string.password_and_keyguard),
modifier = Modifier.alpha((maxOf(scrollState.value-30,0)).toFloat()/80) modifier = Modifier.alpha((maxOf(scrollState.value-30,0)).toFloat()/80)
@@ -130,17 +130,17 @@ fun Password(navCtrl: NavHostController) {
} }
@Composable @Composable
private fun Home(navCtrl:NavHostController,scrollState: ScrollState) { private fun Home(navCtrl:NavHostController, scrollState: ScrollState) {
val context = LocalContext.current val context = LocalContext.current
val sharedPrefs = context.getSharedPreferences("data", Context.MODE_PRIVATE) val sharedPrefs = context.getSharedPreferences("data", Context.MODE_PRIVATE)
val deviceAdmin = context.isDeviceAdmin val deviceAdmin = context.isDeviceAdmin
val deviceOwner = context.isDeviceOwner val deviceOwner = context.isDeviceOwner
val profileOwner = context.isProfileOwner val profileOwner = context.isProfileOwner
Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState).padding(start = 30.dp, end = 12.dp)) { Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)) {
Text( Text(
text = stringResource(R.string.password_and_keyguard), text = stringResource(R.string.password_and_keyguard),
style = typography.headlineLarge, style = typography.headlineLarge,
modifier = Modifier.padding(top = 8.dp, bottom = 5.dp).offset(x = (-8).dp) modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 16.dp)
) )
SubPageItem(R.string.password_info, "", R.drawable.info_fill0) { navCtrl.navigate("PasswordInfo") } SubPageItem(R.string.password_info, "", R.drawable.info_fill0) { navCtrl.navigate("PasswordInfo") }
if(sharedPrefs.getBoolean("dangerous_features", false)) { if(sharedPrefs.getBoolean("dangerous_features", false)) {

View File

@@ -50,7 +50,7 @@ fun DpmPermissions(navCtrl:NavHostController) {
Scaffold( Scaffold(
topBar = { topBar = {
TopBar(backStackEntry,navCtrl,localNavCtrl) { TopBar(backStackEntry,navCtrl,localNavCtrl) {
if(backStackEntry?.destination?.route=="Home"&&scrollState.maxValue>80) { if(backStackEntry?.destination?.route=="Home"&&scrollState.maxValue > 100) {
Text( Text(
text = stringResource(R.string.permission), text = stringResource(R.string.permission),
modifier = Modifier.alpha((maxOf(scrollState.value-30,0)).toFloat()/80) modifier = Modifier.alpha((maxOf(scrollState.value-30,0)).toFloat()/80)
@@ -94,11 +94,11 @@ private fun Home(localNavCtrl:NavHostController,listScrollState:ScrollState) {
val deviceAdmin = context.isDeviceAdmin val deviceAdmin = context.isDeviceAdmin
val deviceOwner = context.isDeviceOwner val deviceOwner = context.isDeviceOwner
val profileOwner = context.isProfileOwner val profileOwner = context.isProfileOwner
Column(modifier = Modifier.fillMaxSize().verticalScroll(listScrollState).padding(start = 30.dp, end = 12.dp)) { Column(modifier = Modifier.fillMaxSize().verticalScroll(listScrollState)) {
Text( Text(
text = stringResource(R.string.permission), text = stringResource(R.string.permission),
style = typography.headlineLarge, style = typography.headlineLarge,
modifier = Modifier.padding(top = 8.dp, bottom = 5.dp).offset(x = (-8).dp) modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 16.dp)
) )
if(!dpm.isDeviceOwnerApp(context.packageName)) { if(!dpm.isDeviceOwnerApp(context.packageName)) {
SwitchItem( SwitchItem(

View File

@@ -51,7 +51,6 @@ fun ShizukuActivate() {
var bindShizuku by remember { mutableStateOf(false) } var bindShizuku by remember { mutableStateOf(false) }
var outputText by remember { mutableStateOf("") } var outputText by remember { mutableStateOf("") }
var showDeviceAdminButton by remember { mutableStateOf(!context.isDeviceAdmin) } var showDeviceAdminButton by remember { mutableStateOf(!context.isDeviceAdmin) }
var showProfileOwnerButton by remember { mutableStateOf(!context.isProfileOwner) }
var showDeviceOwnerButton by remember { mutableStateOf(!context.isDeviceOwner) } var showDeviceOwnerButton by remember { mutableStateOf(!context.isDeviceOwner) }
var showOrgProfileOwnerButton by remember { mutableStateOf(true) } var showOrgProfileOwnerButton by remember { mutableStateOf(true) }
val service by shizukuService.collectAsState() val service by shizukuService.collectAsState()
@@ -117,7 +116,7 @@ fun ShizukuActivate() {
} }
Spacer(Modifier.padding(vertical = 5.dp)) Spacer(Modifier.padding(vertical = 5.dp))
AnimatedVisibility(showDeviceAdminButton && showProfileOwnerButton && showDeviceOwnerButton) { AnimatedVisibility(showDeviceAdminButton && showDeviceOwnerButton) {
Button( Button(
onClick = { onClick = {
coScope.launch{ coScope.launch{
@@ -133,7 +132,7 @@ fun ShizukuActivate() {
} }
} }
AnimatedVisibility(showDeviceOwnerButton && showProfileOwnerButton) { AnimatedVisibility(showDeviceOwnerButton) {
Button( Button(
onClick = { onClick = {
coScope.launch{ coScope.launch{

View File

@@ -126,7 +126,7 @@ fun SystemManage(navCtrl:NavHostController) {
Scaffold( Scaffold(
topBar = { topBar = {
TopBar(backStackEntry,navCtrl,localNavCtrl) { TopBar(backStackEntry,navCtrl,localNavCtrl) {
if(backStackEntry?.destination?.route=="Home"&&scrollState.maxValue>80) { if(backStackEntry?.destination?.route=="Home"&&scrollState.maxValue > 100) {
Text( Text(
text = stringResource(R.string.system_manage), text = stringResource(R.string.system_manage),
modifier = Modifier.alpha((maxOf(scrollState.value-30,0)).toFloat()/80) modifier = Modifier.alpha((maxOf(scrollState.value-30,0)).toFloat()/80)
@@ -177,11 +177,11 @@ private fun Home(navCtrl: NavHostController, scrollState: ScrollState, rebootDia
val dangerousFeatures = sharedPref.getBoolean("dangerous_features", false) val dangerousFeatures = sharedPref.getBoolean("dangerous_features", false)
val deviceOwner = context.isDeviceOwner val deviceOwner = context.isDeviceOwner
val profileOwner = context.isProfileOwner val profileOwner = context.isProfileOwner
Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState).padding(start = 30.dp, end = 12.dp)) { Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)) {
Text( Text(
text = stringResource(R.string.system_manage), text = stringResource(R.string.system_manage),
style = typography.headlineLarge, style = typography.headlineLarge,
modifier = Modifier.padding(top = 8.dp, bottom = 5.dp).offset(x = (-8).dp) modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 16.dp)
) )
if(deviceOwner || profileOwner) { if(deviceOwner || profileOwner) {
SubPageItem(R.string.options, "", R.drawable.tune_fill0) { navCtrl.navigate("Switches") } SubPageItem(R.string.options, "", R.drawable.tune_fill0) { navCtrl.navigate("Switches") }
@@ -239,7 +239,7 @@ private fun Switches() {
val receiver = context.getReceiver() val receiver = context.getReceiver()
val deviceOwner = context.isDeviceOwner val deviceOwner = context.isDeviceOwner
val profileOwner = context.isProfileOwner val profileOwner = context.isProfileOwner
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(start = 20.dp, end = 12.dp)) { Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
Spacer(Modifier.padding(vertical = 10.dp)) Spacer(Modifier.padding(vertical = 10.dp))
if(deviceOwner || profileOwner) { if(deviceOwner || profileOwner) {
SwitchItem(R.string.disable_cam,"", R.drawable.photo_camera_fill0, SwitchItem(R.string.disable_cam,"", R.drawable.photo_camera_fill0,
@@ -247,7 +247,7 @@ private fun Switches() {
) )
} }
if(deviceOwner || profileOwner) { if(deviceOwner || profileOwner) {
SwitchItem(R.string.disable_screen_capture, stringResource(R.string.also_disable_aosp_screen_record), R.drawable.screenshot_fill0, SwitchItem(R.string.disable_screen_capture, "", R.drawable.screenshot_fill0,
{ dpm.getScreenCaptureDisabled(null) }, { dpm.setScreenCaptureDisabled(receiver,it) } { dpm.getScreenCaptureDisabled(null) }, { dpm.setScreenCaptureDisabled(receiver,it) }
) )
} }
@@ -284,7 +284,7 @@ private fun Switches() {
) )
} }
if(VERSION.SDK_INT >= 30 && deviceOwner) { if(VERSION.SDK_INT >= 30 && deviceOwner) {
SwitchItem(R.string.common_criteria_mode, stringResource(R.string.common_criteria_mode_desc),R.drawable.security_fill0, SwitchItem(R.string.common_criteria_mode , "",R.drawable.security_fill0,
{ dpm.isCommonCriteriaModeEnabled(receiver) }, { dpm.setCommonCriteriaModeEnabled(receiver,it) } { dpm.isCommonCriteriaModeEnabled(receiver) }, { dpm.setCommonCriteriaModeEnabled(receiver,it) }
) )
} }
@@ -932,7 +932,7 @@ private fun SecurityLogs() {
Text(text = stringResource(R.string.security_logs), style = typography.headlineLarge) Text(text = stringResource(R.string.security_logs), style = typography.headlineLarge)
Spacer(Modifier.padding(vertical = 5.dp)) Spacer(Modifier.padding(vertical = 5.dp))
Text(text = stringResource(R.string.developing)) Text(text = stringResource(R.string.developing))
SwitchItem(R.string.enable, "", null, { dpm.isSecurityLoggingEnabled(receiver) }, { dpm.setSecurityLoggingEnabled(receiver,it) }) SwitchItem(R.string.enable, "", null, { dpm.isSecurityLoggingEnabled(receiver) }, { dpm.setSecurityLoggingEnabled(receiver,it) }, padding = false)
Button( Button(
onClick = { onClick = {
val log = dpm.retrieveSecurityLogs(receiver) val log = dpm.retrieveSecurityLogs(receiver)

View File

@@ -75,7 +75,7 @@ fun UserManage(navCtrl: NavHostController) {
Scaffold( Scaffold(
topBar = { topBar = {
TopBar(backStackEntry, navCtrl, localNavCtrl) { TopBar(backStackEntry, navCtrl, localNavCtrl) {
if(backStackEntry?.destination?.route == "Home" && scrollState.maxValue > 80) { if(backStackEntry?.destination?.route == "Home" && scrollState.maxValue > 100) {
Text( Text(
text = stringResource(R.string.user_manager), text = stringResource(R.string.user_manager),
modifier = Modifier.alpha((maxOf(scrollState.value-30, 0)).toFloat() / 80) modifier = Modifier.alpha((maxOf(scrollState.value-30, 0)).toFloat() / 80)
@@ -109,11 +109,11 @@ private fun Home(navCtrl: NavHostController,scrollState: ScrollState) {
val context = LocalContext.current val context = LocalContext.current
val deviceOwner = context.isDeviceOwner val deviceOwner = context.isDeviceOwner
val profileOwner = context.isProfileOwner val profileOwner = context.isProfileOwner
Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState).padding(start = 30.dp, end = 12.dp)) { Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)) {
Text( Text(
text = stringResource(R.string.user_manager), text = stringResource(R.string.user_manager),
style = typography.headlineLarge, style = typography.headlineLarge,
modifier = Modifier.padding(top = 8.dp, bottom = 5.dp).offset(x = (-8).dp) modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 16.dp)
) )
SubPageItem(R.string.user_info, "", R.drawable.person_fill0) { navCtrl.navigate("UserInfo") } SubPageItem(R.string.user_info, "", R.drawable.person_fill0) { navCtrl.navigate("UserInfo") }
if(deviceOwner) { if(deviceOwner) {

View File

@@ -98,16 +98,16 @@ private fun Home(navCtrl:NavHostController, scrollState: ScrollState) {
val context = LocalContext.current val context = LocalContext.current
val dpm = context.getDPM() val dpm = context.getDPM()
val receiver = context.getReceiver() val receiver = context.getReceiver()
Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState).padding(start = 30.dp, end = 12.dp)) { Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)) {
Text( Text(
text = stringResource(R.string.user_restrict), text = stringResource(R.string.user_restrict),
style = typography.headlineLarge, style = typography.headlineLarge,
modifier = Modifier.padding(top = 8.dp, bottom = 7.dp).offset(x = (-8).dp) modifier = Modifier.padding(top = 8.dp, bottom = 7.dp, start = 16.dp)
) )
Text(text = stringResource(R.string.switch_to_disable_feature), modifier = Modifier.offset(x = (-6).dp)) Text(text = stringResource(R.string.switch_to_disable_feature), modifier = Modifier.padding(start = 16.dp))
if(context.isProfileOwner) { Text(text = stringResource(R.string.profile_owner_is_restricted), modifier = Modifier.offset(x = (-6).dp)) } if(context.isProfileOwner) { Text(text = stringResource(R.string.profile_owner_is_restricted), modifier = Modifier.padding(start = 16.dp)) }
if(context.isProfileOwner && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver)))) { if(context.isProfileOwner && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver)))) {
Text(text = stringResource(R.string.some_features_invalid_in_work_profile), modifier = Modifier.offset(x = (-6).dp)) Text(text = stringResource(R.string.some_features_invalid_in_work_profile), modifier = Modifier.padding(start = 16.dp))
} }
Spacer(Modifier.padding(vertical = 2.dp)) Spacer(Modifier.padding(vertical = 2.dp))
SubPageItem(R.string.network_internet, "", R.drawable.wifi_fill0) { navCtrl.navigate("Internet") } SubPageItem(R.string.network_internet, "", R.drawable.wifi_fill0) { navCtrl.navigate("Internet") }
@@ -209,7 +209,7 @@ private fun UserRestrictionItem(
Toast.makeText(context, R.string.require_device_owner, Toast.LENGTH_SHORT).show() Toast.makeText(context, R.string.require_device_owner, Toast.LENGTH_SHORT).show()
} }
} }
} }, padding = false
) )
} }
} }
@@ -261,7 +261,7 @@ object RestrictionData {
if(VERSION.SDK_INT>=29) { list += Restriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, R.string.install_unknown_src_globally, "", R.drawable.android_fill0) } if(VERSION.SDK_INT>=29) { list += Restriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, R.string.install_unknown_src_globally, "", R.drawable.android_fill0) }
list += Restriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, R.string.inst_unknown_src, "", R.drawable.android_fill0) list += Restriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, R.string.inst_unknown_src, "", R.drawable.android_fill0)
list += Restriction(UserManager.DISALLOW_UNINSTALL_APPS, R.string.uninstall_app, "", R.drawable.delete_fill0) list += Restriction(UserManager.DISALLOW_UNINSTALL_APPS, R.string.uninstall_app, "", R.drawable.delete_fill0)
list += Restriction(UserManager.DISALLOW_APPS_CONTROL, R.string.apps_ctrl, context.getString(R.string.apps_control_desc), R.drawable.apps_fill0) list += Restriction(UserManager.DISALLOW_APPS_CONTROL, R.string.apps_ctrl, "", R.drawable.apps_fill0)
if(VERSION.SDK_INT>=34) { list += Restriction(UserManager.DISALLOW_CONFIG_DEFAULT_APPS, R.string.config_default_apps, "", R.drawable.apps_fill0) } if(VERSION.SDK_INT>=34) { list += Restriction(UserManager.DISALLOW_CONFIG_DEFAULT_APPS, R.string.config_default_apps, "", R.drawable.apps_fill0) }
return list return list
} }
@@ -301,10 +301,10 @@ object RestrictionData {
list += Restriction(UserManager.DISALLOW_CONTENT_CAPTURE, R.string.content_capture, "", R.drawable.screenshot_fill0) list += Restriction(UserManager.DISALLOW_CONTENT_CAPTURE, R.string.content_capture, "", R.drawable.screenshot_fill0)
list += Restriction(UserManager.DISALLOW_CONTENT_SUGGESTIONS, R.string.content_suggestions, "", R.drawable.sms_fill0) list += Restriction(UserManager.DISALLOW_CONTENT_SUGGESTIONS, R.string.content_suggestions, "", R.drawable.sms_fill0)
} }
list += Restriction(UserManager.DISALLOW_CREATE_WINDOWS, R.string.create_windows, context.getString(R.string.create_windows_desc), R.drawable.web_asset) list += Restriction(UserManager.DISALLOW_CREATE_WINDOWS, R.string.create_windows, "", R.drawable.web_asset)
if(VERSION.SDK_INT>=24) { list += Restriction(UserManager.DISALLOW_SET_WALLPAPER, R.string.set_wallpaper, "", R.drawable.wallpaper_fill0) } if(VERSION.SDK_INT>=24) { list += Restriction(UserManager.DISALLOW_SET_WALLPAPER, R.string.set_wallpaper, "", R.drawable.wallpaper_fill0) }
if(VERSION.SDK_INT>=34) { list += Restriction(UserManager.DISALLOW_GRANT_ADMIN, R.string.grant_admin, "", R.drawable.security_fill0) } if(VERSION.SDK_INT>=34) { list += Restriction(UserManager.DISALLOW_GRANT_ADMIN, R.string.grant_admin, "", R.drawable.security_fill0) }
if(VERSION.SDK_INT>=23) { list += Restriction(UserManager.DISALLOW_FUN, R.string.`fun`, context.getString(R.string.fun_desc), R.drawable.stadia_controller_fill0) } if(VERSION.SDK_INT>=23) { list += Restriction(UserManager.DISALLOW_FUN, R.string.`fun`, "", R.drawable.stadia_controller_fill0) }
list += Restriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, R.string.modify_accounts, "", R.drawable.manage_accounts_fill0) list += Restriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, R.string.modify_accounts, "", R.drawable.manage_accounts_fill0)
if(VERSION.SDK_INT>=28) { if(VERSION.SDK_INT>=28) {
list += Restriction(UserManager.DISALLOW_CONFIG_LOCALE, R.string.config_locale, "", R.drawable.language_fill0) list += Restriction(UserManager.DISALLOW_CONFIG_LOCALE, R.string.config_locale, "", R.drawable.language_fill0)

View File

@@ -35,10 +35,10 @@ fun SubPageItem(
operation: () -> Unit operation: () -> Unit
) { ) {
Row( Row(
modifier = Modifier.fillMaxWidth().clickable(onClick = operation).padding(vertical = 15.dp), modifier = Modifier.fillMaxWidth().clickable(onClick = operation).padding(top = 15.dp, bottom = 15.dp, start = 30.dp, end = 12.dp),
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
if(icon!=null) { if(icon != null) {
Icon(painter = painterResource(icon), contentDescription = stringResource(title), modifier = Modifier.padding(top = 1.dp)) Icon(painter = painterResource(icon), contentDescription = stringResource(title), modifier = Modifier.padding(top = 1.dp))
Spacer(Modifier.padding(start = 15.dp)) Spacer(Modifier.padding(start = 15.dp))
} }
@@ -132,14 +132,15 @@ fun SwitchItem(
getState: ()->Boolean, getState: ()->Boolean,
onCheckedChange: (Boolean)->Unit, onCheckedChange: (Boolean)->Unit,
enable: Boolean = true, enable: Boolean = true,
onClickBlank: (() -> Unit)? = null onClickBlank: (() -> Unit)? = null,
padding: Boolean = true
) { ) {
var checked by remember { mutableStateOf(getState()) } var checked by remember { mutableStateOf(getState()) }
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.clickable(enabled = onClickBlank != null, onClick = onClickBlank?:{}) .clickable(enabled = onClickBlank != null, onClick = onClickBlank?:{})
.padding(vertical = 5.dp) .padding(top = 5.dp, bottom = 5.dp, start = if(padding) 30.dp else 0.dp, end = if(padding) 12.dp else 0.dp)
) { ) {
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,