Optimize code

New Privilege object, which follows Application lifecycle.
Add Privilege.DPM and Privilege.DAR variable, instead of creating DPM and DAR instance every time.
This commit is contained in:
BinTianqi
2025-08-29 20:58:39 +08:00
parent 10ac570818
commit 6f54bf576f
22 changed files with 496 additions and 687 deletions

View File

@@ -86,10 +86,10 @@ import com.bintianqi.owndroid.AppInstallerActivity
import com.bintianqi.owndroid.AppInstallerViewModel
import com.bintianqi.owndroid.ChoosePackageContract
import com.bintianqi.owndroid.HorizontalPadding
import com.bintianqi.owndroid.Privilege
import com.bintianqi.owndroid.R
import com.bintianqi.owndroid.getInstalledAppsFlags
import com.bintianqi.owndroid.installedApps
import com.bintianqi.owndroid.myPrivilege
import com.bintianqi.owndroid.showOperationResultToast
import com.bintianqi.owndroid.ui.ErrorDialog
import com.bintianqi.owndroid.ui.FullWidthRadioButtonItem
@@ -191,7 +191,7 @@ fun ApplicationsFeaturesScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Un
.verticalScroll(rememberScrollState())
.padding(bottom = 80.dp)
) {
val privilege by myPrivilege.collectAsStateWithLifecycle()
val privilege by Privilege.status.collectAsStateWithLifecycle()
if(VERSION.SDK_INT >= 24) FunctionItem(R.string.suspend, icon = R.drawable.block_fill0) { onNavigate(Suspend) }
FunctionItem(R.string.hide, icon = R.drawable.visibility_off_fill0) { onNavigate(Hide) }
FunctionItem(R.string.block_uninstall, icon = R.drawable.delete_forever_fill0) { onNavigate(BlockUninstall) }
@@ -246,10 +246,8 @@ fun ApplicationsFeaturesScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Un
fun ApplicationDetailsScreen(param: ApplicationDetails, onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
val packageName = param.packageName
val context = LocalContext.current
val privilege by myPrivilege.collectAsStateWithLifecycle()
val privilege by Privilege.status.collectAsStateWithLifecycle()
val pm = context.packageManager
val dpm = context.getDPM()
val receiver = context.getReceiver()
var dialog by remember { mutableIntStateOf(0) } // 1: clear storage, 2: uninstall
val info = pm.getApplicationInfo(packageName, getInstalledAppsFlags)
MySmallTitleScaffold(R.string.place_holder, onNavigateUp, 0.dp) {
@@ -261,43 +259,43 @@ fun ApplicationDetailsScreen(param: ApplicationDetails, onNavigateUp: () -> Unit
FunctionItem(R.string.permissions, icon = R.drawable.shield_fill0) { onNavigate(PermissionsManager(packageName)) }
if(VERSION.SDK_INT >= 24) SwitchItem(
R.string.suspend, icon = R.drawable.block_fill0,
getState = { dpm.isPackageSuspended(receiver, packageName) },
onCheckedChange = { dpm.setPackagesSuspended(receiver, arrayOf(packageName), it) }
getState = { Privilege.DPM.isPackageSuspended(Privilege.DAR, packageName) },
onCheckedChange = { Privilege.DPM.setPackagesSuspended(Privilege.DAR, arrayOf(packageName), it) }
)
SwitchItem(
R.string.hide, icon = R.drawable.visibility_off_fill0,
getState = { dpm.isApplicationHidden(receiver, packageName) },
onCheckedChange = { dpm.setApplicationHidden(receiver, packageName, it) }
getState = { Privilege.DPM.isApplicationHidden(Privilege.DAR, packageName) },
onCheckedChange = { Privilege.DPM.setApplicationHidden(Privilege.DAR, packageName, it) }
)
SwitchItem(
R.string.block_uninstall, icon = R.drawable.delete_forever_fill0,
getState = { dpm.isUninstallBlocked(receiver, packageName) },
onCheckedChange = { dpm.setUninstallBlocked(receiver, packageName, it) }
getState = { Privilege.DPM.isUninstallBlocked(Privilege.DAR, packageName) },
onCheckedChange = { Privilege.DPM.setUninstallBlocked(Privilege.DAR, packageName, it) }
)
if(VERSION.SDK_INT >= 30) SwitchItem(
R.string.disable_user_control, icon = R.drawable.do_not_touch_fill0,
getState = { packageName in dpm.getUserControlDisabledPackages(receiver) },
getState = { packageName in Privilege.DPM.getUserControlDisabledPackages(Privilege.DAR) },
onCheckedChange = { state ->
dpm.setUserControlDisabledPackages(receiver,
dpm.getUserControlDisabledPackages(receiver).let { if(state) it.plus(packageName) else it.minus(packageName) }
Privilege.DPM.setUserControlDisabledPackages(Privilege.DAR,
Privilege.DPM.getUserControlDisabledPackages(Privilege.DAR).let { if(state) it.plus(packageName) else it.minus(packageName) }
)
}
)
if(VERSION.SDK_INT >= 28) SwitchItem(
R.string.disable_metered_data, icon = R.drawable.money_off_fill0,
getState = { packageName in dpm.getMeteredDataDisabledPackages(receiver) },
getState = { packageName in Privilege.DPM.getMeteredDataDisabledPackages(Privilege.DAR) },
onCheckedChange = { state ->
dpm.setMeteredDataDisabledPackages(receiver,
dpm.getMeteredDataDisabledPackages(receiver).let { if(state) it.plus(packageName) else it.minus(packageName) }
Privilege.DPM.setMeteredDataDisabledPackages(Privilege.DAR,
Privilege.DPM.getMeteredDataDisabledPackages(Privilege.DAR).let { if(state) it.plus(packageName) else it.minus(packageName) }
)
}
)
if(privilege.device && VERSION.SDK_INT >= 28) SwitchItem(
R.string.keep_after_uninstall, icon = R.drawable.delete_fill0,
getState = { dpm.getKeepUninstalledPackages(receiver)?.contains(packageName) == true },
getState = { Privilege.DPM.getKeepUninstalledPackages(Privilege.DAR)?.contains(packageName) == true },
onCheckedChange = { state ->
dpm.setKeepUninstalledPackages(receiver,
dpm.getKeepUninstalledPackages(receiver)?.let { if(state) it.plus(packageName) else it.minus(packageName) } ?: listOf(packageName)
Privilege.DPM.setKeepUninstalledPackages(Privilege.DAR,
Privilege.DPM.getKeepUninstalledPackages(Privilege.DAR)?.let { if(state) it.plus(packageName) else it.minus(packageName) } ?: listOf(packageName)
)
}
)
@@ -314,14 +312,14 @@ fun ApplicationDetailsScreen(param: ApplicationDetails, onNavigateUp: () -> Unit
@Composable
fun SuspendScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
var packageName by remember { mutableStateOf("") }
val packages = remember { mutableStateListOf<AppInfo>() }
fun refresh() {
val pm = context.packageManager
packages.clear()
pm.getInstalledApplications(getInstalledAppsFlags).filter { dpm.isPackageSuspended(receiver, it.packageName) }.forEach {
pm.getInstalledApplications(getInstalledAppsFlags).filter {
Privilege.DPM.isPackageSuspended(Privilege.DAR, it.packageName)
}.forEach {
packages += it.retrieveAppInfo(pm)
}
}
@@ -329,7 +327,7 @@ fun SuspendScreen(onNavigateUp: () -> Unit) {
MyLazyScaffold(R.string.suspend, onNavigateUp) {
items(packages, { it.name }) {
ApplicationItem(it) {
dpm.setPackagesSuspended(receiver, arrayOf(it.name), false)
Privilege.DPM.setPackagesSuspended(Privilege.DAR, arrayOf(it.name), false)
refresh()
}
}
@@ -338,7 +336,7 @@ fun SuspendScreen(onNavigateUp: () -> Unit) {
PackageNameTextField(packageName, Modifier.padding(vertical = 8.dp)) { packageName = it }
Button(
{
if(dpm.setPackagesSuspended(receiver, arrayOf(packageName), true).isEmpty()) packageName = ""
if(Privilege.DPM.setPackagesSuspended(Privilege.DAR, arrayOf(packageName), true).isEmpty()) packageName = ""
else context.showOperationResultToast(false)
refresh()
},
@@ -358,14 +356,12 @@ fun SuspendScreen(onNavigateUp: () -> Unit) {
@Composable
fun HideScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
var packageName by remember { mutableStateOf("") }
val packages = remember { mutableStateListOf<AppInfo>() }
fun refresh() {
val pm = context.packageManager
packages.clear()
pm.getInstalledApplications(getInstalledAppsFlags).filter { dpm.isApplicationHidden(receiver, it.packageName) }.forEach {
pm.getInstalledApplications(getInstalledAppsFlags).filter { Privilege.DPM.isApplicationHidden(Privilege.DAR, it.packageName) }.forEach {
packages += it.retrieveAppInfo(pm)
}
}
@@ -373,7 +369,7 @@ fun HideScreen(onNavigateUp: () -> Unit) {
MyLazyScaffold(R.string.hide, onNavigateUp) {
items(packages, { it.name }) {
ApplicationItem(it) {
dpm.setApplicationHidden(receiver, it.name, false)
Privilege.DPM.setApplicationHidden(Privilege.DAR, it.name, false)
refresh()
}
}
@@ -382,7 +378,7 @@ fun HideScreen(onNavigateUp: () -> Unit) {
PackageNameTextField(packageName, Modifier.padding(vertical = 8.dp)) { packageName = it }
Button(
{
if(dpm.setApplicationHidden(receiver, packageName, true)) packageName = ""
if(Privilege.DPM.setApplicationHidden(Privilege.DAR, packageName, true)) packageName = ""
else context.showOperationResultToast(false)
refresh()
},
@@ -401,14 +397,12 @@ fun HideScreen(onNavigateUp: () -> Unit) {
@Composable
fun BlockUninstallScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
var packageName by remember { mutableStateOf("") }
val packages = remember { mutableStateListOf<AppInfo>() }
fun refresh() {
val pm = context.packageManager
packages.clear()
pm.getInstalledApplications(getInstalledAppsFlags).filter { dpm.isUninstallBlocked(receiver, it.packageName) }.forEach {
pm.getInstalledApplications(getInstalledAppsFlags).filter { Privilege.DPM.isUninstallBlocked(Privilege.DAR, it.packageName) }.forEach {
packages += it.retrieveAppInfo(pm)
}
}
@@ -416,7 +410,7 @@ fun BlockUninstallScreen(onNavigateUp: () -> Unit) {
MyLazyScaffold(R.string.block_uninstall, onNavigateUp) {
items(packages, { it.name }) {
ApplicationItem(it) {
dpm.setUninstallBlocked(receiver, it.name, false)
Privilege.DPM.setUninstallBlocked(Privilege.DAR, it.name, false)
refresh()
}
}
@@ -425,7 +419,7 @@ fun BlockUninstallScreen(onNavigateUp: () -> Unit) {
PackageNameTextField(packageName, Modifier.padding(vertical = 8.dp)) { packageName = it }
Button(
{
dpm.setUninstallBlocked(receiver, packageName, true)
Privilege.DPM.setUninstallBlocked(Privilege.DAR, packageName, true)
packageName = ""
refresh()
},
@@ -445,13 +439,11 @@ fun BlockUninstallScreen(onNavigateUp: () -> Unit) {
@Composable
fun DisableUserControlScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val packages = remember { mutableStateListOf<AppInfo>() }
fun refresh() {
val pm = context.packageManager
packages.clear()
dpm.getUserControlDisabledPackages(receiver).forEach {
Privilege.DPM.getUserControlDisabledPackages(Privilege.DAR).forEach {
packages += pm.retrieveAppInfo(it)
}
}
@@ -459,7 +451,7 @@ fun DisableUserControlScreen(onNavigateUp: () -> Unit) {
MyLazyScaffold(R.string.disable_user_control, onNavigateUp) {
items(packages, { it.name }) { info ->
ApplicationItem(info) {
dpm.setUserControlDisabledPackages(receiver, packages.minus(info).map { it.name })
Privilege.DPM.setUserControlDisabledPackages(Privilege.DAR, packages.minus(info).map { it.name })
refresh()
}
}
@@ -468,7 +460,7 @@ fun DisableUserControlScreen(onNavigateUp: () -> Unit) {
PackageNameTextField(packageName, Modifier.padding(vertical = 8.dp, horizontal = HorizontalPadding)) { packageName = it }
Button(
{
dpm.setUserControlDisabledPackages(receiver, packages.map { it.name } + packageName)
Privilege.DPM.setUserControlDisabledPackages(Privilege.DAR, packages.map { it.name } + packageName)
refresh()
},
Modifier.fillMaxWidth().padding(horizontal = HorizontalPadding).padding(bottom = 8.dp),
@@ -487,15 +479,13 @@ fun DisableUserControlScreen(onNavigateUp: () -> Unit) {
fun PermissionsManagerScreen(onNavigateUp: () -> Unit, param: PermissionsManager) {
val packageNameParam = param.packageName
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val privilege by myPrivilege.collectAsStateWithLifecycle()
val privilege by Privilege.status.collectAsStateWithLifecycle()
var packageName by remember { mutableStateOf(packageNameParam ?: "") }
var selectedPermission by remember { mutableStateOf<PermissionItem?>(null) }
val statusMap = remember { mutableStateMapOf<String, Int>() }
LaunchedEffect(packageName) {
if(packageName.isValidPackageName) {
permissionList().forEach { statusMap[it.permission] = dpm.getPermissionGrantState(receiver, packageName, it.permission) }
permissionList().forEach { statusMap[it.permission] = Privilege.DPM.getPermissionGrantState(Privilege.DAR, packageName, it.permission) }
} else {
statusMap.clear()
}
@@ -536,9 +526,9 @@ fun PermissionsManagerScreen(onNavigateUp: () -> Unit, param: PermissionsManager
}
if(selectedPermission != null) {
fun changeState(state: Int) {
val result = dpm.setPermissionGrantState(receiver, packageName, selectedPermission!!.permission, state)
val result = Privilege.DPM.setPermissionGrantState(Privilege.DAR, packageName, selectedPermission!!.permission, state)
if (!result) context.showOperationResultToast(false)
statusMap[selectedPermission!!.permission] = dpm.getPermissionGrantState(receiver, packageName, selectedPermission!!.permission)
statusMap[selectedPermission!!.permission] = Privilege.DPM.getPermissionGrantState(Privilege.DAR, packageName, selectedPermission!!.permission)
selectedPermission = null
}
@Composable
@@ -582,14 +572,12 @@ fun PermissionsManagerScreen(onNavigateUp: () -> Unit, param: PermissionsManager
@Composable
fun DisableMeteredDataScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
var packageName by remember { mutableStateOf("") }
val packages = remember { mutableStateListOf<AppInfo>() }
fun refresh() {
val pm = context.packageManager
packages.clear()
dpm.getMeteredDataDisabledPackages(receiver).forEach {
Privilege.DPM.getMeteredDataDisabledPackages(Privilege.DAR).forEach {
packages += pm.retrieveAppInfo(it)
}
}
@@ -597,7 +585,7 @@ fun DisableMeteredDataScreen(onNavigateUp: () -> Unit) {
MyLazyScaffold(R.string.disable_metered_data, onNavigateUp) {
items(packages, { it.name }) { info ->
ApplicationItem(info) {
dpm.setMeteredDataDisabledPackages(receiver, packages.minus(info).map { it.name })
Privilege.DPM.setMeteredDataDisabledPackages(Privilege.DAR, packages.minus(info).map { it.name })
refresh()
}
}
@@ -605,7 +593,7 @@ fun DisableMeteredDataScreen(onNavigateUp: () -> Unit) {
PackageNameTextField(packageName, Modifier.padding(HorizontalPadding, 8.dp)) { packageName = it }
Button(
{
if(dpm.setMeteredDataDisabledPackages(receiver, packages.map { it.name } + packageName).isEmpty()) {
if(Privilege.DPM.setMeteredDataDisabledPackages(Privilege.DAR, packages.map { it.name } + packageName).isEmpty()) {
packageName = ""
} else {
context.showOperationResultToast(false)
@@ -655,8 +643,8 @@ private fun ClearAppStorageDialog(packageName: String, onClose: () -> Unit) {
TextButton(
{
clearing = true
context.getDPM().clearApplicationUserData(
context.getReceiver(), packageName, Executors.newSingleThreadExecutor()
Privilege.DPM.clearApplicationUserData(
Privilege.DAR, packageName, Executors.newSingleThreadExecutor()
) { _, it ->
Looper.prepare()
context.showOperationResultToast(it)
@@ -734,13 +722,11 @@ private fun UninstallAppDialog(packageName: String, onClose: () -> Unit) {
@Composable
fun KeepUninstalledPackagesScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val packages = remember { mutableStateListOf<AppInfo>() }
fun refresh() {
val pm = context.packageManager
packages.clear()
dpm.getKeepUninstalledPackages(receiver)?.forEach {
Privilege.DPM.getKeepUninstalledPackages(Privilege.DAR)?.forEach {
packages += pm.retrieveAppInfo(it)
}
}
@@ -748,7 +734,7 @@ fun KeepUninstalledPackagesScreen(onNavigateUp: () -> Unit) {
MyLazyScaffold(R.string.keep_uninstalled_packages, onNavigateUp) {
items(packages, { it.name }) { info ->
ApplicationItem(info) {
dpm.setKeepUninstalledPackages(receiver, packages.minus(info).map { it.name })
Privilege.DPM.setKeepUninstalledPackages(Privilege.DAR, packages.minus(info).map { it.name })
refresh()
}
}
@@ -757,7 +743,7 @@ fun KeepUninstalledPackagesScreen(onNavigateUp: () -> Unit) {
PackageNameTextField(packageName, Modifier.padding(HorizontalPadding, 8.dp)) { packageName = it }
Button(
{
dpm.setKeepUninstalledPackages(receiver, packages.map { it.name } + packageName)
Privilege.DPM.setKeepUninstalledPackages(Privilege.DAR, packages.map { it.name } + packageName)
packageName = ""
},
Modifier.fillMaxWidth().padding(horizontal = HorizontalPadding).padding(bottom = 8.dp),
@@ -782,7 +768,7 @@ fun InstallExistingAppScreen(onNavigateUp: () -> Unit) {
Button(
{
context.showOperationResultToast(
context.getDPM().installExistingPackage(context.getReceiver(), packageName)
Privilege.DPM.installExistingPackage(Privilege.DAR, packageName)
)
},
Modifier.fillMaxWidth(),
@@ -800,13 +786,11 @@ fun InstallExistingAppScreen(onNavigateUp: () -> Unit) {
@Composable
fun CrossProfilePackagesScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val packages = remember { mutableStateListOf<AppInfo>() }
fun refresh() {
val pm = context.packageManager
packages.clear()
dpm.getCrossProfilePackages(receiver).forEach {
Privilege.DPM.getCrossProfilePackages(Privilege.DAR).forEach {
packages += pm.retrieveAppInfo(it)
}
}
@@ -814,7 +798,7 @@ fun CrossProfilePackagesScreen(onNavigateUp: () -> Unit) {
MyLazyScaffold(R.string.cross_profile_apps, onNavigateUp) {
items(packages, { it.name }) { info ->
ApplicationItem(info) {
dpm.setCrossProfilePackages(receiver, packages.minus(info).map { it.name }.toSet())
Privilege.DPM.setCrossProfilePackages(Privilege.DAR, packages.minus(info).map { it.name }.toSet())
refresh()
}
}
@@ -823,7 +807,7 @@ fun CrossProfilePackagesScreen(onNavigateUp: () -> Unit) {
PackageNameTextField(packageName, Modifier.padding(vertical = 8.dp)) { packageName = it }
Button(
{
dpm.setCrossProfilePackages(receiver, packages.map { it.name }.toSet() + packageName)
Privilege.DPM.setCrossProfilePackages(Privilege.DAR, packages.map { it.name }.toSet() + packageName)
packageName = ""
refresh()
},
@@ -841,13 +825,11 @@ fun CrossProfilePackagesScreen(onNavigateUp: () -> Unit) {
@Composable
fun CrossProfileWidgetProvidersScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val packages = remember { mutableStateListOf<AppInfo>() }
fun refresh() {
val pm = context.packageManager
packages.clear()
dpm.getCrossProfileWidgetProviders(receiver).forEach {
Privilege.DPM.getCrossProfileWidgetProviders(Privilege.DAR).forEach {
packages += pm.retrieveAppInfo(it)
}
}
@@ -855,7 +837,7 @@ fun CrossProfileWidgetProvidersScreen(onNavigateUp: () -> Unit) {
MyLazyScaffold(R.string.cross_profile_widget, onNavigateUp) {
items(packages, { it.name }) {
ApplicationItem(it) {
dpm.removeCrossProfileWidgetProvider(receiver, it.name)
Privilege.DPM.removeCrossProfileWidgetProvider(Privilege.DAR, it.name)
refresh()
}
}
@@ -864,7 +846,7 @@ fun CrossProfileWidgetProvidersScreen(onNavigateUp: () -> Unit) {
PackageNameTextField(packageName, Modifier.padding(vertical = 8.dp, horizontal = HorizontalPadding)) { packageName = it }
Button(
{
dpm.addCrossProfileWidgetProvider(receiver, packageName)
Privilege.DPM.addCrossProfileWidgetProvider(Privilege.DAR, packageName)
packageName = ""
refresh()
},
@@ -884,11 +866,10 @@ fun CrossProfileWidgetProvidersScreen(onNavigateUp: () -> Unit) {
fun CredentialManagerPolicyScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val pm = context.packageManager
val dpm = context.getDPM()
var policyType by remember{ mutableIntStateOf(-1) }
val packages = remember { mutableStateListOf<AppInfo>() }
fun refresh() {
val policy = dpm.credentialManagerPolicy
val policy = Privilege.DPM.credentialManagerPolicy
policyType = policy?.policyType ?: -1
packages.clear()
policy?.packageNames?.forEach {
@@ -928,9 +909,9 @@ fun CredentialManagerPolicyScreen(onNavigateUp: () -> Unit) {
{
try {
if(policyType != -1 && packages.isNotEmpty()) {
dpm.credentialManagerPolicy = PackagePolicy(policyType, packages.map { it.name }.toSet())
Privilege.DPM.credentialManagerPolicy = PackagePolicy(policyType, packages.map { it.name }.toSet())
} else {
dpm.credentialManagerPolicy = null
Privilege.DPM.credentialManagerPolicy = null
}
context.showOperationResultToast(true)
} catch(_: IllegalArgumentException) {
@@ -954,13 +935,11 @@ fun CredentialManagerPolicyScreen(onNavigateUp: () -> Unit) {
fun PermittedAccessibilityServicesScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val pm = context.packageManager
val dpm = context.getDPM()
val receiver = context.getReceiver()
val packages = remember { mutableStateListOf<AppInfo>() }
var allowAll by remember { mutableStateOf(true) }
fun refresh() {
packages.clear()
val list = dpm.getPermittedAccessibilityServices(receiver)
val list = Privilege.DPM.getPermittedAccessibilityServices(Privilege.DAR)
allowAll = list == null
list?.forEach {
packages += pm.retrieveAppInfo(it)
@@ -989,7 +968,7 @@ fun PermittedAccessibilityServicesScreen(onNavigateUp: () -> Unit) {
}
Button(
{
val result = dpm.setPermittedAccessibilityServices(receiver, if(allowAll) null else packages.map { it.name })
val result = Privilege.DPM.setPermittedAccessibilityServices(Privilege.DAR, if(allowAll) null else packages.map { it.name })
context.showOperationResultToast(result)
refresh()
},
@@ -1008,13 +987,11 @@ fun PermittedAccessibilityServicesScreen(onNavigateUp: () -> Unit) {
fun PermittedInputMethodsScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val pm = context.packageManager
val dpm = context.getDPM()
val receiver = context.getReceiver()
val packages = remember { mutableStateListOf<AppInfo>() }
var allowAll by remember { mutableStateOf(true) }
fun refresh() {
packages.clear()
val list = dpm.getPermittedInputMethods(receiver)
val list = Privilege.DPM.getPermittedInputMethods(Privilege.DAR)
allowAll = list == null
list?.forEach {
packages += pm.retrieveAppInfo(it)
@@ -1043,7 +1020,7 @@ fun PermittedInputMethodsScreen(onNavigateUp: () -> Unit) {
}
Button(
{
val result = dpm.setPermittedInputMethods(receiver, if(allowAll) null else packages.map { it.name })
val result = Privilege.DPM.setPermittedInputMethods(Privilege.DAR, if(allowAll) null else packages.map { it.name })
context.showOperationResultToast(result)
refresh()
},
@@ -1067,7 +1044,7 @@ fun EnableSystemAppScreen(onNavigateUp: () -> Unit) {
PackageNameTextField(packageName, Modifier.padding(bottom = 8.dp)) { packageName = it }
Button(
{
context.getDPM().enableSystemApp(context.getReceiver(), packageName)
Privilege.DPM.enableSystemApp(Privilege.DAR, packageName)
packageName = ""
context.showOperationResultToast(true)
},
@@ -1094,7 +1071,7 @@ fun SetDefaultDialerScreen(onNavigateUp: () -> Unit) {
Button(
{
try {
context.getDPM().setDefaultDialerApplication(packageName)
Privilege.DPM.setDefaultDialerApplication(packageName)
context.showOperationResultToast(true)
} catch(e: Exception) {
errorMessage = e.message

View File

@@ -7,7 +7,6 @@ import android.app.admin.DevicePolicyManager
import android.app.admin.DnsEvent
import android.app.admin.IDevicePolicyManager
import android.app.admin.SecurityLog
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.IPackageInstaller
@@ -18,12 +17,10 @@ import androidx.annotation.DrawableRes
import androidx.annotation.RequiresApi
import androidx.annotation.StringRes
import androidx.core.content.pm.ShortcutManagerCompat
import com.bintianqi.owndroid.MyAdminComponent
import com.bintianqi.owndroid.Privilege
import com.bintianqi.owndroid.R
import com.bintianqi.owndroid.SharedPrefs
import com.bintianqi.owndroid.SP
import com.bintianqi.owndroid.createShortcuts
import com.bintianqi.owndroid.myPrivilege
import com.bintianqi.owndroid.updatePrivilege
import com.rosan.dhizuku.api.Dhizuku
import com.rosan.dhizuku.api.DhizukuBinderWrapper
import kotlinx.coroutines.flow.MutableStateFlow
@@ -37,24 +34,6 @@ import kotlinx.serialization.json.put
import kotlinx.serialization.json.putJsonArray
import java.io.OutputStream
val Context.isDeviceOwner: Boolean
get() {
val dpm = getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
return dpm.isDeviceOwnerApp(
if(SharedPrefs(this).dhizuku) {
Dhizuku.getOwnerPackageName()
} else {
"com.bintianqi.owndroid"
}
)
}
val Context.isProfileOwner: Boolean
get() {
val dpm = getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
return dpm.isProfileOwnerApp("com.bintianqi.owndroid")
}
@SuppressLint("PrivateApi")
fun binderWrapperDevicePolicyManager(appContext: Context): DevicePolicyManager? {
try {
@@ -69,7 +48,8 @@ fun binderWrapperDevicePolicyManager(appContext: Context): DevicePolicyManager?
val newInterface = IDevicePolicyManager.Stub.asInterface(newBinder)
field[manager] = newInterface
return manager
} catch (_: Exception) {
} catch (e: Exception) {
e.printStackTrace()
dhizukuErrorStatus.value = 1
}
return null
@@ -96,7 +76,7 @@ private fun binderWrapperPackageInstaller(appContext: Context): PackageInstaller
}
fun Context.getPackageInstaller(): PackageInstaller {
if(SharedPrefs(this).dhizuku) {
if(SP.dhizuku) {
if (!dhizukuPermissionGranted()) {
dhizukuErrorStatus.value = 2
return this.packageManager.packageInstaller
@@ -107,26 +87,6 @@ fun Context.getPackageInstaller(): PackageInstaller {
}
}
fun Context.getDPM(): DevicePolicyManager {
if(SharedPrefs(this).dhizuku) {
if (!dhizukuPermissionGranted()) {
dhizukuErrorStatus.value = 2
return this.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
}
return binderWrapperDevicePolicyManager(this) ?: this.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
} else {
return this.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
}
}
fun Context.getReceiver(): ComponentName {
return if(SharedPrefs(this).dhizuku) {
Dhizuku.getOwnerComponent()
} else {
MyAdminComponent
}
}
val dhizukuErrorStatus = MutableStateFlow(0)
data class PermissionItem(
@@ -195,7 +155,7 @@ fun permissionList(): List<PermissionItem>{
@RequiresApi(26)
fun handleNetworkLogs(context: Context, batchToken: Long) {
val networkEvents = context.getDPM().retrieveNetworkLogs(context.getReceiver(), batchToken) ?: return
val networkEvents = Privilege.DPM.retrieveNetworkLogs(Privilege.DAR, batchToken) ?: return
val file = context.filesDir.resolve("NetworkLogs.json")
val fileExist = file.exists()
val json = Json { ignoreUnknownKeys = true; explicitNulls = false }
@@ -452,19 +412,16 @@ fun parseSecurityEventData(event: SecurityLog.SecurityEvent): JsonElement? {
}
}
fun setDefaultAffiliationID(context: Context) {
fun setDefaultAffiliationID() {
if(VERSION.SDK_INT < 26) return
val sp = SharedPrefs(context)
val privilege = myPrivilege.value
if(!sp.isDefaultAffiliationIdSet) {
val privilege = Privilege.status.value
if(!SP.isDefaultAffiliationIdSet) {
try {
if(privilege.device || (!privilege.primary && privilege.profile)) {
val dpm = context.getDPM()
val receiver = context.getReceiver()
val affiliationIDs = dpm.getAffiliationIds(receiver)
val affiliationIDs = Privilege.DPM.getAffiliationIds(Privilege.DAR)
if(affiliationIDs.isEmpty()) {
dpm.setAffiliationIds(receiver, setOf("OwnDroid_default_affiliation_id"))
sp.isDefaultAffiliationIdSet = true
Privilege.DPM.setAffiliationIds(Privilege.DAR, setOf("OwnDroid_default_affiliation_id"))
SP.isDefaultAffiliationIdSet = true
Log.d("DPM", "Default affiliation id set")
}
}
@@ -510,33 +467,18 @@ fun parsePackageInstallerMessage(context: Context, result: Intent): String {
fun handlePrivilegeChange(context: Context) {
val privilege = myPrivilege.value
val activated = privilege.device || privilege.profile
val sp = SharedPrefs(context)
sp.dhizukuServer = false
if(activated) {
val privilege = Privilege.status.value
SP.dhizukuServer = false
if (privilege.activated) {
createShortcuts(context)
if(!privilege.dhizuku) {
setDefaultAffiliationID(context)
if (!privilege.dhizuku) {
setDefaultAffiliationID()
}
} else {
sp.isDefaultAffiliationIdSet = false
SP.isDefaultAffiliationIdSet = false
if(VERSION.SDK_INT >= 25) {
ShortcutManagerCompat.removeAllDynamicShortcuts(context)
}
sp.isApiEnabled = false
SP.isApiEnabled = false
}
}
fun checkPrivilege(context: Context) {
val sp = SharedPrefs(context)
if (sp.dhizuku) {
if (Dhizuku.init(context)) {
if (!dhizukuPermissionGranted()) { dhizukuErrorStatus.value = 2 }
} else {
sp.dhizuku = false
dhizukuErrorStatus.value = 1
}
}
updatePrivilege(context)
}

View File

@@ -129,11 +129,11 @@ import androidx.core.os.bundleOf
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.bintianqi.owndroid.ChoosePackageContract
import com.bintianqi.owndroid.HorizontalPadding
import com.bintianqi.owndroid.Privilege
import com.bintianqi.owndroid.R
import com.bintianqi.owndroid.formatDate
import com.bintianqi.owndroid.formatFileSize
import com.bintianqi.owndroid.humanReadableDate
import com.bintianqi.owndroid.myPrivilege
import com.bintianqi.owndroid.popToast
import com.bintianqi.owndroid.showOperationResultToast
import com.bintianqi.owndroid.ui.CheckBoxItem
@@ -166,7 +166,7 @@ import kotlin.reflect.jvm.jvmErasure
@Composable
fun NetworkScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
val privilege by myPrivilege.collectAsStateWithLifecycle()
val privilege by Privilege.status.collectAsStateWithLifecycle()
MyScaffold(R.string.network, onNavigateUp, 0.dp) {
if(!privilege.dhizuku) FunctionItem(R.string.wifi, icon = R.drawable.wifi_fill0) { onNavigate(WiFi) }
if(VERSION.SDK_INT >= 30) {
@@ -202,15 +202,13 @@ fun NetworkScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
@Composable
fun NetworkOptionsScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val privilege by myPrivilege.collectAsStateWithLifecycle()
val privilege by Privilege.status.collectAsStateWithLifecycle()
var dialog by remember { mutableIntStateOf(0) }
MyScaffold(R.string.options, onNavigateUp, 0.dp) {
if(VERSION.SDK_INT >= 30 && (privilege.device || privilege.org)) {
SwitchItem(R.string.lockdown_admin_configured_network, icon = R.drawable.wifi_password_fill0,
getState = { dpm.hasLockdownAdminConfiguredNetworks(receiver) }, onCheckedChange = { dpm.setConfiguredNetworksLockdownState(receiver,it) },
getState = { Privilege.DPM.hasLockdownAdminConfiguredNetworks(Privilege.DAR) },
onCheckedChange = { Privilege.DPM.setConfiguredNetworksLockdownState(Privilege.DAR, it) },
onClickBlank = { dialog = 1 }
)
}
@@ -265,7 +263,7 @@ fun WifiScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit, onNavigateTo
HorizontalPager(state = pagerState, verticalAlignment = Alignment.Top) { page ->
if(page == 0) {
val wm = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
val privilege by myPrivilege.collectAsStateWithLifecycle()
val privilege by Privilege.status.collectAsStateWithLifecycle()
@Suppress("DEPRECATION") Column(
modifier = Modifier.fillMaxSize().padding(top = 12.dp)
) {
@@ -313,13 +311,11 @@ fun WifiScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit, onNavigateTo
}
}
if(wifiMacDialog && VERSION.SDK_INT >= 24) {
val dpm = context.getDPM()
val receiver = context.getReceiver()
AlertDialog(
onDismissRequest = { wifiMacDialog = false },
confirmButton = { TextButton(onClick = { wifiMacDialog = false }) { Text(stringResource(R.string.confirm)) } },
text = {
val mac = dpm.getWifiMacAddress(receiver)
val mac = Privilege.DPM.getWifiMacAddress(Privilege.DAR)
OutlinedTextField(
value = mac ?: stringResource(R.string.none), label = { Text(stringResource(R.string.wifi_mac_address)) },
onValueChange = {}, readOnly = true, modifier = Modifier.fillMaxWidth(), textStyle = typography.bodyLarge,
@@ -763,9 +759,8 @@ private fun AddNetworkScreen(wifiConfig: WifiConfiguration? = null, onNavigateUp
@Composable
fun WifiSecurityLevelScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
var selectedWifiSecLevel by remember { mutableIntStateOf(0) }
LaunchedEffect(Unit) { selectedWifiSecLevel = dpm.minimumRequiredWifiSecurityLevel }
LaunchedEffect(Unit) { selectedWifiSecLevel = Privilege.DPM.minimumRequiredWifiSecurityLevel }
MyScaffold(R.string.min_wifi_security_level, onNavigateUp, 0.dp) {
FullWidthRadioButtonItem(R.string.wifi_security_open, selectedWifiSecLevel == WIFI_SECURITY_OPEN) { selectedWifiSecLevel = WIFI_SECURITY_OPEN }
FullWidthRadioButtonItem("WEP, WPA(2)-PSK", selectedWifiSecLevel == WIFI_SECURITY_PERSONAL) { selectedWifiSecLevel = WIFI_SECURITY_PERSONAL }
@@ -773,7 +768,7 @@ fun WifiSecurityLevelScreen(onNavigateUp: () -> Unit) {
FullWidthRadioButtonItem("WPA3-192bit", selectedWifiSecLevel == WIFI_SECURITY_ENTERPRISE_192) { selectedWifiSecLevel = WIFI_SECURITY_ENTERPRISE_192 }
Button(
onClick = {
dpm.minimumRequiredWifiSecurityLevel = selectedWifiSecLevel
Privilege.DPM.minimumRequiredWifiSecurityLevel = selectedWifiSecLevel
context.showOperationResultToast(true)
},
modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp, horizontal = HorizontalPadding)
@@ -790,13 +785,12 @@ fun WifiSecurityLevelScreen(onNavigateUp: () -> Unit) {
@Composable
fun WifiSsidPolicyScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val focusMgr = LocalFocusManager.current
MyScaffold(R.string.wifi_ssid_policy, onNavigateUp, 0.dp) {
var selectedPolicyType by remember { mutableIntStateOf(-1) }
val ssidList = remember { mutableStateListOf<WifiSsid>() }
fun refreshPolicy() {
val policy = dpm.wifiSsidPolicy
val policy = Privilege.DPM.wifiSsidPolicy
ssidList.clear()
selectedPolicyType = policy?.policyType ?: -1
ssidList.addAll(policy?.ssids ?: mutableSetOf())
@@ -842,7 +836,7 @@ fun WifiSsidPolicyScreen(onNavigateUp: () -> Unit) {
Button(
onClick = {
focusMgr.clearFocus()
dpm.wifiSsidPolicy = if(selectedPolicyType == -1 || ssidList.isEmpty()) {
Privilege.DPM.wifiSsidPolicy = if(selectedPolicyType == -1 || ssidList.isEmpty()) {
null
} else {
WifiSsidPolicy(selectedPolicyType, ssidList.toSet())
@@ -894,7 +888,7 @@ fun NetworkStats.toBucketList(): List<NetworkStats.Bucket> {
@Composable
fun NetworkStatsScreen(onNavigateUp: () -> Unit, onNavigateToViewer: (NetworkStatsViewer) -> Unit) {
val context = LocalContext.current
val privilege by myPrivilege.collectAsStateWithLifecycle()
val privilege by Privilege.status.collectAsStateWithLifecycle()
val fm = LocalFocusManager.current
val nsm = context.getSystemService(NetworkStatsManager::class.java)
val coroutine = rememberCoroutineScope()
@@ -1392,8 +1386,6 @@ fun NetworkStatsViewerScreen(nsv: NetworkStatsViewer, onNavigateUp: () -> Unit)
@Composable
fun PrivateDnsScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val focusMgr = LocalFocusManager.current
MyScaffold(R.string.private_dns, onNavigateUp) {
fun getDnsStatus(code: Int) = when (code) {
@@ -1409,16 +1401,16 @@ fun PrivateDnsScreen(onNavigateUp: () -> Unit) {
PRIVATE_DNS_SET_ERROR_FAILURE_SETTING -> R.string.failed
else -> R.string.place_holder
}
var dnsMode by remember { mutableIntStateOf(dpm.getGlobalPrivateDnsMode(receiver)) }
var dnsMode by remember { mutableIntStateOf(Privilege.DPM.getGlobalPrivateDnsMode(Privilege.DAR)) }
Spacer(Modifier.padding(vertical = 5.dp))
Text(stringResource(R.string.current_state, stringResource(getDnsStatus(dnsMode))))
AnimatedVisibility(visible = dpm.getGlobalPrivateDnsMode(receiver)!=PRIVATE_DNS_MODE_OPPORTUNISTIC) {
AnimatedVisibility(Privilege.DPM.getGlobalPrivateDnsMode(Privilege.DAR) != PRIVATE_DNS_MODE_OPPORTUNISTIC) {
Spacer(Modifier.padding(vertical = 5.dp))
Button(
onClick = {
val result = dpm.setGlobalPrivateDnsModeOpportunistic(receiver)
val result = Privilege.DPM.setGlobalPrivateDnsModeOpportunistic(Privilege.DAR)
context.popToast(getOperationResult(result))
dnsMode = dpm.getGlobalPrivateDnsMode(receiver)
dnsMode = Privilege.DPM.getGlobalPrivateDnsMode(Privilege.DAR)
},
modifier = Modifier.fillMaxWidth()
) {
@@ -1427,7 +1419,7 @@ fun PrivateDnsScreen(onNavigateUp: () -> Unit) {
}
Notes(R.string.info_private_dns_mode_oppertunistic)
Spacer(Modifier.padding(vertical = 10.dp))
var inputHost by remember { mutableStateOf(dpm.getGlobalPrivateDnsHost(receiver) ?: "") }
var inputHost by remember { mutableStateOf(Privilege.DPM.getGlobalPrivateDnsHost(Privilege.DAR) ?: "") }
OutlinedTextField(
value = inputHost,
onValueChange = { inputHost=it },
@@ -1441,7 +1433,7 @@ fun PrivateDnsScreen(onNavigateUp: () -> Unit) {
onClick = {
focusMgr.clearFocus()
try {
val result = dpm.setGlobalPrivateDnsModeSpecifiedHost(receiver,inputHost)
val result = Privilege.DPM.setGlobalPrivateDnsModeSpecifiedHost(Privilege.DAR, inputHost)
context.popToast(getOperationResult(result))
} catch(e: IllegalArgumentException) {
e.printStackTrace()
@@ -1450,7 +1442,7 @@ fun PrivateDnsScreen(onNavigateUp: () -> Unit) {
e.printStackTrace()
context.popToast(R.string.security_exception)
} finally {
dnsMode = dpm.getGlobalPrivateDnsMode(receiver)
dnsMode = Privilege.DPM.getGlobalPrivateDnsMode(Privilege.DAR)
}
},
modifier = Modifier.fillMaxWidth()
@@ -1467,19 +1459,17 @@ fun PrivateDnsScreen(onNavigateUp: () -> Unit) {
@Composable
fun AlwaysOnVpnPackageScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
var lockdown by rememberSaveable { mutableStateOf(false) }
var pkgName by rememberSaveable { mutableStateOf("") }
val focusMgr = LocalFocusManager.current
val refresh = { pkgName = dpm.getAlwaysOnVpnPackage(receiver) ?: "" }
val refresh = { pkgName = Privilege.DPM.getAlwaysOnVpnPackage(Privilege.DAR) ?: "" }
LaunchedEffect(Unit) { refresh() }
val choosePackage = rememberLauncherForActivityResult(ChoosePackageContract()) { result ->
result?.let { pkgName = it }
}
val setAlwaysOnVpn: (String?, Boolean)->Boolean = { vpnPkg: String?, lockdownEnabled: Boolean ->
try {
dpm.setAlwaysOnVpnPackage(receiver, vpnPkg, lockdownEnabled)
Privilege.DPM.setAlwaysOnVpnPackage(Privilege.DAR, vpnPkg, lockdownEnabled)
context.showOperationResultToast(true)
true
} catch(e: UnsupportedOperationException) {
@@ -1532,8 +1522,6 @@ fun AlwaysOnVpnPackageScreen(onNavigateUp: () -> Unit) {
@Composable
fun RecommendedGlobalProxyScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val focusMgr = LocalFocusManager.current
var proxyType by remember { mutableIntStateOf(0) }
var proxyUri by remember { mutableStateOf("") }
@@ -1584,7 +1572,7 @@ fun RecommendedGlobalProxyScreen(onNavigateUp: () -> Unit) {
Button(
onClick = {
if(proxyType == 0) {
dpm.setRecommendedGlobalProxy(receiver, null)
Privilege.DPM.setRecommendedGlobalProxy(Privilege.DAR, null)
context.showOperationResultToast(true)
return@Button
}
@@ -1615,7 +1603,7 @@ fun RecommendedGlobalProxyScreen(onNavigateUp: () -> Unit) {
context.popToast(R.string.invalid_config)
return@Button
}
dpm.setRecommendedGlobalProxy(receiver, proxyInfo)
Privilege.DPM.setRecommendedGlobalProxy(Privilege.DAR, proxyInfo)
context.showOperationResultToast(true)
},
modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp)
@@ -1632,8 +1620,6 @@ fun RecommendedGlobalProxyScreen(onNavigateUp: () -> Unit) {
@Composable
fun NetworkLoggingScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val logFile = context.filesDir.resolve("NetworkLogs.json")
var fileSize by remember { mutableLongStateOf(0) }
LaunchedEffect(Unit) { fileSize = logFile.length() }
@@ -1648,8 +1634,8 @@ fun NetworkLoggingScreen(onNavigateUp: () -> Unit) {
MyScaffold(R.string.network_logging, onNavigateUp) {
SwitchItem(
R.string.enable,
getState = { dpm.isNetworkLoggingEnabled(receiver) },
onCheckedChange = { dpm.setNetworkLoggingEnabled(receiver,it) },
getState = { Privilege.DPM.isNetworkLoggingEnabled(Privilege.DAR) },
onCheckedChange = { Privilege.DPM.setNetworkLoggingEnabled(Privilege.DAR, it) },
padding = false
)
Text(stringResource(R.string.log_file_size_is, formatFileSize(fileSize)))
@@ -1684,7 +1670,6 @@ fun NetworkLoggingScreen(onNavigateUp: () -> Unit) {
@Composable
fun WifiAuthKeypairScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val focusMgr = LocalFocusManager.current
var keyPair by remember { mutableStateOf("") }
MyScaffold(R.string.wifi_auth_keypair, onNavigateUp) {
@@ -1698,7 +1683,7 @@ fun WifiAuthKeypairScreen(onNavigateUp: () -> Unit) {
)
Spacer(Modifier.padding(vertical = 5.dp))
val isExist = try {
dpm.isKeyPairGrantedToWifiAuth(keyPair)
Privilege.DPM.isKeyPairGrantedToWifiAuth(keyPair)
} catch(e: java.lang.IllegalArgumentException) {
e.printStackTrace()
false
@@ -1707,13 +1692,13 @@ fun WifiAuthKeypairScreen(onNavigateUp: () -> Unit) {
Spacer(Modifier.padding(vertical = 5.dp))
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
Button(
onClick = { context.showOperationResultToast(dpm.grantKeyPairToWifiAuth(keyPair)) },
onClick = { context.showOperationResultToast(Privilege.DPM.grantKeyPairToWifiAuth(keyPair)) },
modifier = Modifier.fillMaxWidth(0.49F)
) {
Text(stringResource(R.string.grant))
}
Button(
onClick = { context.showOperationResultToast(dpm.revokeKeyPairFromWifiAuth(keyPair)) },
onClick = { context.showOperationResultToast(Privilege.DPM.revokeKeyPairFromWifiAuth(keyPair)) },
modifier = Modifier.fillMaxWidth(0.96F)
) {
Text(stringResource(R.string.revoke))
@@ -1727,19 +1712,17 @@ fun WifiAuthKeypairScreen(onNavigateUp: () -> Unit) {
@RequiresApi(33)
@Composable
fun PreferentialNetworkServiceScreen(onNavigateUp: () -> Unit, onNavigate: (AddPreferentialNetworkServiceConfig) -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
var masterEnabled by remember { mutableStateOf(false) }
val configs = remember { mutableStateListOf<PreferentialNetworkServiceConfig>() }
fun refresh() {
masterEnabled = dpm.isPreferentialNetworkServiceEnabled
masterEnabled = Privilege.DPM.isPreferentialNetworkServiceEnabled
configs.clear()
configs.addAll(dpm.preferentialNetworkServiceConfigs)
configs.addAll(Privilege.DPM.preferentialNetworkServiceConfigs)
}
LaunchedEffect(Unit) { refresh() }
MySmallTitleScaffold(R.string.preferential_network_service, onNavigateUp, 0.dp) {
SwitchItem(R.string.enabled, state = masterEnabled, onCheckedChange = {
dpm.isPreferentialNetworkServiceEnabled = it
Privilege.DPM.isPreferentialNetworkServiceEnabled = it
refresh()
})
Spacer(Modifier.padding(vertical = 4.dp))
@@ -1794,7 +1777,6 @@ fun PreferentialNetworkServiceScreen(onNavigateUp: () -> Unit, onNavigate: (AddP
fun AddPreferentialNetworkServiceConfigScreen(route: AddPreferentialNetworkServiceConfig,onNavigateUp: () -> Unit) {
val updateMode = route.index != -1
val context = LocalContext.current
val dpm = context.getDPM()
var enabled by remember { mutableStateOf(route.enabled) }
var id by remember { mutableIntStateOf(route.id) }
var allowFallback by remember { mutableStateOf(route.allowFallback) }
@@ -1854,10 +1836,10 @@ fun AddPreferentialNetworkServiceConfigScreen(route: AddPreferentialNetworkServi
setIncludedUids(includedUids.lines().filter { it.isNotBlank() }.map { it.toInt() }.toIntArray())
if(VERSION.SDK_INT >= 34) setShouldBlockNonMatchingNetworks(blockNonMatching)
}.build()
val configs = dpm.preferentialNetworkServiceConfigs
val configs = Privilege.DPM.preferentialNetworkServiceConfigs
if(updateMode) configs[route.index] = config
else configs += config
dpm.preferentialNetworkServiceConfigs = configs
Privilege.DPM.preferentialNetworkServiceConfigs = configs
onNavigateUp()
} catch(e: Exception) {
context.showOperationResultToast(false)
@@ -1872,7 +1854,7 @@ fun AddPreferentialNetworkServiceConfigScreen(route: AddPreferentialNetworkServi
if(updateMode) Button(
onClick = {
try {
dpm.preferentialNetworkServiceConfigs = dpm.preferentialNetworkServiceConfigs.drop(route.index)
Privilege.DPM.preferentialNetworkServiceConfigs = Privilege.DPM.preferentialNetworkServiceConfigs.drop(route.index)
onNavigateUp()
} catch(e: Exception) {
context.showOperationResultToast(false)
@@ -1892,22 +1874,19 @@ fun AddPreferentialNetworkServiceConfigScreen(route: AddPreferentialNetworkServi
@RequiresApi(28)
@Composable
fun OverrideApnScreen(onNavigateUp: () -> Unit, onNavigateToAddSetting: (Bundle) -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
var enabled by remember { mutableStateOf(false) }
val settings = remember { mutableStateListOf<ApnSetting>() }
fun refresh() {
enabled = dpm.isOverrideApnEnabled(receiver)
enabled = Privilege.DPM.isOverrideApnEnabled(Privilege.DAR)
settings.clear()
settings.addAll(dpm.getOverrideApns(receiver))
settings.addAll(Privilege.DPM.getOverrideApns(Privilege.DAR))
}
LaunchedEffect(Unit) { refresh() }
MyScaffold(R.string.override_apn, onNavigateUp, 0.dp) {
SwitchItem(
R.string.enable, state = enabled,
onCheckedChange = {
dpm.setOverrideApnsEnabled(receiver, it)
Privilege.DPM.setOverrideApnsEnabled(Privilege.DAR, it)
refresh()
}
)
@@ -1957,9 +1936,6 @@ private val apnTypes = listOf(
@RequiresApi(28)
@Composable
fun AddApnSettingScreen(origin: ApnSetting?, onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val fm = LocalFocusManager.current
var dropdown by remember { mutableIntStateOf(0) } // 1:Auth type, 2:MVNO type, 3:Protocol, 4:Roaming protocol
var dialog by remember { mutableIntStateOf(0) } // 1:Proxy, 2:MMS proxy
@@ -2204,9 +2180,9 @@ fun AddApnSettingScreen(origin: ApnSetting?, onNavigateUp: () -> Unit) {
if(VERSION.SDK_INT >= 35) setAlwaysOn(alwaysOn)
}.build()
if(origin == null) {
dpm.addOverrideApn(receiver, setting)
Privilege.DPM.addOverrideApn(Privilege.DAR, setting)
} else {
dpm.updateOverrideApn(receiver, origin.id, setting)
Privilege.DPM.updateOverrideApn(Privilege.DAR, origin.id, setting)
}
onNavigateUp()
} catch(e: Exception) {
@@ -2219,7 +2195,7 @@ fun AddApnSettingScreen(origin: ApnSetting?, onNavigateUp: () -> Unit) {
}
if(origin != null) Button(
{
dpm.removeOverrideApn(receiver, origin.id)
Privilege.DPM.removeOverrideApn(Privilege.DAR, origin.id)
onNavigateUp()
},
Modifier.fillMaxWidth(),

View File

@@ -66,9 +66,9 @@ import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat.startActivity
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.bintianqi.owndroid.HorizontalPadding
import com.bintianqi.owndroid.Privilege
import com.bintianqi.owndroid.R
import com.bintianqi.owndroid.SharedPrefs
import com.bintianqi.owndroid.myPrivilege
import com.bintianqi.owndroid.SP
import com.bintianqi.owndroid.popToast
import com.bintianqi.owndroid.showOperationResultToast
import com.bintianqi.owndroid.ui.CheckBoxItem
@@ -88,11 +88,11 @@ import kotlinx.serialization.Serializable
@Composable
fun PasswordScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
val context = LocalContext.current
val privilege by myPrivilege.collectAsStateWithLifecycle()
val privilege by Privilege.status.collectAsStateWithLifecycle()
var dialog by remember { mutableIntStateOf(0) }
MyScaffold(R.string.password_and_keyguard, onNavigateUp, 0.dp) {
FunctionItem(R.string.password_info, icon = R.drawable.info_fill0) { onNavigate(PasswordInfo) }
if(SharedPrefs(context).displayDangerousFeatures) {
if(SP.displayDangerousFeatures) {
if(VERSION.SDK_INT >= 26) {
FunctionItem(R.string.reset_password_token, icon = R.drawable.key_vertical_fill0) { onNavigate(ResetPasswordToken) }
}
@@ -116,16 +116,14 @@ fun PasswordScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
}
}
if(dialog != 0) {
val dpm = context.getDPM()
val receiver = context.getReceiver()
var input by remember { mutableStateOf("") }
LaunchedEffect(Unit) {
input = when(dialog) {
1 -> dpm.getMaximumTimeToLock(receiver).toString()
2 -> dpm.getRequiredStrongAuthTimeout(receiver).toString()
3 -> dpm.getPasswordExpirationTimeout(receiver).toString()
4 -> dpm.getMaximumFailedPasswordsForWipe(receiver).toString()
5 -> dpm.getPasswordHistoryLength(receiver).toString()
1 -> Privilege.DPM.getMaximumTimeToLock(Privilege.DAR).toString()
2 -> Privilege.DPM.getRequiredStrongAuthTimeout(Privilege.DAR).toString()
3 -> Privilege.DPM.getPasswordExpirationTimeout(Privilege.DAR).toString()
4 -> Privilege.DPM.getMaximumFailedPasswordsForWipe(Privilege.DAR).toString()
5 -> Privilege.DPM.getPasswordHistoryLength(Privilege.DAR).toString()
else -> ""
}
}
@@ -180,11 +178,11 @@ fun PasswordScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
TextButton(
onClick = {
when(dialog) {
1 -> dpm.setMaximumTimeToLock(receiver, input.toLong())
2 -> dpm.setRequiredStrongAuthTimeout(receiver, input.toLong())
3 -> dpm.setPasswordExpirationTimeout(receiver, input.toLong())
4 -> dpm.setMaximumFailedPasswordsForWipe(receiver, input.toInt())
5 -> dpm.setPasswordHistoryLength(receiver, input.toInt())
1 -> Privilege.DPM.setMaximumTimeToLock(Privilege.DAR, input.toLong())
2 -> Privilege.DPM.setRequiredStrongAuthTimeout(Privilege.DAR, input.toLong())
3 -> Privilege.DPM.setPasswordExpirationTimeout(Privilege.DAR, input.toLong())
4 -> Privilege.DPM.setMaximumFailedPasswordsForWipe(Privilege.DAR, input.toInt())
5 -> Privilege.DPM.setPasswordHistoryLength(Privilege.DAR, input.toInt())
}
dialog = 0
}
@@ -208,14 +206,11 @@ fun PasswordScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
@Composable
fun PasswordInfoScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val privilege by myPrivilege.collectAsStateWithLifecycle()
val privilege by Privilege.status.collectAsStateWithLifecycle()
var dialog by remember { mutableIntStateOf(0) } // 0:none, 1:password complexity
MyScaffold(R.string.password_info, onNavigateUp, 0.dp) {
if(VERSION.SDK_INT >= 29) {
val text = when(dpm.passwordComplexity) {
val text = when(Privilege.DPM.passwordComplexity) {
PASSWORD_COMPLEXITY_NONE -> R.string.none
PASSWORD_COMPLEXITY_LOW -> R.string.low
PASSWORD_COMPLEXITY_MEDIUM -> R.string.medium
@@ -224,9 +219,9 @@ fun PasswordInfoScreen(onNavigateUp: () -> Unit) {
}
InfoItem(R.string.current_password_complexity, text, true) { dialog = 1 }
}
InfoItem(R.string.password_sufficient, dpm.isActivePasswordSufficient.yesOrNo)
InfoItem(R.string.password_sufficient, Privilege.DPM.isActivePasswordSufficient.yesOrNo)
if(VERSION.SDK_INT >= 28 && privilege.work) {
InfoItem(R.string.unified_password, dpm.isUsingUnifiedPassword(receiver).yesOrNo)
InfoItem(R.string.unified_password, Privilege.DPM.isUsingUnifiedPassword(Privilege.DAR).yesOrNo)
}
}
if(dialog != 0) AlertDialog(
@@ -246,8 +241,6 @@ fun PasswordInfoScreen(onNavigateUp: () -> Unit) {
@Composable
fun ResetPasswordTokenScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
var token by remember { mutableStateOf("") }
val tokenByteArray = token.toByteArray()
val focusMgr = LocalFocusManager.current
@@ -267,7 +260,7 @@ fun ResetPasswordTokenScreen(onNavigateUp: () -> Unit) {
Button(
onClick = {
try {
context.showOperationResultToast(dpm.setResetPasswordToken(receiver, tokenByteArray))
context.showOperationResultToast(Privilege.DPM.setResetPasswordToken(Privilege.DAR, tokenByteArray))
} catch(_:SecurityException) {
context.popToast(R.string.security_exception)
}
@@ -283,7 +276,7 @@ fun ResetPasswordTokenScreen(onNavigateUp: () -> Unit) {
) {
Button(
onClick = {
if(!dpm.isResetPasswordTokenActive(receiver)) {
if(!Privilege.DPM.isResetPasswordTokenActive(Privilege.DAR)) {
try { activateToken(context) }
catch(_:NullPointerException) { context.popToast(R.string.please_set_a_token) }
} else { context.popToast(R.string.token_already_activated) }
@@ -293,7 +286,7 @@ fun ResetPasswordTokenScreen(onNavigateUp: () -> Unit) {
Text(stringResource(R.string.activate))
}
Button(
onClick = { context.showOperationResultToast(dpm.clearResetPasswordToken(receiver)) },
onClick = { context.showOperationResultToast(Privilege.DPM.clearResetPasswordToken(Privilege.DAR)) },
modifier = Modifier.fillMaxWidth(0.96F)
) {
Text(stringResource(R.string.clear))
@@ -309,8 +302,6 @@ fun ResetPasswordTokenScreen(onNavigateUp: () -> Unit) {
@Composable
fun ResetPasswordScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val focusMgr = LocalFocusManager.current
var password by remember { mutableStateOf("") }
var useToken by remember { mutableStateOf(false) }
@@ -401,9 +392,9 @@ fun ResetPasswordScreen(onNavigateUp: () -> Unit) {
TextButton(
onClick = {
val success = if(VERSION.SDK_INT >= 26 && useToken) {
dpm.resetPasswordWithToken(receiver, password, tokenByteArray, flag)
Privilege.DPM.resetPasswordWithToken(Privilege.DAR, password, tokenByteArray, flag)
} else {
dpm.resetPassword(password, flag)
Privilege.DPM.resetPassword(password, flag)
}
context.showOperationResultToast(success)
password = ""
@@ -430,7 +421,6 @@ fun ResetPasswordScreen(onNavigateUp: () -> Unit) {
@Composable
fun RequiredPasswordComplexityScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val passwordComplexity = mapOf(
PASSWORD_COMPLEXITY_NONE to R.string.none,
PASSWORD_COMPLEXITY_LOW to R.string.low,
@@ -438,7 +428,7 @@ fun RequiredPasswordComplexityScreen(onNavigateUp: () -> Unit) {
PASSWORD_COMPLEXITY_HIGH to R.string.high
)
var selectedItem by remember { mutableIntStateOf(PASSWORD_COMPLEXITY_NONE) }
LaunchedEffect(Unit) { selectedItem = dpm.requiredPasswordComplexity }
LaunchedEffect(Unit) { selectedItem = Privilege.DPM.requiredPasswordComplexity }
MyScaffold(R.string.required_password_complexity, onNavigateUp, 0.dp) {
passwordComplexity.forEach {
FullWidthRadioButtonItem(it.value, selectedItem == it.key) { selectedItem = it.key }
@@ -446,8 +436,8 @@ fun RequiredPasswordComplexityScreen(onNavigateUp: () -> Unit) {
Spacer(Modifier.padding(vertical = 5.dp))
Button(
onClick = {
dpm.requiredPasswordComplexity = selectedItem
selectedItem = dpm.requiredPasswordComplexity
Privilege.DPM.requiredPasswordComplexity = selectedItem
selectedItem = Privilege.DPM.requiredPasswordComplexity
context.showOperationResultToast(true)
},
modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp, horizontal = HorizontalPadding)
@@ -463,8 +453,6 @@ fun RequiredPasswordComplexityScreen(onNavigateUp: () -> Unit) {
@Composable
fun KeyguardDisabledFeaturesScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
var flag by remember { mutableIntStateOf(0) }
var mode by remember { mutableIntStateOf(0) } // 0:Enable all, 1:Disable all, 2:Custom
val flagsLiat = mutableListOf(
@@ -482,14 +470,14 @@ fun KeyguardDisabledFeaturesScreen(onNavigateUp: () -> Unit) {
}
if(VERSION.SDK_INT >= 34) flagsLiat += R.string.disable_keyguard_features_shortcuts to KEYGUARD_DISABLE_SHORTCUTS_ALL
fun refresh() {
flag = dpm.getKeyguardDisabledFeatures(receiver)
flag = Privilege.DPM.getKeyguardDisabledFeatures(Privilege.DAR)
mode = when(flag) {
KEYGUARD_DISABLE_FEATURES_NONE -> 0
KEYGUARD_DISABLE_FEATURES_ALL -> 1
else -> 2
}
}
LaunchedEffect(mode) { if(mode != 2) flag = dpm.getKeyguardDisabledFeatures(receiver) }
LaunchedEffect(mode) { if(mode != 2) flag = Privilege.DPM.getKeyguardDisabledFeatures(Privilege.DAR) }
LaunchedEffect(Unit) { refresh() }
MyScaffold(R.string.disable_keyguard_features, onNavigateUp) {
FullWidthRadioButtonItem(R.string.enable_all, mode == 0) { mode = 0 }
@@ -507,7 +495,7 @@ fun KeyguardDisabledFeaturesScreen(onNavigateUp: () -> Unit) {
Button(
onClick = {
val disabledFeatures = if(mode == 0) KEYGUARD_DISABLE_FEATURES_NONE else if(mode == 1) KEYGUARD_DISABLE_FEATURES_ALL else flag
dpm.setKeyguardDisabledFeatures(receiver, disabledFeatures)
Privilege.DPM.setKeyguardDisabledFeatures(Privilege.DAR, disabledFeatures)
refresh()
context.showOperationResultToast(true)
},
@@ -523,8 +511,6 @@ fun KeyguardDisabledFeaturesScreen(onNavigateUp: () -> Unit) {
@Composable
fun RequiredPasswordQualityScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val passwordQuality = mapOf(
PASSWORD_QUALITY_UNSPECIFIED to R.string.password_quality_unspecified,
PASSWORD_QUALITY_SOMETHING to R.string.password_quality_something,
@@ -535,7 +521,7 @@ fun RequiredPasswordQualityScreen(onNavigateUp: () -> Unit) {
PASSWORD_QUALITY_NUMERIC_COMPLEX to R.string.password_quality_numeric_complex
)
var selectedItem by remember { mutableIntStateOf(PASSWORD_QUALITY_UNSPECIFIED) }
LaunchedEffect(Unit) { selectedItem=dpm.getPasswordQuality(receiver) }
LaunchedEffect(Unit) { selectedItem = Privilege.DPM.getPasswordQuality(Privilege.DAR) }
MyScaffold(R.string.required_password_quality, onNavigateUp) {
passwordQuality.forEach {
RadioButtonItem(it.value, selectedItem == it.key) { selectedItem = it.key }
@@ -543,7 +529,7 @@ fun RequiredPasswordQualityScreen(onNavigateUp: () -> Unit) {
Spacer(Modifier.padding(vertical = 5.dp))
Button(
onClick = {
dpm.setPasswordQuality(receiver,selectedItem)
Privilege.DPM.setPasswordQuality(Privilege.DAR, selectedItem)
context.showOperationResultToast(true)
},
modifier = Modifier.fillMaxWidth()
@@ -558,7 +544,7 @@ private fun activateToken(context: Context) {
val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
val confirmIntent = keyguardManager.createConfirmDeviceCredentialIntent(context.getString(R.string.app_name), desc)
if (confirmIntent != null) {
startActivity(context,confirmIntent, null)
startActivity(context, confirmIntent, null)
} else {
context.showOperationResultToast(false)
}

View File

@@ -94,10 +94,10 @@ import com.bintianqi.owndroid.DhizukuPermissions
import com.bintianqi.owndroid.HorizontalPadding
import com.bintianqi.owndroid.IUserService
import com.bintianqi.owndroid.MyAdminComponent
import com.bintianqi.owndroid.Privilege
import com.bintianqi.owndroid.R
import com.bintianqi.owndroid.SP
import com.bintianqi.owndroid.Settings
import com.bintianqi.owndroid.SharedPrefs
import com.bintianqi.owndroid.myPrivilege
import com.bintianqi.owndroid.showOperationResultToast
import com.bintianqi.owndroid.ui.CircularProgressDialog
import com.bintianqi.owndroid.ui.InfoItem
@@ -107,7 +107,6 @@ import com.bintianqi.owndroid.ui.MySmallTitleScaffold
import com.bintianqi.owndroid.ui.NavIcon
import com.bintianqi.owndroid.ui.Notes
import com.bintianqi.owndroid.ui.SwitchItem
import com.bintianqi.owndroid.updatePrivilege
import com.bintianqi.owndroid.useShizuku
import com.bintianqi.owndroid.yesOrNo
import com.google.accompanist.drawablepainter.rememberDrawablePainter
@@ -129,13 +128,17 @@ fun WorkModesScreen(
) {
val context = LocalContext.current
val coroutine = rememberCoroutineScope()
val privilege by myPrivilege.collectAsStateWithLifecycle()
val privilege by Privilege.status.collectAsStateWithLifecycle()
/** 0: none, 1: device owner, 2: circular progress indicator, 3: result, 4: deactivate, 5: command */
var dialog by remember { mutableIntStateOf(0) }
var operationSucceed by remember { mutableStateOf(false) }
LaunchedEffect(privilege) {
if (!params.canNavigateUp && privilege.device) {
delay(1000)
if (dialog != 3) dialog = 3 // Activated by ADB command
if (dialog != 3) { // Activated by ADB command
operationSucceed = true
dialog = 3
}
}
}
Scaffold(
@@ -194,15 +197,13 @@ fun WorkModesScreen(
contentWindowInsets = WindowInsets.ime
) { paddingValues ->
var navigateUpOnSucceed by remember { mutableStateOf(true) }
var operationSucceed by remember { mutableStateOf(false) }
var resultText by remember { mutableStateOf("") }
fun handleResult(succeeded: Boolean, activateSucceeded: Boolean, output: String?) {
if(succeeded) {
operationSucceed = activateSucceeded
resultText = output ?: ""
dialog = 3
updatePrivilege(context)
handlePrivilegeChange(context)
Privilege.updateStatus()
} else {
dialog = 0
context.showOperationResultToast(false)
@@ -261,7 +262,7 @@ fun WorkModesScreen(
}
if(
privilege.work || (VERSION.SDK_INT < 24 ||
context.getDPM().isProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE))
Privilege.DPM.isProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE))
) Row(
Modifier
.fillMaxWidth()
@@ -367,18 +368,18 @@ fun WorkModesScreen(
TextButton(
{
if(privilege.dhizuku) {
SharedPrefs(context).dhizuku = false
SP.dhizuku = false
Privilege.initialize(context)
Privilege.updateStatus()
} else {
val dpm = context.getDPM()
if(privilege.device) {
dpm.clearDeviceOwnerApp(context.packageName)
Privilege.DPM.clearDeviceOwnerApp(context.packageName)
} else if(VERSION.SDK_INT >= 24) {
dpm.clearProfileOwner(MyAdminComponent)
Privilege.DPM.clearProfileOwner(MyAdminComponent)
}
// Status updated in Receiver.onDisabled()
}
dialog = 0
updatePrivilege(context)
handlePrivilegeChange(context)
},
enabled = time == 0,
colors = ButtonDefaults.textButtonColors(contentColor = colorScheme.error)
@@ -440,16 +441,23 @@ fun activateUsingRoot(context: Context, callback: (Boolean, Boolean, String?) ->
fun activateUsingDhizuku(context: Context, callback: (Boolean, Boolean, String?) -> Unit) {
fun doTransfer() {
try {
val dpm = binderWrapperDevicePolicyManager(context)
if(dpm == null) {
context.showOperationResultToast(false)
if (SP.dhizuku) {
Privilege.DPM.transferOwnership(Privilege.DAR, MyAdminComponent, PersistableBundle())
SP.dhizuku = false
Privilege.initialize(context)
} else {
dpm.transferOwnership(Dhizuku.getOwnerComponent(), MyAdminComponent, PersistableBundle())
callback(true, true, null)
val dpm = binderWrapperDevicePolicyManager(context)
if (dpm == null) {
callback(false, false, null)
return
} else {
dpm.transferOwnership(Dhizuku.getOwnerComponent(), MyAdminComponent, PersistableBundle())
}
}
callback(true, true, null)
} catch (e: Exception) {
e.printStackTrace()
callback(true, false, null)
callback(false, false, null)
}
}
if(Dhizuku.init(context)) {
@@ -470,7 +478,8 @@ fun activateUsingDhizuku(context: Context, callback: (Boolean, Boolean, String?)
fun activateDhizukuMode(context: Context, callback: (Boolean, Boolean, String?) -> Unit) {
fun onSucceed() {
SharedPrefs(context).dhizuku = true
SP.dhizuku = true
Privilege.initialize(context)
callback(true, true, null)
}
if(Dhizuku.init(context)) {
@@ -496,13 +505,12 @@ const val ACTIVATE_DEVICE_OWNER_COMMAND = "dpm set-device-owner com.bintianqi.ow
fun DhizukuServerSettingsScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val pm = context.packageManager
val sp = SharedPrefs(context)
val file = context.filesDir.resolve(DHIZUKU_CLIENTS_FILE)
var enabled by remember { mutableStateOf(sp.dhizukuServer) }
var enabled by remember { mutableStateOf(SP.dhizukuServer) }
val clients = remember { mutableStateListOf<DhizukuClientInfo>() }
fun changeEnableState(status: Boolean) {
enabled = status
sp.dhizukuServer = status
SP.dhizukuServer = status
}
fun writeList() {
file.writeText(Json.encodeToString(clients.toList()))
@@ -519,7 +527,7 @@ fun DhizukuServerSettingsScreen(onNavigateUp: () -> Unit) {
}
MyLazyScaffold(R.string.dhizuku_server, onNavigateUp) {
item {
SwitchItem(R.string.enable, getState = { sp.dhizukuServer }, onCheckedChange = ::changeEnableState)
SwitchItem(R.string.enable, getState = { SP.dhizukuServer }, onCheckedChange = ::changeEnableState)
HorizontalDivider(Modifier.padding(vertical = 8.dp))
}
if (enabled) itemsIndexed(clients) { index, client ->
@@ -531,10 +539,14 @@ fun DhizukuServerSettingsScreen(onNavigateUp: () -> Unit) {
val info = pm.getApplicationInfo(name, 0)
var expand by remember { mutableStateOf(false) }
Card(
Modifier.fillMaxWidth().padding(HorizontalPadding, 8.dp)
Modifier
.fillMaxWidth()
.padding(HorizontalPadding, 8.dp)
) {
Row(
Modifier.fillMaxWidth().padding(8.dp, 8.dp, 0.dp, 8.dp),
Modifier
.fillMaxWidth()
.padding(8.dp, 8.dp, 0.dp, 8.dp),
Arrangement.SpaceBetween, Alignment.CenterVertically
) {
Row(verticalAlignment = Alignment.CenterVertically) {
@@ -597,10 +609,8 @@ fun DhizukuServerSettingsScreen(onNavigateUp: () -> Unit) {
@Composable
fun LockScreenInfoScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val focusMgr = LocalFocusManager.current
var infoText by remember { mutableStateOf(dpm.deviceOwnerLockScreenInfo?.toString() ?: "") }
var infoText by remember { mutableStateOf(Privilege.DPM.deviceOwnerLockScreenInfo?.toString() ?: "") }
MyScaffold(R.string.lock_screen_info, onNavigateUp) {
OutlinedTextField(
value = infoText,
@@ -615,7 +625,7 @@ fun LockScreenInfoScreen(onNavigateUp: () -> Unit) {
Button(
onClick = {
focusMgr.clearFocus()
dpm.setDeviceOwnerLockScreenInfo(receiver,infoText)
Privilege.DPM.setDeviceOwnerLockScreenInfo(Privilege.DAR, infoText)
context.showOperationResultToast(true)
},
modifier = Modifier.fillMaxWidth()
@@ -625,7 +635,7 @@ fun LockScreenInfoScreen(onNavigateUp: () -> Unit) {
Button(
onClick = {
focusMgr.clearFocus()
dpm.setDeviceOwnerLockScreenInfo(receiver, null)
Privilege.DPM.setDeviceOwnerLockScreenInfo(Privilege.DAR, null)
infoText = ""
context.showOperationResultToast(true)
},
@@ -659,15 +669,12 @@ enum class DelegatedScope(val id: String, @StringRes val string: Int, val requir
@RequiresApi(26)
@Composable
fun DelegatedAdminsScreen(onNavigateUp: () -> Unit, onNavigate: (AddDelegatedAdmin) -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val packages = remember { mutableStateMapOf<String, MutableList<DelegatedScope>>() }
fun refresh() {
val list = mutableMapOf<String, MutableList<DelegatedScope>>()
DelegatedScope.entries.forEach { ds ->
if(VERSION.SDK_INT >= ds.requiresApi) {
dpm.getDelegatePackages(receiver, ds.id)?.forEach { pkg ->
Privilege.DPM.getDelegatePackages(Privilege.DAR, ds.id)?.forEach { pkg ->
if(list[pkg] != null) {
list[pkg]!!.add(ds)
} else {
@@ -728,7 +735,6 @@ fun DelegatedAdminsScreen(onNavigateUp: () -> Unit, onNavigate: (AddDelegatedAdm
fun AddDelegatedAdminScreen(data: AddDelegatedAdmin, onNavigateUp: () -> Unit) {
val updateMode = data.pkg.isNotEmpty()
val fm = LocalFocusManager.current
val context = LocalContext.current
var input by remember { mutableStateOf(data.pkg) }
val scopes = remember { mutableStateListOf(*data.scopes.toTypedArray()) }
val choosePackage = rememberLauncherForActivityResult(ChoosePackageContract()) { result ->
@@ -768,7 +774,7 @@ fun AddDelegatedAdminScreen(data: AddDelegatedAdmin, onNavigateUp: () -> Unit) {
}
Button(
onClick = {
context.getDPM().setDelegatedScopes(context.getReceiver(), input, scopes.map { it.id })
Privilege.DPM.setDelegatedScopes(Privilege.DAR, input, scopes.map { it.id })
onNavigateUp()
},
modifier = Modifier
@@ -780,7 +786,7 @@ fun AddDelegatedAdminScreen(data: AddDelegatedAdmin, onNavigateUp: () -> Unit) {
}
if(updateMode) Button(
onClick = {
context.getDPM().setDelegatedScopes(context.getReceiver(), input, emptyList())
Privilege.DPM.setDelegatedScopes(Privilege.DAR, input, emptyList())
onNavigateUp()
},
modifier = Modifier
@@ -797,16 +803,14 @@ fun AddDelegatedAdminScreen(data: AddDelegatedAdmin, onNavigateUp: () -> Unit) {
@Composable
fun DeviceInfoScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val privilege by myPrivilege.collectAsStateWithLifecycle()
val privilege by Privilege.status.collectAsStateWithLifecycle()
var dialog by remember { mutableIntStateOf(0) }
MyScaffold(R.string.device_info, onNavigateUp, 0.dp) {
if(VERSION.SDK_INT>=34 && (privilege.device || privilege.org)) {
InfoItem(R.string.financed_device, dpm.isDeviceFinanced.yesOrNo)
InfoItem(R.string.financed_device, Privilege.DPM.isDeviceFinanced.yesOrNo)
}
if(VERSION.SDK_INT >= 33) {
val dpmRole = dpm.devicePolicyManagementRoleHolderPackage
val dpmRole = Privilege.DPM.devicePolicyManagementRoleHolderPackage
InfoItem(R.string.dpmrh, dpmRole ?: stringResource(R.string.none))
}
val encryptionStatus = mutableMapOf(
@@ -816,14 +820,14 @@ fun DeviceInfoScreen(onNavigateUp: () -> Unit) {
)
if(VERSION.SDK_INT >= 23) { encryptionStatus[DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY] = R.string.es_active_default_key }
if(VERSION.SDK_INT >= 24) { encryptionStatus[DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER] = R.string.es_active_per_user }
InfoItem(R.string.encryption_status, encryptionStatus[dpm.storageEncryptionStatus] ?: R.string.unknown)
InfoItem(R.string.encryption_status, encryptionStatus[Privilege.DPM.storageEncryptionStatus] ?: R.string.unknown)
if(VERSION.SDK_INT >= 28) {
InfoItem(R.string.support_device_id_attestation, dpm.isDeviceIdAttestationSupported.yesOrNo, true) { dialog = 1 }
InfoItem(R.string.support_device_id_attestation, Privilege.DPM.isDeviceIdAttestationSupported.yesOrNo, true) { dialog = 1 }
}
if (VERSION.SDK_INT >= 30) {
InfoItem(R.string.support_unique_device_attestation, dpm.isUniqueDeviceAttestationSupported.yesOrNo, true) { dialog = 2 }
InfoItem(R.string.support_unique_device_attestation, Privilege.DPM.isUniqueDeviceAttestationSupported.yesOrNo, true) { dialog = 2 }
}
val adminList = dpm.activeAdmins
val adminList = Privilege.DPM.activeAdmins
if(adminList != null) {
InfoItem(R.string.activated_device_admin, adminList.joinToString("\n") { it.flattenToShortString() })
}
@@ -841,13 +845,11 @@ fun DeviceInfoScreen(onNavigateUp: () -> Unit) {
@Composable
fun SupportMessageScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
var shortMsg by remember { mutableStateOf("") }
var longMsg by remember { mutableStateOf("") }
val refreshMsg = {
shortMsg = dpm.getShortSupportMessage(receiver)?.toString() ?: ""
longMsg = dpm.getLongSupportMessage(receiver)?.toString() ?: ""
shortMsg = Privilege.DPM.getShortSupportMessage(Privilege.DAR)?.toString() ?: ""
longMsg = Privilege.DPM.getLongSupportMessage(Privilege.DAR)?.toString() ?: ""
}
LaunchedEffect(Unit) { refreshMsg() }
MyScaffold(R.string.support_messages, onNavigateUp) {
@@ -863,7 +865,7 @@ fun SupportMessageScreen(onNavigateUp: () -> Unit) {
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
Button(
onClick = {
dpm.setShortSupportMessage(receiver, shortMsg)
Privilege.DPM.setShortSupportMessage(Privilege.DAR, shortMsg)
refreshMsg()
context.showOperationResultToast(true)
},
@@ -873,7 +875,7 @@ fun SupportMessageScreen(onNavigateUp: () -> Unit) {
}
Button(
onClick = {
dpm.setShortSupportMessage(receiver, null)
Privilege.DPM.setShortSupportMessage(Privilege.DAR, null)
refreshMsg()
context.showOperationResultToast(true)
},
@@ -896,7 +898,7 @@ fun SupportMessageScreen(onNavigateUp: () -> Unit) {
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
Button(
onClick = {
dpm.setLongSupportMessage(receiver, longMsg)
Privilege.DPM.setLongSupportMessage(Privilege.DAR, longMsg)
refreshMsg()
context.showOperationResultToast(true)
},
@@ -906,7 +908,7 @@ fun SupportMessageScreen(onNavigateUp: () -> Unit) {
}
Button(
onClick = {
dpm.setLongSupportMessage(receiver, null)
Privilege.DPM.setLongSupportMessage(Privilege.DAR, null)
refreshMsg()
context.showOperationResultToast(true)
},
@@ -925,7 +927,7 @@ fun SupportMessageScreen(onNavigateUp: () -> Unit) {
@Composable
fun TransferOwnershipScreen(onNavigateUp: () -> Unit, onTransferred: () -> Unit) {
val context = LocalContext.current
val privilege by myPrivilege.collectAsStateWithLifecycle()
val privilege by Privilege.status.collectAsStateWithLifecycle()
val focusMgr = LocalFocusManager.current
var input by remember { mutableStateOf("") }
val componentName = ComponentName.unflattenFromString(input)
@@ -960,12 +962,10 @@ fun TransferOwnershipScreen(onNavigateUp: () -> Unit, onTransferred: () -> Unit)
confirmButton = {
TextButton(
onClick = {
val dpm = context.getDPM()
val receiver = context.getReceiver()
try {
dpm.transferOwnership(receiver, componentName!!, null)
Privilege.DPM.transferOwnership(Privilege.DAR, componentName!!, null)
Privilege.updateStatus()
context.showOperationResultToast(true)
updatePrivilege(context)
dialog = false
onTransferred()
} catch(e: Exception) {

View File

@@ -121,12 +121,12 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.bintianqi.owndroid.ChoosePackageContract
import com.bintianqi.owndroid.HorizontalPadding
import com.bintianqi.owndroid.NotificationUtils
import com.bintianqi.owndroid.Privilege
import com.bintianqi.owndroid.R
import com.bintianqi.owndroid.SharedPrefs
import com.bintianqi.owndroid.SP
import com.bintianqi.owndroid.createShortcuts
import com.bintianqi.owndroid.formatFileSize
import com.bintianqi.owndroid.humanReadableDate
import com.bintianqi.owndroid.myPrivilege
import com.bintianqi.owndroid.parseDate
import com.bintianqi.owndroid.popToast
import com.bintianqi.owndroid.showOperationResultToast
@@ -161,14 +161,11 @@ import kotlin.math.roundToLong
@Composable
fun SystemManagerScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val sp = SharedPrefs(context)
val privilege by myPrivilege.collectAsStateWithLifecycle()
val privilege by Privilege.status.collectAsStateWithLifecycle()
/** 1: reboot, 2: bug report, 3: org name, 4: org id, 5: enrollment specific id*/
var dialog by remember { mutableIntStateOf(0) }
var enrollmentSpecificId by remember {
mutableStateOf(if (VERSION.SDK_INT >= 31 && (privilege.device || privilege.profile)) dpm.enrollmentSpecificId else "")
mutableStateOf(if (VERSION.SDK_INT >= 31 && (privilege.device || privilege.profile)) Privilege.DPM.enrollmentSpecificId else "")
}
MyScaffold(R.string.system, onNavigateUp, 0.dp) {
FunctionItem(R.string.options, icon = R.drawable.tune_fill0) { onNavigate(SystemOptions) }
@@ -178,7 +175,7 @@ fun SystemManagerScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
if(VERSION.SDK_INT >= 24 && privilege.device) {
FunctionItem(R.string.reboot, icon = R.drawable.restart_alt_fill0) { dialog = 1 }
}
if(VERSION.SDK_INT >= 24 && privilege.device && (VERSION.SDK_INT < 28 || dpm.isAffiliatedUser)) {
if(VERSION.SDK_INT >= 24 && privilege.device && (VERSION.SDK_INT < 28 || privilege.affiliated)) {
FunctionItem(R.string.bug_report, icon = R.drawable.bug_report_fill0) { dialog = 2 }
}
if(VERSION.SDK_INT >= 28 && (privilege.device || privilege.org)) {
@@ -235,7 +232,7 @@ fun SystemManagerScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
if(VERSION.SDK_INT >= 30 && (privilege.device || privilege.org)) {
FunctionItem(R.string.frp_policy, icon = R.drawable.device_reset_fill0) { onNavigate(FrpPolicy) }
}
if(sp.displayDangerousFeatures && !privilege.work) {
if(SP.displayDangerousFeatures && !privilege.work) {
FunctionItem(R.string.wipe_data, icon = R.drawable.device_reset_fill0) { onNavigate(WipeData) }
}
}
@@ -252,9 +249,9 @@ fun SystemManagerScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
TextButton(
onClick = {
if(dialog == 1) {
dpm.reboot(receiver)
Privilege.DPM.reboot(Privilege.DAR)
} else {
context.showOperationResultToast(dpm.requestBugreport(receiver))
context.showOperationResultToast(Privilege.DPM.requestBugreport(Privilege.DAR))
}
dialog = 0
}
@@ -270,7 +267,7 @@ fun SystemManagerScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
text = {
val focusMgr = LocalFocusManager.current
LaunchedEffect(Unit) {
if(dialog == 5 && VERSION.SDK_INT >= 31) input = dpm.enrollmentSpecificId
if(dialog == 5 && VERSION.SDK_INT >= 31) input = Privilege.DPM.enrollmentSpecificId
}
Column {
OutlinedTextField(
@@ -306,10 +303,10 @@ fun SystemManagerScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
TextButton(
onClick = {
try {
if (dialog == 3 && VERSION.SDK_INT >= 24) dpm.setOrganizationName(receiver, input)
if (dialog == 3 && VERSION.SDK_INT >= 24) Privilege.DPM.setOrganizationName(Privilege.DAR, input)
if (dialog == 4 && VERSION.SDK_INT >= 31) {
dpm.setOrganizationId(input)
enrollmentSpecificId = dpm.enrollmentSpecificId
Privilege.DPM.setOrganizationId(input)
enrollmentSpecificId = Privilege.DPM.enrollmentSpecificId
}
dialog = 0
} catch(_: IllegalStateException) {
@@ -330,66 +327,71 @@ fun SystemManagerScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
@Composable
fun SystemOptionsScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val privilege by myPrivilege.collectAsStateWithLifecycle()
val privilege by Privilege.status.collectAsStateWithLifecycle()
var dialog by remember { mutableIntStateOf(0) }
MyScaffold(R.string.options, onNavigateUp, 0.dp) {
SwitchItem(R.string.disable_cam, icon = R.drawable.no_photography_fill0,
getState = { dpm.getCameraDisabled(null) }, onCheckedChange = {
dpm.setCameraDisabled(receiver, it)
getState = { Privilege.DPM.getCameraDisabled(null) }, onCheckedChange = {
Privilege.DPM.setCameraDisabled(Privilege.DAR, it)
createShortcuts(context)
}
)
SwitchItem(R.string.disable_screen_capture, icon = R.drawable.screenshot_fill0,
getState = { dpm.getScreenCaptureDisabled(null) }, onCheckedChange = { dpm.setScreenCaptureDisabled(receiver,it) }
getState = { Privilege.DPM.getScreenCaptureDisabled(null) },
onCheckedChange = { Privilege.DPM.setScreenCaptureDisabled(Privilege.DAR, it) }
)
if(VERSION.SDK_INT >= 34 && (privilege.device || (privilege.profile && privilege.affiliated))) {
SwitchItem(R.string.disable_status_bar, icon = R.drawable.notifications_fill0,
getState = { dpm.isStatusBarDisabled}, onCheckedChange = { dpm.setStatusBarDisabled(receiver,it) }
getState = { Privilege.DPM.isStatusBarDisabled},
onCheckedChange = { Privilege.DPM.setStatusBarDisabled(Privilege.DAR, it) }
)
}
if(privilege.device || privilege.org) {
if(VERSION.SDK_INT >= 30) {
SwitchItem(R.string.auto_time, icon = R.drawable.schedule_fill0,
getState = { dpm.getAutoTimeEnabled(receiver) }, onCheckedChange = { dpm.setAutoTimeEnabled(receiver,it) }
getState = { Privilege.DPM.getAutoTimeEnabled(Privilege.DAR) },
onCheckedChange = { Privilege.DPM.setAutoTimeEnabled(Privilege.DAR, it) }
)
SwitchItem(R.string.auto_timezone, icon = R.drawable.globe_fill0,
getState = { dpm.getAutoTimeZoneEnabled(receiver) }, onCheckedChange = { dpm.setAutoTimeZoneEnabled(receiver,it) }
getState = { Privilege.DPM.getAutoTimeZoneEnabled(Privilege.DAR) },
onCheckedChange = { Privilege.DPM.setAutoTimeZoneEnabled(Privilege.DAR, it) }
)
} else {
SwitchItem(R.string.require_auto_time, icon = R.drawable.schedule_fill0,
getState = { dpm.autoTimeRequired }, onCheckedChange = { dpm.setAutoTimeRequired(receiver,it) }, padding = false)
getState = { Privilege.DPM.autoTimeRequired },
onCheckedChange = { Privilege.DPM.setAutoTimeRequired(Privilege.DAR, it) }, padding = false)
}
}
if (!privilege.work) SwitchItem(R.string.master_mute, icon = R.drawable.volume_off_fill0,
getState = { dpm.isMasterVolumeMuted(receiver) }, onCheckedChange = {
dpm.setMasterVolumeMuted(receiver,it)
getState = { Privilege.DPM.isMasterVolumeMuted(Privilege.DAR) }, onCheckedChange = {
Privilege.DPM.setMasterVolumeMuted(Privilege.DAR, it)
createShortcuts(context)
}
)
if(VERSION.SDK_INT >= 26) {
SwitchItem(R.string.backup_service, icon = R.drawable.backup_fill0,
getState = { dpm.isBackupServiceEnabled(receiver) }, onCheckedChange = { dpm.setBackupServiceEnabled(receiver,it) },
getState = { Privilege.DPM.isBackupServiceEnabled(Privilege.DAR) },
onCheckedChange = { Privilege.DPM.setBackupServiceEnabled(Privilege.DAR, it) },
onClickBlank = { dialog = 1 }
)
}
if(VERSION.SDK_INT >= 24 && privilege.work) {
SwitchItem(R.string.disable_bt_contact_share, icon = R.drawable.account_circle_fill0,
getState = { dpm.getBluetoothContactSharingDisabled(receiver) },
onCheckedChange = { dpm.setBluetoothContactSharingDisabled(receiver,it) }
getState = { Privilege.DPM.getBluetoothContactSharingDisabled(Privilege.DAR) },
onCheckedChange = { Privilege.DPM.setBluetoothContactSharingDisabled(Privilege.DAR, it) }
)
}
if(VERSION.SDK_INT >= 30 && privilege.device) {
SwitchItem(R.string.common_criteria_mode , icon =R.drawable.security_fill0,
getState = { dpm.isCommonCriteriaModeEnabled(receiver) }, onCheckedChange = { dpm.setCommonCriteriaModeEnabled(receiver,it) },
getState = { Privilege.DPM.isCommonCriteriaModeEnabled(Privilege.DAR) },
onCheckedChange = { Privilege.DPM.setCommonCriteriaModeEnabled(Privilege.DAR, it) },
onClickBlank = { dialog = 2 }
)
}
if(VERSION.SDK_INT >= 31 && (privilege.device || privilege.org) && dpm.canUsbDataSignalingBeDisabled()) {
if(VERSION.SDK_INT >= 31 && (privilege.device || privilege.org) && Privilege.DPM.canUsbDataSignalingBeDisabled()) {
SwitchItem(
R.string.disable_usb_signal, icon = R.drawable.usb_fill0, getState = { !dpm.isUsbDataSignalingEnabled },
onCheckedChange = { dpm.isUsbDataSignalingEnabled = !it },
R.string.disable_usb_signal, icon = R.drawable.usb_fill0, getState = { !Privilege.DPM.isUsbDataSignalingEnabled },
onCheckedChange = { Privilege.DPM.isUsbDataSignalingEnabled = !it },
)
}
}
@@ -415,9 +417,7 @@ fun SystemOptionsScreen(onNavigateUp: () -> Unit) {
@Composable
fun KeyguardScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val privilege by myPrivilege.collectAsStateWithLifecycle()
val privilege by Privilege.status.collectAsStateWithLifecycle()
MyScaffold(R.string.keyguard, onNavigateUp) {
if(VERSION.SDK_INT >= 23 && (privilege.device || (VERSION.SDK_INT >= 28 && privilege.profile && privilege.affiliated))) {
Row(
@@ -425,13 +425,13 @@ fun KeyguardScreen(onNavigateUp: () -> Unit) {
modifier = Modifier.fillMaxWidth()
) {
Button(
onClick = { context.showOperationResultToast(dpm.setKeyguardDisabled(receiver, true)) },
onClick = { context.showOperationResultToast(Privilege.DPM.setKeyguardDisabled(Privilege.DAR, true)) },
modifier = Modifier.fillMaxWidth(0.49F)
) {
Text(stringResource(R.string.disable))
}
Button(
onClick = { context.showOperationResultToast(dpm.setKeyguardDisabled(receiver, false)) },
onClick = { context.showOperationResultToast(Privilege.DPM.setKeyguardDisabled(Privilege.DAR, false)) },
modifier = Modifier.fillMaxWidth(0.96F)
) {
Text(stringResource(R.string.enable))
@@ -452,7 +452,7 @@ fun KeyguardScreen(onNavigateUp: () -> Unit) {
}
Button(
onClick = {
if(VERSION.SDK_INT >= 26) dpm.lockNow(flag) else dpm.lockNow()
if(VERSION.SDK_INT >= 26) Privilege.DPM.lockNow(flag) else Privilege.DPM.lockNow()
},
modifier = Modifier.fillMaxWidth()
) {
@@ -553,8 +553,6 @@ fun HardwareMonitorScreen(onNavigateUp: () -> Unit) {
@Composable
fun ChangeTimeScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val focusMgr = LocalFocusManager.current
val pagerState = rememberPagerState { 2 }
var picker by remember { mutableIntStateOf(0) } //0:None, 1:DatePicker, 2:TimePicker
@@ -617,7 +615,7 @@ fun ChangeTimeScreen(onNavigateUp: () -> Unit) {
Button(
onClick = {
val timeMillis = datePickerState.selectedDateMillis!! + timePickerState.hour * 3600000 + timePickerState.minute * 60000
context.showOperationResultToast(dpm.setTime(receiver, timeMillis))
context.showOperationResultToast(Privilege.DPM.setTime(Privilege.DAR, timeMillis))
},
modifier = Modifier.fillMaxWidth(),
enabled = datePickerState.selectedDateMillis != null
@@ -637,7 +635,7 @@ fun ChangeTimeScreen(onNavigateUp: () -> Unit) {
Button(
onClick = {
val timeMillis = inputTime.toLong()
context.showOperationResultToast(dpm.setTime(receiver, timeMillis))
context.showOperationResultToast(Privilege.DPM.setTime(Privilege.DAR, timeMillis))
},
modifier = Modifier
.fillMaxWidth()
@@ -677,9 +675,7 @@ fun ChangeTimeScreen(onNavigateUp: () -> Unit) {
@Composable
fun ChangeTimeZoneScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val focusMgr = LocalFocusManager.current
val receiver = context.getReceiver()
var inputTimezone by remember { mutableStateOf("") }
var dialog by remember { mutableStateOf(false) }
MyScaffold(R.string.change_timezone, onNavigateUp) {
@@ -699,7 +695,7 @@ fun ChangeTimeZoneScreen(onNavigateUp: () -> Unit) {
Spacer(Modifier.padding(vertical = 5.dp))
Button(
onClick = {
context.showOperationResultToast(dpm.setTimeZone(receiver, inputTimezone))
context.showOperationResultToast(Privilege.DPM.setTimeZone(Privilege.DAR, inputTimezone))
},
modifier = Modifier.fillMaxWidth()
) {
@@ -741,9 +737,7 @@ fun ChangeTimeZoneScreen(onNavigateUp: () -> Unit) {
@RequiresApi(36)
@Composable
fun AutoTimePolicyScreen(onNavigateUp: () -> Unit) = MyScaffold(R.string.auto_time_policy, onNavigateUp, 0.dp) {
val context = LocalContext.current
val dpm = context.getDPM()
var policy by remember { mutableIntStateOf(dpm.autoTimePolicy) }
var policy by remember { mutableIntStateOf(Privilege.DPM.autoTimePolicy) }
listOf(
DevicePolicyManager.AUTO_TIME_ENABLED to R.string.enable,
DevicePolicyManager.AUTO_TIME_DISABLED to R.string.disabled,
@@ -754,8 +748,8 @@ fun AutoTimePolicyScreen(onNavigateUp: () -> Unit) = MyScaffold(R.string.auto_ti
}
}
Button({
dpm.autoTimePolicy = policy
policy = dpm.autoTimePolicy
Privilege.DPM.autoTimePolicy = policy
policy = Privilege.DPM.autoTimePolicy
}, Modifier.fillMaxWidth().padding(horizontal = HorizontalPadding)) {
Text(stringResource(R.string.apply))
}
@@ -766,9 +760,7 @@ fun AutoTimePolicyScreen(onNavigateUp: () -> Unit) = MyScaffold(R.string.auto_ti
@RequiresApi(36)
@Composable
fun AutoTimeZonePolicyScreen(onNavigateUp: () -> Unit) = MyScaffold(R.string.auto_timezone_policy, onNavigateUp, 0.dp) {
val context = LocalContext.current
val dpm = context.getDPM()
var policy by remember { mutableIntStateOf(dpm.autoTimeZonePolicy) }
var policy by remember { mutableIntStateOf(Privilege.DPM.autoTimeZonePolicy) }
listOf(
DevicePolicyManager.AUTO_TIME_ZONE_ENABLED to R.string.enable,
DevicePolicyManager.AUTO_TIME_ZONE_DISABLED to R.string.disabled,
@@ -779,8 +771,8 @@ fun AutoTimeZonePolicyScreen(onNavigateUp: () -> Unit) = MyScaffold(R.string.aut
}
}
Button({
dpm.autoTimeZonePolicy = policy
policy = dpm.autoTimeZonePolicy
Privilege.DPM.autoTimeZonePolicy = policy
policy = Privilege.DPM.autoTimeZonePolicy
}, Modifier.fillMaxWidth().padding(horizontal = HorizontalPadding)) {
Text(stringResource(R.string.apply))
}
@@ -972,10 +964,8 @@ fun KeyPairs(navCtrl: NavHostController) {
@Composable
fun ContentProtectionPolicyScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
var policy by remember { mutableIntStateOf(DevicePolicyManager.CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY) }
fun refresh() { policy = dpm.getContentProtectionPolicy(receiver) }
fun refresh() { policy = Privilege.DPM.getContentProtectionPolicy(Privilege.DAR) }
LaunchedEffect(Unit) { refresh() }
MyScaffold(R.string.content_protection_policy, onNavigateUp, 0.dp) {
mapOf(
@@ -987,7 +977,7 @@ fun ContentProtectionPolicyScreen(onNavigateUp: () -> Unit) {
}
Button(
onClick = {
dpm.setContentProtectionPolicy(receiver, policy)
Privilege.DPM.setContentProtectionPolicy(Privilege.DAR, policy)
refresh()
context.showOperationResultToast(true)
},
@@ -1007,9 +997,7 @@ fun ContentProtectionPolicyScreen(onNavigateUp: () -> Unit) {
@Composable
fun PermissionPolicyScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
var selectedPolicy by remember { mutableIntStateOf(dpm.getPermissionPolicy(receiver)) }
var selectedPolicy by remember { mutableIntStateOf(Privilege.DPM.getPermissionPolicy(Privilege.DAR)) }
MyScaffold(R.string.permission_policy, onNavigateUp, 0.dp) {
FullWidthRadioButtonItem(R.string.default_stringres, selectedPolicy == PERMISSION_POLICY_PROMPT) {
selectedPolicy = PERMISSION_POLICY_PROMPT
@@ -1023,7 +1011,7 @@ fun PermissionPolicyScreen(onNavigateUp: () -> Unit) {
Spacer(Modifier.padding(vertical = 5.dp))
Button(
onClick = {
dpm.setPermissionPolicy(receiver,selectedPolicy)
Privilege.DPM.setPermissionPolicy(Privilege.DAR,selectedPolicy)
context.showOperationResultToast(true)
},
modifier = Modifier
@@ -1042,8 +1030,7 @@ fun PermissionPolicyScreen(onNavigateUp: () -> Unit) {
@Composable
fun MtePolicyScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
var selectedMtePolicy by remember { mutableIntStateOf(dpm.mtePolicy) }
var selectedMtePolicy by remember { mutableIntStateOf(Privilege.DPM.mtePolicy) }
MyScaffold(R.string.mte_policy, onNavigateUp, 0.dp) {
FullWidthRadioButtonItem(R.string.decide_by_user, selectedMtePolicy == MTE_NOT_CONTROLLED_BY_POLICY) {
selectedMtePolicy = MTE_NOT_CONTROLLED_BY_POLICY
@@ -1053,12 +1040,12 @@ fun MtePolicyScreen(onNavigateUp: () -> Unit) {
Button(
onClick = {
try {
dpm.mtePolicy = selectedMtePolicy
Privilege.DPM.mtePolicy = selectedMtePolicy
context.showOperationResultToast(true)
} catch(_: java.lang.UnsupportedOperationException) {
context.popToast(R.string.unsupported)
}
selectedMtePolicy = dpm.mtePolicy
selectedMtePolicy = Privilege.DPM.mtePolicy
},
modifier = Modifier
.fillMaxWidth()
@@ -1076,8 +1063,7 @@ fun MtePolicyScreen(onNavigateUp: () -> Unit) {
@Composable
fun NearbyStreamingPolicyScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
var appPolicy by remember { mutableIntStateOf(dpm.nearbyAppStreamingPolicy) }
var appPolicy by remember { mutableIntStateOf(Privilege.DPM.nearbyAppStreamingPolicy) }
MySmallTitleScaffold(R.string.nearby_streaming_policy, onNavigateUp, 0.dp) {
Text(
stringResource(R.string.nearby_app_streaming),
@@ -1095,8 +1081,8 @@ fun NearbyStreamingPolicyScreen(onNavigateUp: () -> Unit) {
) { appPolicy = NEARBY_STREAMING_SAME_MANAGED_ACCOUNT_ONLY }
Button(
onClick = {
dpm.nearbyAppStreamingPolicy = appPolicy
appPolicy = dpm.nearbyAppStreamingPolicy
Privilege.DPM.nearbyAppStreamingPolicy = appPolicy
appPolicy = Privilege.DPM.nearbyAppStreamingPolicy
context.showOperationResultToast(true)
},
modifier = Modifier
@@ -1106,7 +1092,7 @@ fun NearbyStreamingPolicyScreen(onNavigateUp: () -> Unit) {
Text(stringResource(R.string.apply))
}
Notes(R.string.info_nearby_app_streaming_policy, HorizontalPadding)
var notificationPolicy by remember { mutableIntStateOf(dpm.nearbyNotificationStreamingPolicy) }
var notificationPolicy by remember { mutableIntStateOf(Privilege.DPM.nearbyNotificationStreamingPolicy) }
Text(
stringResource(R.string.nearby_notification_streaming),
Modifier.padding(start = 8.dp, top = 10.dp, bottom = 4.dp), style = typography.titleLarge
@@ -1129,8 +1115,8 @@ fun NearbyStreamingPolicyScreen(onNavigateUp: () -> Unit) {
) { notificationPolicy = NEARBY_STREAMING_SAME_MANAGED_ACCOUNT_ONLY }
Button(
onClick = {
dpm.nearbyNotificationStreamingPolicy = notificationPolicy
notificationPolicy = dpm.nearbyNotificationStreamingPolicy
Privilege.DPM.nearbyNotificationStreamingPolicy = notificationPolicy
notificationPolicy = Privilege.DPM.nearbyNotificationStreamingPolicy
context.showOperationResultToast(true)
},
modifier = Modifier
@@ -1213,7 +1199,6 @@ fun LockTaskModeScreen(onNavigateUp: () -> Unit) {
@Composable
private fun ColumnScope.StartLockTaskMode() {
val context = LocalContext.current
val dpm = context.getDPM()
val focusMgr = LocalFocusManager.current
var startLockTaskApp by rememberSaveable { mutableStateOf("") }
var startLockTaskActivity by rememberSaveable { mutableStateOf("") }
@@ -1256,7 +1241,7 @@ private fun ColumnScope.StartLockTaskMode() {
modifier = Modifier.fillMaxWidth(),
onClick = {
if(!NotificationUtils.checkPermission(context)) return@Button
if(!dpm.isLockTaskPermitted(startLockTaskApp)) {
if(!Privilege.DPM.isLockTaskPermitted(startLockTaskApp)) {
context.popToast(R.string.app_not_allowed)
return@Button
}
@@ -1281,15 +1266,13 @@ private fun ColumnScope.StartLockTaskMode() {
@Composable
private fun ColumnScope.LockTaskPackages() {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val focusMgr = LocalFocusManager.current
val lockTaskPackages = remember { mutableStateListOf<String>() }
var input by rememberSaveable { mutableStateOf("") }
val choosePackage = rememberLauncherForActivityResult(ChoosePackageContract()) { result ->
result?.let { input = it }
}
LaunchedEffect(Unit) { lockTaskPackages.addAll(dpm.getLockTaskPackages(receiver)) }
LaunchedEffect(Unit) { lockTaskPackages.addAll(Privilege.DPM.getLockTaskPackages(Privilege.DAR)) }
Spacer(Modifier.padding(vertical = 5.dp))
if(lockTaskPackages.isEmpty()) Text(text = stringResource(R.string.none))
for(i in lockTaskPackages) {
@@ -1335,7 +1318,7 @@ private fun ColumnScope.LockTaskPackages() {
Button(
modifier = Modifier.fillMaxWidth(),
onClick = {
dpm.setLockTaskPackages(receiver, lockTaskPackages.toTypedArray())
Privilege.DPM.setLockTaskPackages(Privilege.DAR, lockTaskPackages.toTypedArray())
context.showOperationResultToast(true)
}
) {
@@ -1348,13 +1331,11 @@ private fun ColumnScope.LockTaskPackages() {
@Composable
private fun ColumnScope.LockTaskFeatures() {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
var flags by remember { mutableIntStateOf(0) }
var custom by rememberSaveable { mutableStateOf(false) }
var errorMessage by remember { mutableStateOf<String?>(null) }
fun refresh() {
flags = dpm.getLockTaskFeatures(receiver)
flags = Privilege.DPM.getLockTaskFeatures(Privilege.DAR)
custom = flags != 0
}
LaunchedEffect(Unit) { refresh() }
@@ -1385,7 +1366,7 @@ private fun ColumnScope.LockTaskFeatures() {
.padding(vertical = 4.dp, horizontal = HorizontalPadding),
onClick = {
try {
dpm.setLockTaskFeatures(receiver, flags)
Privilege.DPM.setLockTaskFeatures(Privilege.DAR, flags)
context.showOperationResultToast(true)
} catch (e: IllegalArgumentException) {
errorMessage = e.message
@@ -1409,8 +1390,6 @@ data class CaCertInfo(
@Composable
fun CaCertScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
/** 0:none, 1:install, 2:info, 3:uninstall all */
var dialog by remember { mutableIntStateOf(0) }
var caCertByteArray by remember { mutableStateOf(byteArrayOf()) }
@@ -1436,7 +1415,7 @@ fun CaCertScreen(onNavigateUp: () -> Unit) {
caCerts.clear()
coroutine.launch(Dispatchers.IO) {
val md = MessageDigest.getInstance("SHA-256")
dpm.getInstalledCaCerts(receiver).forEach { ba ->
Privilege.DPM.getInstalledCaCerts(Privilege.DAR).forEach { ba ->
val hash = md.digest(ba).toHexString()
withContext(Dispatchers.Main) { caCerts += CaCertInfo(hash, ba) }
}
@@ -1519,7 +1498,7 @@ fun CaCertScreen(onNavigateUp: () -> Unit) {
.padding(top = 4.dp), Arrangement.SpaceBetween) {
TextButton(
onClick = {
dpm.uninstallCaCert(receiver, caCertByteArray)
Privilege.DPM.uninstallCaCert(Privilege.DAR, caCertByteArray)
refresh()
dialog = 0
},
@@ -1544,10 +1523,10 @@ fun CaCertScreen(onNavigateUp: () -> Unit) {
TextButton({
try {
if(dialog == 1) {
context.showOperationResultToast(dpm.installCaCert(receiver, caCertByteArray))
context.showOperationResultToast(Privilege.DPM.installCaCert(Privilege.DAR, caCertByteArray))
}
if(dialog == 3) {
dpm.uninstallAllUserCaCerts(receiver)
Privilege.DPM.uninstallAllUserCaCerts(Privilege.DAR)
}
refresh()
dialog = 0
@@ -1575,8 +1554,6 @@ fun CaCertScreen(onNavigateUp: () -> Unit) {
@Composable
fun SecurityLoggingScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val logFile = context.filesDir.resolve("SecurityLogs.json")
var fileSize by remember { mutableLongStateOf(0) }
LaunchedEffect(Unit) { fileSize = logFile.length() }
@@ -1597,7 +1574,8 @@ fun SecurityLoggingScreen(onNavigateUp: () -> Unit) {
MyScaffold(R.string.security_logging, onNavigateUp) {
SwitchItem(
R.string.enable,
getState = { dpm.isSecurityLoggingEnabled(receiver) }, onCheckedChange = { dpm.setSecurityLoggingEnabled(receiver, it) },
getState = { Privilege.DPM.isSecurityLoggingEnabled(Privilege.DAR) },
onCheckedChange = { Privilege.DPM.setSecurityLoggingEnabled(Privilege.DAR, it) },
padding = false
)
Text(stringResource(R.string.log_file_size_is, formatFileSize(fileSize)))
@@ -1626,7 +1604,7 @@ fun SecurityLoggingScreen(onNavigateUp: () -> Unit) {
Spacer(Modifier.padding(vertical = 5.dp))
Button(
onClick = {
val logs = dpm.retrievePreRebootSecurityLogs(receiver)
val logs = Privilege.DPM.retrievePreRebootSecurityLogs(Privilege.DAR)
if(logs == null) {
context.popToast(R.string.no_logs)
return@Button
@@ -1651,22 +1629,19 @@ fun SecurityLoggingScreen(onNavigateUp: () -> Unit) {
@Composable
fun DisableAccountManagementScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val focusMgr = LocalFocusManager.current
MyScaffold(R.string.disable_account_management, onNavigateUp) {
val list = remember { mutableStateListOf<String>() }
fun refreshList() {
list.clear()
dpm.accountTypesWithManagementDisabled?.forEach { list += it }
Privilege.DPM.accountTypesWithManagementDisabled?.forEach { list += it }
}
LaunchedEffect(Unit) { refreshList() }
Column(modifier = Modifier.animateContentSize()) {
if(list.isEmpty()) Text(stringResource(R.string.none))
for(i in list) {
ListItem(i) {
dpm.setAccountManagementDisabled(receiver, i, false)
Privilege.DPM.setAccountManagementDisabled(Privilege.DAR, i, false)
refreshList()
}
}
@@ -1679,7 +1654,7 @@ fun DisableAccountManagementScreen(onNavigateUp: () -> Unit) {
trailingIcon = {
IconButton(
onClick = {
dpm.setAccountManagementDisabled(receiver, inputText, true)
Privilege.DPM.setAccountManagementDisabled(Privilege.DAR, inputText, true)
inputText = ""
refreshList()
},
@@ -1704,10 +1679,7 @@ fun DisableAccountManagementScreen(onNavigateUp: () -> Unit) {
@RequiresApi(30)
@Composable
fun FrpPolicyScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val focusMgr = LocalFocusManager.current
val receiver = context.getReceiver()
var usePolicy by remember { mutableStateOf(false) }
var enabled by remember { mutableStateOf(false) }
var unsupported by remember { mutableStateOf(false) }
@@ -1716,7 +1688,7 @@ fun FrpPolicyScreen(onNavigateUp: () -> Unit) {
LaunchedEffect(Unit) {
var policy: FactoryResetProtectionPolicy? = null
try {
policy = dpm.getFactoryResetProtectionPolicy(receiver)
policy = Privilege.DPM.getFactoryResetProtectionPolicy(Privilege.DAR)
} catch(_: UnsupportedOperationException) {
unsupported = true
policy = null
@@ -1789,7 +1761,7 @@ fun FrpPolicyScreen(onNavigateUp: () -> Unit) {
.setFactoryResetProtectionEnabled(enabled)
.setFactoryResetProtectionAccounts(accountList)
.build()
dpm.setFactoryResetProtectionPolicy(receiver, policy)
Privilege.DPM.setFactoryResetProtectionPolicy(Privilege.DAR, policy)
},
modifier = Modifier
.fillMaxWidth()
@@ -1807,8 +1779,7 @@ fun FrpPolicyScreen(onNavigateUp: () -> Unit) {
fun WipeDataScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
val dpm = context.getDPM()
val privilege by myPrivilege.collectAsStateWithLifecycle()
val privilege by Privilege.status.collectAsStateWithLifecycle()
val focusMgr = LocalFocusManager.current
var flag by remember { mutableIntStateOf(0) }
var warning by remember { mutableStateOf(false) }
@@ -1887,12 +1858,12 @@ fun WipeDataScreen(onNavigateUp: () -> Unit) {
onClick = {
if(silent && VERSION.SDK_INT >= 29) { flag = flag or WIPE_SILENTLY }
if(wipeDevice && VERSION.SDK_INT >= 34) {
dpm.wipeDevice(flag)
Privilege.DPM.wipeDevice(flag)
} else {
if(VERSION.SDK_INT >= 28 && reason != "") {
dpm.wipeData(flag, reason)
Privilege.DPM.wipeData(flag, reason)
} else {
dpm.wipeData(flag)
Privilege.DPM.wipeData(flag)
}
}
},
@@ -1918,11 +1889,9 @@ fun WipeDataScreen(onNavigateUp: () -> Unit) {
@Composable
fun SystemUpdatePolicyScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val focusMgr = LocalFocusManager.current
MyScaffold(R.string.system_update_policy, onNavigateUp, 0.dp) {
var selectedPolicy by remember { mutableStateOf(dpm.systemUpdatePolicy?.policyType) }
var selectedPolicy by remember { mutableStateOf(Privilege.DPM.systemUpdatePolicy?.policyType) }
FullWidthRadioButtonItem(
R.string.system_update_policy_automatic,
selectedPolicy == TYPE_INSTALL_AUTOMATIC
@@ -1974,7 +1943,7 @@ fun SystemUpdatePolicyScreen(onNavigateUp: () -> Unit) {
TYPE_POSTPONE-> SystemUpdatePolicy.createPostponeInstallPolicy()
else -> null
}
dpm.setSystemUpdatePolicy(receiver,policy)
Privilege.DPM.setSystemUpdatePolicy(Privilege.DAR, policy)
context.showOperationResultToast(true)
},
modifier = Modifier
@@ -1984,7 +1953,7 @@ fun SystemUpdatePolicyScreen(onNavigateUp: () -> Unit) {
Text(stringResource(R.string.apply))
}
if(VERSION.SDK_INT >= 26) {
val sysUpdateInfo = dpm.getPendingSystemUpdate(receiver)
val sysUpdateInfo = Privilege.DPM.getPendingSystemUpdate(Privilege.DAR)
Column(Modifier.padding(HorizontalPadding)) {
if(sysUpdateInfo != null) {
Text(text = stringResource(R.string.update_received_time, Date(sysUpdateInfo.receivedTime)))
@@ -2008,8 +1977,6 @@ fun SystemUpdatePolicyScreen(onNavigateUp: () -> Unit) {
@Composable
fun InstallSystemUpdateScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val callback = object: InstallSystemUpdateCallback() {
override fun onInstallUpdateError(errorCode: Int, errorMessage: String) {
super.onInstallUpdateError(errorCode, errorMessage)
@@ -2043,7 +2010,7 @@ fun InstallSystemUpdateScreen(onNavigateUp: () -> Unit) {
onClick = {
val executor = Executors.newCachedThreadPool()
try {
dpm.installSystemUpdate(receiver, uri!!, executor, callback)
Privilege.DPM.installSystemUpdate(Privilege.DAR, uri!!, executor, callback)
context.popToast(R.string.start_install_system_update)
} catch(e: Exception) {
errorMessage = e.message

View File

@@ -55,8 +55,8 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.bintianqi.owndroid.HorizontalPadding
import com.bintianqi.owndroid.Privilege
import com.bintianqi.owndroid.R
import com.bintianqi.owndroid.myPrivilege
import com.bintianqi.owndroid.showOperationResultToast
import com.bintianqi.owndroid.ui.FunctionItem
import com.bintianqi.owndroid.ui.MyLazyScaffold
@@ -77,7 +77,7 @@ data class Restriction(
@RequiresApi(24)
@Composable
fun UserRestrictionScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
val privilege by myPrivilege.collectAsStateWithLifecycle()
val privilege by Privilege.status.collectAsStateWithLifecycle()
val sb = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
fun navigateToOptions(title: Int, items: List<Restriction>) {
onNavigate(UserRestrictionOptions(title, items))
@@ -147,11 +147,9 @@ fun UserRestrictionOptionsScreen(
data: UserRestrictionOptions, onNavigateUp: () -> Unit
) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val status = remember { mutableStateMapOf<String, Boolean>() }
fun refresh() {
val restrictions = dpm.getUserRestrictions(receiver)
val restrictions = Privilege.DPM.getUserRestrictions(Privilege.DAR)
data.items.forEach {
status.put(it.id, restrictions.getBoolean(it.id))
}
@@ -178,9 +176,9 @@ fun UserRestrictionOptionsScreen(
{
try {
if (it) {
dpm.addUserRestriction(receiver, restriction.id)
Privilege.DPM.addUserRestriction(Privilege.DAR, restriction.id)
} else {
dpm.clearUserRestriction(receiver, restriction.id)
Privilege.DPM.clearUserRestriction(Privilege.DAR, restriction.id)
}
} catch (e: Exception) {
e.printStackTrace()
@@ -288,11 +286,9 @@ object RestrictionData {
@Composable
fun UserRestrictionEditorScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val list = remember { mutableStateListOf<String>() }
fun refresh() {
val restrictions = dpm.getUserRestrictions(receiver)
val restrictions = Privilege.DPM.getUserRestrictions(Privilege.DAR)
list.clear()
list.addAll(restrictions.keySet().filter { restrictions.getBoolean(it) })
}
@@ -315,7 +311,7 @@ fun UserRestrictionEditorScreen(onNavigateUp: () -> Unit) {
Text(it)
IconButton({
try {
dpm.clearUserRestriction(receiver, it)
Privilege.DPM.clearUserRestriction(Privilege.DAR, it)
} catch (e: Exception) {
e.printStackTrace()
context.showOperationResultToast(false)
@@ -330,7 +326,7 @@ fun UserRestrictionEditorScreen(onNavigateUp: () -> Unit) {
var input by remember { mutableStateOf("") }
fun add() {
try {
dpm.addUserRestriction(receiver, input)
Privilege.DPM.addUserRestriction(Privilege.DAR, input)
input = ""
} catch (e: Exception) {
e.printStackTrace()

View File

@@ -62,8 +62,8 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.bintianqi.owndroid.HorizontalPadding
import com.bintianqi.owndroid.Privilege
import com.bintianqi.owndroid.R
import com.bintianqi.owndroid.myPrivilege
import com.bintianqi.owndroid.parseTimestamp
import com.bintianqi.owndroid.popToast
import com.bintianqi.owndroid.showOperationResultToast
@@ -87,9 +87,7 @@ import kotlinx.serialization.Serializable
@Composable
fun UsersScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val privilege by myPrivilege.collectAsStateWithLifecycle()
val privilege by Privilege.status.collectAsStateWithLifecycle()
var dialog by remember { mutableIntStateOf(0) }
MyScaffold(R.string.users, onNavigateUp, 0.dp) {
if(VERSION.SDK_INT >= 28 && privilege.profile && privilege.affiliated) {
@@ -134,7 +132,7 @@ fun UsersScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
text = {
if(dialog == 1) {
val um = context.getSystemService(Context.USER_SERVICE) as UserManager
val list = dpm.getSecondaryUsers(receiver)
val list = Privilege.DPM.getSecondaryUsers(Privilege.DAR)
if(list.isEmpty()) {
Text(stringResource(R.string.no_secondary_users))
} else {
@@ -148,7 +146,7 @@ fun UsersScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
TextButton(
onClick = {
if(dialog == 2) {
val result = dpm.logoutUser(receiver)
val result = Privilege.DPM.logoutUser(Privilege.DAR)
context.popToast(userOperationResultCode(result))
}
dialog = 0
@@ -170,12 +168,10 @@ fun UsersScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
@Composable
fun UsersOptionsScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
MyScaffold(R.string.options, onNavigateUp, 0.dp) {
if(VERSION.SDK_INT >= 28) {
SwitchItem(R.string.enable_logout, getState = { dpm.isLogoutEnabled }, onCheckedChange = { dpm.setLogoutEnabled(receiver, it) })
SwitchItem(R.string.enable_logout, getState = { Privilege.DPM.isLogoutEnabled },
onCheckedChange = { Privilege.DPM.setLogoutEnabled(Privilege.DAR, it) })
}
}
}
@@ -185,9 +181,7 @@ fun UsersOptionsScreen(onNavigateUp: () -> Unit) {
@Composable
fun UserInfoScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val privilege by myPrivilege.collectAsStateWithLifecycle()
val privilege by Privilege.status.collectAsStateWithLifecycle()
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
val user = Process.myUserHandle()
var infoDialog by remember { mutableIntStateOf(0) }
@@ -202,8 +196,8 @@ fun UserInfoScreen(onNavigateUp: () -> Unit) {
if(it != 0L) InfoItem(R.string.creation_time, parseTimestamp(it))
}
if (VERSION.SDK_INT >= 28) {
InfoItem(R.string.logout_enabled, dpm.isLogoutEnabled.yesOrNo)
InfoItem(R.string.ephemeral_user, dpm.isEphemeralUser(receiver).yesOrNo)
InfoItem(R.string.logout_enabled, Privilege.DPM.isLogoutEnabled.yesOrNo)
InfoItem(R.string.ephemeral_user, Privilege.DPM.isEphemeralUser(Privilege.DAR).yesOrNo)
InfoItem(R.string.affiliated_user, privilege.affiliated.yesOrNo)
}
InfoItem(R.string.user_id, (Binder.getCallingUid() / 100000).toString())
@@ -226,8 +220,6 @@ fun UserInfoScreen(onNavigateUp: () -> Unit) {
fun UserOperationScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
val dpm = context.getDPM()
val receiver = context.getReceiver()
var input by remember { mutableStateOf("") }
val focusMgr = LocalFocusManager.current
var useUserId by remember { mutableStateOf(false) }
@@ -266,7 +258,7 @@ fun UserOperationScreen(onNavigateUp: () -> Unit) {
onClick = {
focusMgr.clearFocus()
withUserHandle {
val result = dpm.startUserInBackground(receiver, it)
val result = Privilege.DPM.startUserInBackground(Privilege.DAR, it)
context.popToast(userOperationResultCode(result))
}
},
@@ -280,7 +272,7 @@ fun UserOperationScreen(onNavigateUp: () -> Unit) {
Button(
onClick = {
focusMgr.clearFocus()
withUserHandle { context.showOperationResultToast(dpm.switchUser(receiver, it)) }
withUserHandle { context.showOperationResultToast(Privilege.DPM.switchUser(Privilege.DAR, it)) }
},
enabled = legalInput,
modifier = Modifier.fillMaxWidth()
@@ -293,7 +285,7 @@ fun UserOperationScreen(onNavigateUp: () -> Unit) {
onClick = {
focusMgr.clearFocus()
withUserHandle {
val result = dpm.stopUser(receiver, it)
val result = Privilege.DPM.stopUser(Privilege.DAR, it)
context.popToast(userOperationResultCode(result))
}
},
@@ -308,7 +300,7 @@ fun UserOperationScreen(onNavigateUp: () -> Unit) {
onClick = {
focusMgr.clearFocus()
withUserHandle {
if(dpm.removeUser(receiver, it)) {
if(Privilege.DPM.removeUser(Privilege.DAR, it)) {
context.showOperationResultToast(true)
input = ""
} else {
@@ -332,8 +324,6 @@ fun UserOperationScreen(onNavigateUp: () -> Unit) {
fun CreateUserScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
val dpm = context.getDPM()
val receiver = context.getReceiver()
val focusMgr = LocalFocusManager.current
var userName by remember { mutableStateOf("") }
var creating by remember { mutableStateOf(false) }
@@ -369,7 +359,7 @@ fun CreateUserScreen(onNavigateUp: () -> Unit) {
creating = true
coroutine.launch(Dispatchers.IO) {
try {
val uh = dpm.createAndManageUser(receiver, userName, receiver, null, flag)
val uh = Privilege.DPM.createAndManageUser(Privilege.DAR, userName, Privilege.DAR, null, flag)
withContext(Dispatchers.Main) {
createdUserSerialNumber = userManager.getSerialNumberForUser(uh)
}
@@ -408,14 +398,12 @@ fun CreateUserScreen(onNavigateUp: () -> Unit) {
@Composable
fun AffiliationIdScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val focusMgr = LocalFocusManager.current
var input by remember { mutableStateOf("") }
val list = remember { mutableStateListOf<String>() }
val refreshIds = {
list.clear()
list.addAll(dpm.getAffiliationIds(receiver))
list.addAll(Privilege.DPM.getAffiliationIds(Privilege.DAR))
}
LaunchedEffect(Unit) { refreshIds() }
MyScaffold(R.string.affiliation_id, onNavigateUp) {
@@ -449,7 +437,7 @@ fun AffiliationIdScreen(onNavigateUp: () -> Unit) {
Button(
onClick = {
list.removeAll(setOf(""))
dpm.setAffiliationIds(receiver, list.toSet())
Privilege.DPM.setAffiliationIds(Privilege.DAR, list.toSet())
context.showOperationResultToast(true)
refreshIds()
},
@@ -466,8 +454,6 @@ fun AffiliationIdScreen(onNavigateUp: () -> Unit) {
@Composable
fun ChangeUsernameScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val focusMgr = LocalFocusManager.current
var inputUsername by remember { mutableStateOf("") }
MyScaffold(R.string.change_username, onNavigateUp) {
@@ -482,7 +468,7 @@ fun ChangeUsernameScreen(onNavigateUp: () -> Unit) {
Spacer(Modifier.padding(vertical = 5.dp))
Button(
onClick = {
dpm.setProfileName(receiver, inputUsername)
Privilege.DPM.setProfileName(Privilege.DAR, inputUsername)
context.showOperationResultToast(true)
},
modifier = Modifier.fillMaxWidth()
@@ -490,7 +476,7 @@ fun ChangeUsernameScreen(onNavigateUp: () -> Unit) {
Text(stringResource(R.string.apply))
}
Button(
onClick = { dpm.setProfileName(receiver,null) },
onClick = { Privilege.DPM.setProfileName(Privilege.DAR, null) },
modifier = Modifier.fillMaxWidth()
) {
Text(stringResource(R.string.reset))
@@ -504,14 +490,12 @@ fun ChangeUsernameScreen(onNavigateUp: () -> Unit) {
@Composable
fun UserSessionMessageScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val focusMgr = LocalFocusManager.current
var start by remember { mutableStateOf("") }
var end by remember { mutableStateOf("") }
val refreshMsg = {
start = dpm.getStartUserSessionMessage(receiver)?.toString() ?: ""
end = dpm.getEndUserSessionMessage(receiver)?.toString() ?: ""
start = Privilege.DPM.getStartUserSessionMessage(Privilege.DAR)?.toString() ?: ""
end = Privilege.DPM.getEndUserSessionMessage(Privilege.DAR)?.toString() ?: ""
}
LaunchedEffect(Unit) { refreshMsg() }
MyScaffold(R.string.user_session_msg, onNavigateUp) {
@@ -526,7 +510,7 @@ fun UserSessionMessageScreen(onNavigateUp: () -> Unit) {
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
Button(
onClick = {
dpm.setStartUserSessionMessage(receiver,start)
Privilege.DPM.setStartUserSessionMessage(Privilege.DAR, start)
refreshMsg()
},
modifier = Modifier.fillMaxWidth(0.49F)
@@ -535,7 +519,7 @@ fun UserSessionMessageScreen(onNavigateUp: () -> Unit) {
}
Button(
onClick = {
dpm.setStartUserSessionMessage(receiver,null)
Privilege.DPM.setStartUserSessionMessage(Privilege.DAR, null)
refreshMsg()
context.showOperationResultToast(true)
},
@@ -556,7 +540,7 @@ fun UserSessionMessageScreen(onNavigateUp: () -> Unit) {
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
Button(
onClick = {
dpm.setEndUserSessionMessage(receiver,end)
Privilege.DPM.setEndUserSessionMessage(Privilege.DAR, end)
refreshMsg()
context.showOperationResultToast(true)
},
@@ -566,7 +550,7 @@ fun UserSessionMessageScreen(onNavigateUp: () -> Unit) {
}
Button(
onClick = {
dpm.setEndUserSessionMessage(receiver,null)
Privilege.DPM.setEndUserSessionMessage(Privilege.DAR, null)
refreshMsg()
context.showOperationResultToast(true)
},
@@ -594,7 +578,7 @@ private fun ChangeUserIconDialog(bitmap: Bitmap, onClose: () -> Unit) {
},
confirmButton = {
TextButton({
context.getDPM().setUserIcon(context.getReceiver(), bitmap)
Privilege.DPM.setUserIcon(Privilege.DAR, bitmap)
context.showOperationResultToast(true)
onClose()
}) {

View File

@@ -56,8 +56,9 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.bintianqi.owndroid.IUserService
import com.bintianqi.owndroid.MyAdminComponent
import com.bintianqi.owndroid.Privilege
import com.bintianqi.owndroid.R
import com.bintianqi.owndroid.myPrivilege
import com.bintianqi.owndroid.popToast
import com.bintianqi.owndroid.showOperationResultToast
import com.bintianqi.owndroid.ui.CheckBoxItem
@@ -72,7 +73,7 @@ import kotlinx.serialization.Serializable
@Composable
fun WorkProfileScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
val privilege by myPrivilege.collectAsStateWithLifecycle()
val privilege by Privilege.status.collectAsStateWithLifecycle()
MyScaffold(R.string.work_profile, onNavigateUp, 0.dp) {
if(VERSION.SDK_INT >= 30 && !privilege.org) {
FunctionItem(R.string.org_owned_work_profile, icon = R.drawable.corporate_fare_fill0) { onNavigate(OrganizationOwnedProfile) }
@@ -90,7 +91,6 @@ fun WorkProfileScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
@Composable
fun CreateWorkProfileScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val receiver = context.getReceiver()
val focusMgr = LocalFocusManager.current
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { }
MyScaffold(R.string.create_work_profile, onNavigateUp) {
@@ -133,7 +133,7 @@ fun CreateWorkProfileScreen(onNavigateUp: () -> Unit) {
try {
val intent = Intent(ACTION_PROVISION_MANAGED_PROFILE)
if(VERSION.SDK_INT >= 23) {
intent.putExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,receiver)
intent.putExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME, MyAdminComponent)
} else {
intent.putExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME, context.packageName)
}
@@ -201,26 +201,24 @@ val activateOrgProfileCommand = "dpm mark-profile-owner-on-organization-owned-de
@Composable
fun SuspendPersonalAppScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val focusMgr = LocalFocusManager.current
var suspend by remember { mutableStateOf(dpm.getPersonalAppsSuspendedReasons(receiver) != PERSONAL_APPS_NOT_SUSPENDED) }
var suspend by remember { mutableStateOf(Privilege.DPM.getPersonalAppsSuspendedReasons(Privilege.DAR) != PERSONAL_APPS_NOT_SUSPENDED) }
MyScaffold(R.string.suspend_personal_app, onNavigateUp) {
SwitchItem(R.string.suspend_personal_app, state = suspend,
onCheckedChange = {
dpm.setPersonalAppsSuspended(receiver,it)
suspend = dpm.getPersonalAppsSuspendedReasons(receiver) != PERSONAL_APPS_NOT_SUSPENDED
Privilege.DPM.setPersonalAppsSuspended(Privilege.DAR, it)
suspend = Privilege.DPM.getPersonalAppsSuspendedReasons(Privilege.DAR) != PERSONAL_APPS_NOT_SUSPENDED
}, padding = false
)
var time by remember { mutableStateOf("") }
time = dpm.getManagedProfileMaximumTimeOff(receiver).toString()
time = Privilege.DPM.getManagedProfileMaximumTimeOff(Privilege.DAR).toString()
Spacer(Modifier.padding(vertical = 10.dp))
Text(text = stringResource(R.string.profile_max_time_off), style = typography.titleLarge)
Text(text = stringResource(R.string.profile_max_time_out_desc))
Text(
text = stringResource(
R.string.personal_app_suspended_because_timeout,
dpm.getPersonalAppsSuspendedReasons(receiver) == PERSONAL_APPS_SUSPENDED_PROFILE_TIMEOUT
Privilege.DPM.getPersonalAppsSuspendedReasons(Privilege.DAR) == PERSONAL_APPS_SUSPENDED_PROFILE_TIMEOUT
)
)
OutlinedTextField(
@@ -232,7 +230,7 @@ fun SuspendPersonalAppScreen(onNavigateUp: () -> Unit) {
Text(text = stringResource(R.string.cannot_less_than_72_hours))
Button(
onClick = {
dpm.setManagedProfileMaximumTimeOff(receiver,time.toLong())
Privilege.DPM.setManagedProfileMaximumTimeOff(Privilege.DAR, time.toLong())
context.showOperationResultToast(true)
},
modifier = Modifier.fillMaxWidth()
@@ -248,8 +246,6 @@ fun SuspendPersonalAppScreen(onNavigateUp: () -> Unit) {
@Composable
fun CrossProfileIntentFilterScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val focusMgr = LocalFocusManager.current
MyScaffold(R.string.intent_filter, onNavigateUp) {
var action by remember { mutableStateOf("") }
@@ -263,7 +259,7 @@ fun CrossProfileIntentFilterScreen(onNavigateUp: () -> Unit) {
Spacer(Modifier.padding(vertical = 5.dp))
Button(
onClick = {
dpm.addCrossProfileIntentFilter(receiver, IntentFilter(action), FLAG_PARENT_CAN_ACCESS_MANAGED)
Privilege.DPM.addCrossProfileIntentFilter(Privilege.DAR, IntentFilter(action), FLAG_PARENT_CAN_ACCESS_MANAGED)
context.showOperationResultToast(true)
},
modifier = Modifier.fillMaxWidth()
@@ -272,7 +268,7 @@ fun CrossProfileIntentFilterScreen(onNavigateUp: () -> Unit) {
}
Button(
onClick = {
dpm.addCrossProfileIntentFilter(receiver, IntentFilter(action), FLAG_MANAGED_CAN_ACCESS_PARENT)
Privilege.DPM.addCrossProfileIntentFilter(Privilege.DAR, IntentFilter(action), FLAG_MANAGED_CAN_ACCESS_PARENT)
context.showOperationResultToast(true)
},
modifier = Modifier.fillMaxWidth()
@@ -282,7 +278,7 @@ fun CrossProfileIntentFilterScreen(onNavigateUp: () -> Unit) {
Spacer(Modifier.padding(vertical = 2.dp))
Button(
onClick = {
dpm.clearCrossProfileIntentFilters(receiver)
Privilege.DPM.clearCrossProfileIntentFilters(Privilege.DAR)
context.showOperationResultToast(true)
},
modifier = Modifier.fillMaxWidth()
@@ -297,8 +293,6 @@ fun CrossProfileIntentFilterScreen(onNavigateUp: () -> Unit) {
@Composable
fun DeleteWorkProfileScreen(onNavigateUp: () -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val focusMgr = LocalFocusManager.current
var flag by remember { mutableIntStateOf(0) }
var warning by remember { mutableStateOf(false) }
@@ -342,9 +336,9 @@ fun DeleteWorkProfileScreen(onNavigateUp: () -> Unit) {
TextButton(
onClick = {
if(VERSION.SDK_INT >= 28 && !silent) {
dpm.wipeData(flag, reason)
Privilege.DPM.wipeData(flag, reason)
} else {
dpm.wipeData(flag)
Privilege.DPM.wipeData(flag)
}
},
colors = ButtonDefaults.textButtonColors(contentColor = colorScheme.error)