mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-23 19:15:58 +00:00
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:
@@ -24,6 +24,7 @@
|
||||
android:enableOnBackInvokedCallback="true"
|
||||
android:testOnly="false"
|
||||
android:manageSpaceActivity=".ManageSpaceActivity"
|
||||
android:name=".MyApplication"
|
||||
tools:targetApi="35">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
|
||||
@@ -5,19 +5,14 @@ import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import com.bintianqi.owndroid.dpm.getDPM
|
||||
import com.bintianqi.owndroid.dpm.getReceiver
|
||||
|
||||
class ApiReceiver: BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
val requestKey = intent.getStringExtra("key")
|
||||
var log = "OwnDroid API request received. action: ${intent.action}\nkey: $requestKey"
|
||||
val sp = SharedPrefs(context)
|
||||
if(!sp.isApiEnabled) return
|
||||
val key = sp.apiKey
|
||||
if(!SP.isApiEnabled) return
|
||||
val key = SP.apiKey
|
||||
if(!key.isNullOrEmpty() && key == requestKey) {
|
||||
val dpm = context.getDPM()
|
||||
val receiver = context.getReceiver()
|
||||
val app = intent.getStringExtra("package")
|
||||
val permission = intent.getStringExtra("permission")
|
||||
val restriction = intent.getStringExtra("restriction")
|
||||
@@ -26,32 +21,32 @@ class ApiReceiver: BroadcastReceiver() {
|
||||
try {
|
||||
@SuppressWarnings("NewApi")
|
||||
val ok = when(intent.action?.removePrefix("com.bintianqi.owndroid.action.")) {
|
||||
"HIDE" -> dpm.setApplicationHidden(receiver, app, true)
|
||||
"UNHIDE" -> dpm.setApplicationHidden(receiver, app, false)
|
||||
"SUSPEND" -> dpm.setPackagesSuspended(receiver, arrayOf(app), true).isEmpty()
|
||||
"UNSUSPEND" -> dpm.setPackagesSuspended(receiver, arrayOf(app), false).isEmpty()
|
||||
"ADD_USER_RESTRICTION" -> { dpm.addUserRestriction(receiver, restriction); true }
|
||||
"CLEAR_USER_RESTRICTION" -> { dpm.clearUserRestriction(receiver, restriction); true }
|
||||
"HIDE" -> Privilege.DPM.setApplicationHidden(Privilege.DAR, app, true)
|
||||
"UNHIDE" -> Privilege.DPM.setApplicationHidden(Privilege.DAR, app, false)
|
||||
"SUSPEND" -> Privilege.DPM.setPackagesSuspended(Privilege.DAR, arrayOf(app), true).isEmpty()
|
||||
"UNSUSPEND" -> Privilege.DPM.setPackagesSuspended(Privilege.DAR, arrayOf(app), false).isEmpty()
|
||||
"ADD_USER_RESTRICTION" -> { Privilege.DPM.addUserRestriction(Privilege.DAR, restriction); true }
|
||||
"CLEAR_USER_RESTRICTION" -> { Privilege.DPM.clearUserRestriction(Privilege.DAR, restriction); true }
|
||||
"SET_PERMISSION_DEFAULT" -> {
|
||||
dpm.setPermissionGrantState(
|
||||
receiver, app!!, permission!!,
|
||||
Privilege.DPM.setPermissionGrantState(
|
||||
Privilege.DAR, app!!, permission!!,
|
||||
DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT
|
||||
)
|
||||
}
|
||||
"SET_PERMISSION_GRANTED" -> {
|
||||
dpm.setPermissionGrantState(
|
||||
receiver, app!!, permission!!,
|
||||
Privilege.DPM.setPermissionGrantState(
|
||||
Privilege.DAR, app!!, permission!!,
|
||||
DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED
|
||||
)
|
||||
}
|
||||
"SET_PERMISSION_DENIED" -> {
|
||||
dpm.setPermissionGrantState(
|
||||
receiver, app!!, permission!!,
|
||||
Privilege.DPM.setPermissionGrantState(
|
||||
Privilege.DAR, app!!, permission!!,
|
||||
DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED
|
||||
)
|
||||
}
|
||||
"LOCK" -> { dpm.lockNow(); true }
|
||||
"REBOOT" -> { dpm.reboot(receiver); true }
|
||||
"LOCK" -> { Privilege.DPM.lockNow(); true }
|
||||
"REBOOT" -> { Privilege.DPM.reboot(Privilege.DAR); true }
|
||||
else -> {
|
||||
log += "\nInvalid action"
|
||||
false
|
||||
|
||||
@@ -125,7 +125,6 @@ private fun AppInstaller(
|
||||
result: Intent? = null,
|
||||
onResultDialogClose: () -> Unit = {}
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
var appLockDialog by rememberSaveable { mutableStateOf(false) }
|
||||
val coroutine = rememberCoroutineScope()
|
||||
Scaffold(
|
||||
@@ -142,7 +141,7 @@ private fun AppInstaller(
|
||||
else Icon(Icons.Default.PlayArrow, null)
|
||||
},
|
||||
onClick = {
|
||||
if(SharedPrefs(context).lockPasswordHash.isNullOrEmpty()) onStartInstall() else appLockDialog = true
|
||||
if(SP.lockPasswordHash.isNullOrEmpty()) onStartInstall() else appLockDialog = true
|
||||
},
|
||||
expanded = !installing
|
||||
)
|
||||
|
||||
@@ -44,11 +44,10 @@ import androidx.compose.ui.window.DialogProperties
|
||||
fun AppLockDialog(onSucceed: () -> Unit, onDismiss: () -> Unit) = Dialog(onDismiss, DialogProperties(true, false)) {
|
||||
val context = LocalContext.current
|
||||
val fm = LocalFocusManager.current
|
||||
val sp = SharedPrefs(context)
|
||||
var input by remember { mutableStateOf("") }
|
||||
var isError by remember { mutableStateOf(false) }
|
||||
fun unlock() {
|
||||
if(input.hash() == sp.lockPasswordHash) {
|
||||
if(input.hash() == SP.lockPasswordHash) {
|
||||
fm.clearFocus()
|
||||
onSucceed()
|
||||
} else {
|
||||
@@ -56,7 +55,7 @@ fun AppLockDialog(onSucceed: () -> Unit, onDismiss: () -> Unit) = Dialog(onDismi
|
||||
}
|
||||
}
|
||||
LaunchedEffect(Unit) {
|
||||
if (Build.VERSION.SDK_INT >= 28 && sp.biometricsUnlock) startBiometricsUnlock(context, onSucceed)
|
||||
if (Build.VERSION.SDK_INT >= 28 && SP.biometricsUnlock) startBiometricsUnlock(context, onSucceed)
|
||||
}
|
||||
BackHandler(onBack = onDismiss)
|
||||
Card(Modifier.pointerInput(Unit) { detectTapGestures(onTap = { fm.clearFocus() }) }, shape = RoundedCornerShape(16.dp)) {
|
||||
@@ -70,7 +69,7 @@ fun AppLockDialog(onSucceed: () -> Unit, onDismiss: () -> Unit) = Dialog(onDismi
|
||||
),
|
||||
keyboardActions = KeyboardActions({ fm.clearFocus() }, { unlock() })
|
||||
)
|
||||
if(Build.VERSION.SDK_INT >= 28 && sp.biometricsUnlock) {
|
||||
if(Build.VERSION.SDK_INT >= 28 && SP.biometricsUnlock) {
|
||||
FilledTonalIconButton({ startBiometricsUnlock(context, onSucceed) }, Modifier.padding(start = 4.dp)) {
|
||||
Icon(painterResource(R.drawable.fingerprint_fill0), null)
|
||||
}
|
||||
|
||||
@@ -11,14 +11,8 @@ import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.activity.viewModels
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Checkbox
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
@@ -27,7 +21,6 @@ import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
@@ -51,14 +44,14 @@ const val DHIZUKU_CLIENTS_FILE = "dhizuku_clients.json"
|
||||
class MyDhizukuProvider(): DhizukuProvider() {
|
||||
override fun onCreateService(client: IDhizukuClient): DhizukuService? {
|
||||
Log.d(TAG, "Creating MyDhizukuService")
|
||||
return if (SharedPrefs(context!!).dhizukuServer) MyDhizukuService(context!!, MyAdminComponent, client) else null
|
||||
return if (SP.dhizukuServer) MyDhizukuService(context!!, MyAdminComponent, client) else null
|
||||
}
|
||||
}
|
||||
|
||||
class MyDhizukuService(context: Context, admin: ComponentName, client: IDhizukuClient) :
|
||||
DhizukuService(context, admin, client) {
|
||||
override fun checkCallingPermission(func: String?, callingUid: Int, callingPid: Int): Boolean {
|
||||
if (!SharedPrefs(mContext).dhizukuServer) return false
|
||||
if (!SP.dhizukuServer) return false
|
||||
val pm = mContext.packageManager
|
||||
val packageInfo = pm.getPackageInfo(
|
||||
pm.getNameForUid(callingUid) ?: return false,
|
||||
@@ -87,7 +80,7 @@ class DhizukuActivity : ComponentActivity() {
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
if (!SharedPrefs(this).dhizukuServer) {
|
||||
if (!SP.dhizukuServer) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
@@ -145,7 +138,7 @@ class DhizukuActivity : ComponentActivity() {
|
||||
}
|
||||
}
|
||||
TextButton({
|
||||
if (SharedPrefs(this).lockPasswordHash.isNullOrEmpty()) {
|
||||
if (SP.lockPasswordHash.isNullOrEmpty()) {
|
||||
close(true)
|
||||
} else {
|
||||
appLockDialog = true
|
||||
|
||||
@@ -54,7 +54,6 @@ import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleEventObserver
|
||||
import androidx.lifecycle.compose.LocalLifecycleOwner
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
@@ -235,17 +234,10 @@ import com.bintianqi.owndroid.dpm.WorkModes
|
||||
import com.bintianqi.owndroid.dpm.WorkModesScreen
|
||||
import com.bintianqi.owndroid.dpm.WorkProfile
|
||||
import com.bintianqi.owndroid.dpm.WorkProfileScreen
|
||||
import com.bintianqi.owndroid.dpm.checkPrivilege
|
||||
import com.bintianqi.owndroid.dpm.dhizukuErrorStatus
|
||||
import com.bintianqi.owndroid.dpm.getDPM
|
||||
import com.bintianqi.owndroid.dpm.getReceiver
|
||||
import com.bintianqi.owndroid.dpm.setDefaultAffiliationID
|
||||
import com.bintianqi.owndroid.ui.Animations
|
||||
import com.bintianqi.owndroid.ui.theme.OwnDroidTheme
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.serialization.Serializable
|
||||
import org.lsposed.hiddenapibypass.HiddenApiBypass
|
||||
import java.util.Locale
|
||||
|
||||
@ExperimentalMaterial3Api
|
||||
@@ -254,12 +246,9 @@ class MainActivity : FragmentActivity() {
|
||||
enableEdgeToEdge()
|
||||
super.onCreate(savedInstanceState)
|
||||
val context = applicationContext
|
||||
if (VERSION.SDK_INT >= 28) HiddenApiBypass.setHiddenApiExemptions("")
|
||||
val locale = context.resources?.configuration?.locale
|
||||
zhCN = locale == Locale.SIMPLIFIED_CHINESE || locale == Locale.CHINESE || locale == Locale.CHINA
|
||||
val vm by viewModels<MyViewModel>()
|
||||
checkPrivilege(this)
|
||||
lifecycleScope.launch { delay(5000); setDefaultAffiliationID(context) }
|
||||
setContent {
|
||||
var appLockDialog by rememberSaveable { mutableStateOf(false) }
|
||||
val theme by vm.theme.collectAsStateWithLifecycle()
|
||||
@@ -274,7 +263,6 @@ class MainActivity : FragmentActivity() {
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
checkPrivilege(this)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -284,14 +272,12 @@ class MainActivity : FragmentActivity() {
|
||||
fun Home(vm: MyViewModel, onLock: () -> Unit) {
|
||||
val navController = rememberNavController()
|
||||
val context = LocalContext.current
|
||||
val receiver = context.getReceiver()
|
||||
val focusMgr = LocalFocusManager.current
|
||||
val lifecycleOwner = LocalLifecycleOwner.current
|
||||
fun navigateUp() { navController.navigateUp() }
|
||||
fun navigate(destination: Any) { navController.navigate(destination) }
|
||||
LaunchedEffect(Unit) {
|
||||
val privilege = myPrivilege.value
|
||||
if(!privilege.device && !privilege.profile) {
|
||||
if(!Privilege.status.value.activated) {
|
||||
navController.navigate(WorkModes(false)) {
|
||||
popUpTo<Home> { inclusive = true }
|
||||
}
|
||||
@@ -385,7 +371,7 @@ fun Home(vm: MyViewModel, onLock: () -> Unit) {
|
||||
AppChooserScreen(it.toRoute(), { dest ->
|
||||
if(dest == null) navigateUp() else navigate(ApplicationDetails(dest))
|
||||
}, {
|
||||
SharedPrefs(context).applicationsListView = false
|
||||
SP.applicationsListView = false
|
||||
navController.navigate(ApplicationsFeatures) {
|
||||
popUpTo(Home)
|
||||
}
|
||||
@@ -393,7 +379,7 @@ fun Home(vm: MyViewModel, onLock: () -> Unit) {
|
||||
}
|
||||
composable<ApplicationsFeatures> {
|
||||
ApplicationsFeaturesScreen(::navigateUp, ::navigate) {
|
||||
SharedPrefs(context).applicationsListView = true
|
||||
SP.applicationsListView = true
|
||||
navController.navigate(ApplicationsList(true)) {
|
||||
popUpTo(Home)
|
||||
}
|
||||
@@ -451,7 +437,7 @@ fun Home(vm: MyViewModel, onLock: () -> Unit) {
|
||||
composable<SettingsOptions> { SettingsOptionsScreen(::navigateUp) }
|
||||
composable<Appearance> {
|
||||
val theme by vm.theme.collectAsStateWithLifecycle()
|
||||
AppearanceScreen(::navigateUp, theme) { vm.theme.value = it }
|
||||
AppearanceScreen(::navigateUp, theme, vm::changeTheme)
|
||||
}
|
||||
composable<AppLockSettings> { AppLockSettingsScreen(::navigateUp) }
|
||||
composable<ApiSettings> { ApiSettings(::navigateUp) }
|
||||
@@ -459,11 +445,10 @@ fun Home(vm: MyViewModel, onLock: () -> Unit) {
|
||||
composable<About> { AboutScreen(::navigateUp) }
|
||||
}
|
||||
DisposableEffect(lifecycleOwner) {
|
||||
val sp = SharedPrefs(context)
|
||||
val observer = LifecycleEventObserver { _, event ->
|
||||
if (
|
||||
(event == Lifecycle.Event.ON_CREATE && !sp.lockPasswordHash.isNullOrEmpty()) ||
|
||||
(event == Lifecycle.Event.ON_RESUME && sp.lockWhenLeaving)
|
||||
(event == Lifecycle.Event.ON_CREATE && !SP.lockPasswordHash.isNullOrEmpty()) ||
|
||||
(event == Lifecycle.Event.ON_RESUME && SP.lockWhenLeaving)
|
||||
) {
|
||||
onLock()
|
||||
}
|
||||
@@ -474,18 +459,16 @@ fun Home(vm: MyViewModel, onLock: () -> Unit) {
|
||||
}
|
||||
}
|
||||
LaunchedEffect(Unit) {
|
||||
val dpm = context.getDPM()
|
||||
val sp = SharedPrefs(context)
|
||||
val profileNotActivated = !sp.managedProfileActivated && myPrivilege.value.work
|
||||
val profileNotActivated = !SP.managedProfileActivated && Privilege.status.value.work
|
||||
if(profileNotActivated) {
|
||||
dpm.setProfileEnabled(receiver)
|
||||
sp.managedProfileActivated = true
|
||||
Privilege.DPM.setProfileEnabled(Privilege.DAR)
|
||||
SP.managedProfileActivated = true
|
||||
context.popToast(R.string.work_profile_activated)
|
||||
}
|
||||
}
|
||||
DhizukuErrorDialog {
|
||||
dhizukuErrorStatus.value = 0
|
||||
updatePrivilege(context)
|
||||
Privilege.updateStatus()
|
||||
navController.navigate(WorkModes(false)) {
|
||||
popUpTo<Home> { inclusive = true }
|
||||
launchSingleTop = true
|
||||
@@ -498,8 +481,7 @@ fun Home(vm: MyViewModel, onLock: () -> Unit) {
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
private fun HomeScreen(onNavigate: (Any) -> Unit) {
|
||||
val context = LocalContext.current
|
||||
val privilege by myPrivilege.collectAsStateWithLifecycle()
|
||||
val privilege by Privilege.status.collectAsStateWithLifecycle()
|
||||
val sb = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
|
||||
Scaffold(
|
||||
Modifier.nestedScroll(sb.nestedScrollConnection),
|
||||
@@ -527,7 +509,7 @@ private fun HomeScreen(onNavigate: (Any) -> Unit) {
|
||||
}
|
||||
if(privilege.device || privilege.profile) {
|
||||
HomePageItem(R.string.applications, R.drawable.apps_fill0) {
|
||||
onNavigate(if(SharedPrefs(context).applicationsListView) ApplicationsList(true) else ApplicationsFeatures)
|
||||
onNavigate(if(SP.applicationsListView) ApplicationsList(true) else ApplicationsFeatures)
|
||||
}
|
||||
if(VERSION.SDK_INT >= 24) {
|
||||
HomePageItem(R.string.user_restriction, R.drawable.person_off) { onNavigate(UserRestriction) }
|
||||
@@ -567,9 +549,8 @@ fun HomePageItem(name: Int, imgVector: Int, onClick: () -> Unit) {
|
||||
private fun DhizukuErrorDialog(onClose: () -> Unit) {
|
||||
val status by dhizukuErrorStatus.collectAsState()
|
||||
if (status != 0) {
|
||||
val sp = SharedPrefs(LocalContext.current)
|
||||
LaunchedEffect(Unit) {
|
||||
sp.dhizuku = false
|
||||
SP.dhizuku = false
|
||||
}
|
||||
AlertDialog(
|
||||
onDismissRequest = {},
|
||||
@@ -580,14 +561,13 @@ private fun DhizukuErrorDialog(onClose: () -> Unit) {
|
||||
},
|
||||
title = { Text(stringResource(R.string.dhizuku)) },
|
||||
text = {
|
||||
var text = stringResource(
|
||||
val text = stringResource(
|
||||
when(status){
|
||||
1 -> R.string.failed_to_init_dhizuku
|
||||
2 -> R.string.dhizuku_permission_not_granted
|
||||
else -> R.string.failed_to_init_dhizuku
|
||||
}
|
||||
)
|
||||
if(sp.dhizuku) text += "\n" + stringResource(R.string.dhizuku_mode_disabled)
|
||||
Text(text)
|
||||
},
|
||||
properties = DialogProperties(dismissOnBackPress = false, dismissOnClickOutside = false)
|
||||
|
||||
@@ -27,7 +27,7 @@ class ManageSpaceActivity: FragmentActivity() {
|
||||
setContent {
|
||||
val theme by vm.theme.collectAsStateWithLifecycle()
|
||||
OwnDroidTheme(theme) {
|
||||
var appLockDialog by remember { mutableStateOf(!SharedPrefs(this).lockPasswordHash.isNullOrEmpty()) }
|
||||
var appLockDialog by remember { mutableStateOf(!SP.lockPasswordHash.isNullOrEmpty()) }
|
||||
if(appLockDialog) {
|
||||
AppLockDialog({ appLockDialog = false }, ::finish)
|
||||
} else {
|
||||
|
||||
18
app/src/main/java/com/bintianqi/owndroid/MyApplication.kt
Normal file
18
app/src/main/java/com/bintianqi/owndroid/MyApplication.kt
Normal file
@@ -0,0 +1,18 @@
|
||||
package com.bintianqi.owndroid
|
||||
|
||||
import android.app.Application
|
||||
import android.os.Build.VERSION
|
||||
import org.lsposed.hiddenapibypass.HiddenApiBypass
|
||||
|
||||
class MyApplication : Application() {
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
if (VERSION.SDK_INT >= 28) HiddenApiBypass.setHiddenApiExemptions("")
|
||||
SP = SharedPrefs(applicationContext)
|
||||
Privilege.initialize(applicationContext)
|
||||
Privilege.updateStatus()
|
||||
}
|
||||
}
|
||||
|
||||
lateinit var SP: SharedPrefs
|
||||
private set
|
||||
@@ -2,23 +2,15 @@ package com.bintianqi.owndroid
|
||||
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class MyViewModel(application: Application): AndroidViewModel(application) {
|
||||
val theme = MutableStateFlow(ThemeSettings())
|
||||
|
||||
init {
|
||||
val sp = SharedPrefs(application)
|
||||
theme.value = ThemeSettings(sp.materialYou, sp.darkTheme, sp.blackTheme)
|
||||
viewModelScope.launch {
|
||||
theme.collect {
|
||||
sp.materialYou = it.materialYou
|
||||
sp.darkTheme = it.darkTheme
|
||||
sp.blackTheme = it.blackTheme
|
||||
}
|
||||
}
|
||||
val theme = MutableStateFlow(ThemeSettings(SP.materialYou, SP.darkTheme, SP.blackTheme))
|
||||
fun changeTheme(newTheme: ThemeSettings) {
|
||||
theme.value = newTheme
|
||||
SP.materialYou = newTheme.materialYou
|
||||
SP.darkTheme = newTheme.darkTheme
|
||||
SP.blackTheme = newTheme.blackTheme
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,39 +1,64 @@
|
||||
package com.bintianqi.owndroid
|
||||
|
||||
import android.app.admin.DevicePolicyManager
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.os.Binder
|
||||
import android.os.Build
|
||||
import com.bintianqi.owndroid.dpm.getDPM
|
||||
import com.bintianqi.owndroid.dpm.getReceiver
|
||||
import com.bintianqi.owndroid.dpm.isDeviceOwner
|
||||
import com.bintianqi.owndroid.dpm.isProfileOwner
|
||||
import com.bintianqi.owndroid.dpm.binderWrapperDevicePolicyManager
|
||||
import com.bintianqi.owndroid.dpm.dhizukuErrorStatus
|
||||
import com.rosan.dhizuku.api.Dhizuku
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
class Privilege(
|
||||
val device: Boolean = false, // Device owner
|
||||
val profile: Boolean = false, // Profile owner
|
||||
val dhizuku: Boolean = false,
|
||||
val work: Boolean = false, // Work profile
|
||||
val org: Boolean = false, // Organization-owned work profile
|
||||
val affiliated: Boolean = false
|
||||
) {
|
||||
val primary = Binder.getCallingUid() / 100000 == 0 // Primary user
|
||||
object Privilege {
|
||||
fun initialize(context: Context) {
|
||||
if (SP.dhizuku) {
|
||||
Dhizuku.init(context)
|
||||
val hasPermission = try {
|
||||
Dhizuku.isPermissionGranted()
|
||||
} catch(_: Exception) {
|
||||
false
|
||||
}
|
||||
if (hasPermission) {
|
||||
val dhizukuDpm = binderWrapperDevicePolicyManager(context)
|
||||
if (dhizukuDpm != null) {
|
||||
DPM = dhizukuDpm
|
||||
DAR = Dhizuku.getOwnerComponent()
|
||||
return
|
||||
}
|
||||
}
|
||||
dhizukuErrorStatus.value = 2
|
||||
}
|
||||
DPM = context.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
|
||||
DAR = MyAdminComponent
|
||||
}
|
||||
lateinit var DPM: DevicePolicyManager
|
||||
private set
|
||||
lateinit var DAR: ComponentName
|
||||
private set
|
||||
|
||||
data class Status(
|
||||
val device: Boolean = false,
|
||||
val profile: Boolean = false,
|
||||
val dhizuku: Boolean = false,
|
||||
val work: Boolean = false,
|
||||
val org: Boolean = false,
|
||||
val affiliated: Boolean = false
|
||||
) {
|
||||
val activated = device || profile
|
||||
val primary = Binder.getCallingUid() / 100000 == 0 // Primary user
|
||||
}
|
||||
val status = MutableStateFlow(Status())
|
||||
fun updateStatus() {
|
||||
val profile = DPM.isProfileOwnerApp(DAR.packageName)
|
||||
val work = profile && Build.VERSION.SDK_INT >= 24 && DPM.isManagedProfile(DAR)
|
||||
status.value = Status(
|
||||
device = DPM.isDeviceOwnerApp(DAR.packageName),
|
||||
profile = profile,
|
||||
dhizuku = SP.dhizuku,
|
||||
work = work,
|
||||
org = work && Build.VERSION.SDK_INT >= 30 && DPM.isOrganizationOwnedDeviceWithManagedProfile,
|
||||
affiliated = Build.VERSION.SDK_INT >= 28 && DPM.isAffiliatedUser
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val myPrivilege = MutableStateFlow(Privilege())
|
||||
|
||||
fun updatePrivilege(context: Context) {
|
||||
val dpm = context.getDPM()
|
||||
val receiver = context.getReceiver()
|
||||
val profile = context.isProfileOwner
|
||||
val work = profile && Build.VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver)
|
||||
myPrivilege.value = Privilege(
|
||||
device = context.isDeviceOwner,
|
||||
profile = profile,
|
||||
dhizuku = SharedPrefs(context).dhizuku,
|
||||
work = work,
|
||||
org = work && Build.VERSION.SDK_INT >= 30 && dpm.isOrganizationOwnedDeviceWithManagedProfile,
|
||||
affiliated = Build.VERSION.SDK_INT >= 28 && dpm.isAffiliatedUser
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build.VERSION
|
||||
import android.os.PersistableBundle
|
||||
import android.os.UserHandle
|
||||
import android.os.UserManager
|
||||
import androidx.core.app.NotificationCompat
|
||||
@@ -35,13 +34,13 @@ class Receiver : DeviceAdminReceiver() {
|
||||
|
||||
override fun onEnabled(context: Context, intent: Intent) {
|
||||
super.onEnabled(context, intent)
|
||||
updatePrivilege(context)
|
||||
Privilege.updateStatus()
|
||||
handlePrivilegeChange(context)
|
||||
}
|
||||
|
||||
override fun onDisabled(context: Context, intent: Intent) {
|
||||
super.onDisabled(context, intent)
|
||||
updatePrivilege(context)
|
||||
Privilege.updateStatus()
|
||||
handlePrivilegeChange(context)
|
||||
}
|
||||
|
||||
@@ -74,11 +73,6 @@ class Receiver : DeviceAdminReceiver() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTransferOwnershipComplete(context: Context, bundle: PersistableBundle?) {
|
||||
super.onTransferOwnershipComplete(context, bundle)
|
||||
SharedPrefs(context).dhizuku = false
|
||||
}
|
||||
|
||||
override fun onLockTaskModeEntering(context: Context, intent: Intent, pkg: String) {
|
||||
super.onLockTaskModeEntering(context, intent, pkg)
|
||||
if(!NotificationUtils.checkPermission(context)) return
|
||||
|
||||
@@ -78,7 +78,7 @@ import kotlin.system.exitProcess
|
||||
@Composable
|
||||
fun SettingsScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
|
||||
val context = LocalContext.current
|
||||
val privilege by myPrivilege.collectAsStateWithLifecycle()
|
||||
val privilege by Privilege.status.collectAsStateWithLifecycle()
|
||||
val exportLogsLauncher = rememberLauncherForActivityResult(ActivityResultContracts.CreateDocument("text/plain")) {
|
||||
if(it != null) exportLogs(context, it)
|
||||
}
|
||||
@@ -145,17 +145,16 @@ fun SettingsScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
|
||||
@Composable
|
||||
fun SettingsOptionsScreen(onNavigateUp: () -> Unit) {
|
||||
val context = LocalContext.current
|
||||
val sp = SharedPrefs(context)
|
||||
MyScaffold(R.string.options, onNavigateUp, 0.dp) {
|
||||
SwitchItem(
|
||||
R.string.show_dangerous_features, icon = R.drawable.warning_fill0,
|
||||
getState = { sp.displayDangerousFeatures },
|
||||
onCheckedChange = { sp.displayDangerousFeatures = it }
|
||||
getState = { SP.displayDangerousFeatures },
|
||||
onCheckedChange = { SP.displayDangerousFeatures = it }
|
||||
)
|
||||
SwitchItem(
|
||||
R.string.shortcuts, icon = R.drawable.open_in_new,
|
||||
getState = { sp.shortcuts }, onCheckedChange = {
|
||||
sp.shortcuts = it
|
||||
getState = { SP.shortcuts }, onCheckedChange = {
|
||||
SP.shortcuts = it
|
||||
ShortcutManagerCompat.removeAllDynamicShortcuts(context)
|
||||
createShortcuts(context)
|
||||
}
|
||||
@@ -230,13 +229,12 @@ fun AppearanceScreen(onNavigateUp: () -> Unit, currentTheme: ThemeSettings, onTh
|
||||
@Composable
|
||||
fun AppLockSettingsScreen(onNavigateUp: () -> Unit) = MyScaffold(R.string.app_lock, onNavigateUp, 0.dp) {
|
||||
val fm = LocalFocusManager.current
|
||||
val sp = SharedPrefs(LocalContext.current)
|
||||
var password by remember { mutableStateOf("") }
|
||||
var confirmPassword by remember { mutableStateOf("") }
|
||||
var allowBiometrics by remember { mutableStateOf(sp.biometricsUnlock) }
|
||||
var lockWhenLeaving by remember { mutableStateOf(sp.lockWhenLeaving) }
|
||||
var allowBiometrics by remember { mutableStateOf(SP.biometricsUnlock) }
|
||||
var lockWhenLeaving by remember { mutableStateOf(SP.lockWhenLeaving) }
|
||||
val fr = FocusRequester()
|
||||
val alreadySet = !sp.lockPasswordHash.isNullOrEmpty()
|
||||
val alreadySet = !SP.lockPasswordHash.isNullOrEmpty()
|
||||
val isInputLegal = password.length !in 1..3 && (alreadySet || (password.isNotEmpty() && password.isNotBlank()))
|
||||
Column(Modifier.widthIn(max = 300.dp).align(Alignment.CenterHorizontally)) {
|
||||
OutlinedTextField(
|
||||
@@ -263,9 +261,9 @@ fun AppLockSettingsScreen(onNavigateUp: () -> Unit) = MyScaffold(R.string.app_lo
|
||||
Button(
|
||||
onClick = {
|
||||
fm.clearFocus()
|
||||
if(password.isNotEmpty()) sp.lockPasswordHash = password.hash()
|
||||
sp.biometricsUnlock = allowBiometrics
|
||||
sp.lockWhenLeaving = lockWhenLeaving
|
||||
if(password.isNotEmpty()) SP.lockPasswordHash = password.hash()
|
||||
SP.biometricsUnlock = allowBiometrics
|
||||
SP.lockWhenLeaving = lockWhenLeaving
|
||||
onNavigateUp()
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
@@ -276,9 +274,9 @@ fun AppLockSettingsScreen(onNavigateUp: () -> Unit) = MyScaffold(R.string.app_lo
|
||||
if(alreadySet) FilledTonalButton(
|
||||
onClick = {
|
||||
fm.clearFocus()
|
||||
sp.lockPasswordHash = ""
|
||||
sp.biometricsUnlock = false
|
||||
sp.lockWhenLeaving = false
|
||||
SP.lockPasswordHash = ""
|
||||
SP.biometricsUnlock = false
|
||||
SP.lockWhenLeaving = false
|
||||
onNavigateUp()
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
@@ -293,13 +291,12 @@ fun AppLockSettingsScreen(onNavigateUp: () -> Unit) = MyScaffold(R.string.app_lo
|
||||
@Composable
|
||||
fun ApiSettings(onNavigateUp: () -> Unit) {
|
||||
val context = LocalContext.current
|
||||
val sp = SharedPrefs(context)
|
||||
MyScaffold(R.string.api, onNavigateUp) {
|
||||
var enabled by remember { mutableStateOf(sp.isApiEnabled) }
|
||||
var enabled by remember { mutableStateOf(SP.isApiEnabled) }
|
||||
SwitchItem(R.string.enable, state = enabled, onCheckedChange = {
|
||||
enabled = it
|
||||
sp.isApiEnabled = it
|
||||
if(!it) sp.sharedPrefs.edit { remove("api.key") }
|
||||
SP.isApiEnabled = it
|
||||
if(!it) SP.sharedPrefs.edit { remove("api.key") }
|
||||
}, padding = false)
|
||||
if(enabled) {
|
||||
var key by remember { mutableStateOf("") }
|
||||
@@ -321,14 +318,14 @@ fun ApiSettings(onNavigateUp: () -> Unit) {
|
||||
Button(
|
||||
modifier = Modifier.fillMaxWidth().padding(bottom = 10.dp),
|
||||
onClick = {
|
||||
sp.apiKey = key
|
||||
SP.apiKey = key
|
||||
context.showOperationResultToast(true)
|
||||
},
|
||||
enabled = key.isNotEmpty()
|
||||
) {
|
||||
Text(stringResource(R.string.apply))
|
||||
}
|
||||
if(sp.apiKey != null) Notes(R.string.api_key_exist)
|
||||
if(SP.apiKey != null) Notes(R.string.api_key_exist)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,25 +7,21 @@ import android.os.Bundle
|
||||
import androidx.core.content.pm.ShortcutInfoCompat
|
||||
import androidx.core.content.pm.ShortcutManagerCompat
|
||||
import androidx.core.graphics.drawable.IconCompat
|
||||
import com.bintianqi.owndroid.dpm.getDPM
|
||||
import com.bintianqi.owndroid.dpm.getReceiver
|
||||
|
||||
class ShortcutsReceiverActivity : Activity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
try {
|
||||
val action = intent.action?.removePrefix("com.bintianqi.owndroid.action.")
|
||||
if (action != null && SharedPrefs(this).shortcuts) {
|
||||
val dpm = getDPM()
|
||||
val receiver = getReceiver()
|
||||
if (action != null && SP.shortcuts) {
|
||||
when (action) {
|
||||
"LOCK" -> dpm.lockNow()
|
||||
"LOCK" -> Privilege.DPM.lockNow()
|
||||
"DISABLE_CAMERA" -> {
|
||||
dpm.setCameraDisabled(receiver, !dpm.getCameraDisabled(receiver))
|
||||
Privilege.DPM.setCameraDisabled(Privilege.DAR, !Privilege.DPM.getCameraDisabled(Privilege.DAR))
|
||||
createShortcuts(this)
|
||||
}
|
||||
"MUTE" -> {
|
||||
dpm.setMasterVolumeMuted(receiver, !dpm.isMasterVolumeMuted(receiver))
|
||||
Privilege.DPM.setMasterVolumeMuted(Privilege.DAR, !Privilege.DPM.isMasterVolumeMuted(Privilege.DAR))
|
||||
createShortcuts(this)
|
||||
}
|
||||
}
|
||||
@@ -37,13 +33,11 @@ class ShortcutsReceiverActivity : Activity() {
|
||||
}
|
||||
|
||||
fun createShortcuts(context: Context) {
|
||||
if (!SharedPrefs(context).shortcuts) return
|
||||
if (!SP.shortcuts) return
|
||||
val action = "com.bintianqi.owndroid.action"
|
||||
val baseIntent = Intent(context, ShortcutsReceiverActivity::class.java)
|
||||
val dpm = context.getDPM()
|
||||
val receiver = context.getReceiver()
|
||||
val cameraDisabled = dpm.getCameraDisabled(receiver)
|
||||
val muted = dpm.isMasterVolumeMuted(receiver)
|
||||
val cameraDisabled = Privilege.DPM.getCameraDisabled(Privilege.DAR)
|
||||
val muted = Privilege.DPM.isMasterVolumeMuted(Privilege.DAR)
|
||||
val list = listOf(
|
||||
ShortcutInfoCompat.Builder(context, "LOCK")
|
||||
.setIcon(IconCompat.createWithResource(context, R.drawable.screen_lock_portrait_fill0))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
}) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user