From 8fd1d9e4fe7ca8ecd6d33542e254fdef00f400cd Mon Sep 17 00:00:00 2001 From: BinTianqi Date: Sun, 21 Jul 2024 08:56:03 +0800 Subject: [PATCH] Support Dhizuku mode --- .../bintianqi/owndroid/AutomationReceiver.kt | 8 +- .../com/bintianqi/owndroid/MainActivity.kt | 53 +++++--- .../java/com/bintianqi/owndroid/Receiver.kt | 24 +++- .../owndroid/dpm/ApplicationManage.kt | 81 ++++++----- .../java/com/bintianqi/owndroid/dpm/DPM.kt | 45 ++++++- .../bintianqi/owndroid/dpm/ManagedProfile.kt | 26 ++-- .../com/bintianqi/owndroid/dpm/Network.kt | 49 ++++--- .../com/bintianqi/owndroid/dpm/Password.kt | 126 ++++++++++++------ .../com/bintianqi/owndroid/dpm/Permissions.kt | 81 ++++++----- .../bintianqi/owndroid/dpm/ShizukuActivate.kt | 17 +-- .../bintianqi/owndroid/dpm/SystemManager.kt | 119 ++++++++--------- .../com/bintianqi/owndroid/dpm/UserManager.kt | 47 ++++--- .../bintianqi/owndroid/dpm/UserRestriction.kt | 22 ++- 13 files changed, 398 insertions(+), 300 deletions(-) diff --git a/app/src/main/java/com/bintianqi/owndroid/AutomationReceiver.kt b/app/src/main/java/com/bintianqi/owndroid/AutomationReceiver.kt index ee32652..e89b316 100644 --- a/app/src/main/java/com/bintianqi/owndroid/AutomationReceiver.kt +++ b/app/src/main/java/com/bintianqi/owndroid/AutomationReceiver.kt @@ -1,12 +1,12 @@ package com.bintianqi.owndroid import android.annotation.SuppressLint -import android.app.admin.DevicePolicyManager import android.content.BroadcastReceiver import android.content.ComponentName import android.content.Context import android.content.Intent -import androidx.activity.ComponentActivity +import com.bintianqi.owndroid.dpm.getDPM +import com.bintianqi.owndroid.dpm.getReceiver class AutomationReceiver: BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { @@ -25,8 +25,8 @@ fun handleTask(context: Context, intent: Intent): String { return "Wrong key" } val operation = intent.getStringExtra("operation") - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val app = intent.getStringExtra("app") val restriction = intent.getStringExtra("restriction") try { diff --git a/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt b/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt index 1988e3f..7ac09b0 100644 --- a/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt +++ b/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt @@ -3,17 +3,22 @@ package com.bintianqi.owndroid import android.app.admin.DevicePolicyManager import android.content.ComponentName import android.content.Context -import android.os.Build import android.os.Build.VERSION import android.os.Bundle import android.widget.Toast -import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.imePadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll @@ -22,7 +27,14 @@ import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme.colorScheme import androidx.compose.material3.MaterialTheme.typography import androidx.compose.material3.Text -import androidx.compose.runtime.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -38,7 +50,18 @@ import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController -import com.bintianqi.owndroid.dpm.* +import com.bintianqi.owndroid.dpm.ApplicationManage +import com.bintianqi.owndroid.dpm.DpmPermissions +import com.bintianqi.owndroid.dpm.ManagedProfile +import com.bintianqi.owndroid.dpm.Network +import com.bintianqi.owndroid.dpm.Password +import com.bintianqi.owndroid.dpm.SystemManage +import com.bintianqi.owndroid.dpm.UserManage +import com.bintianqi.owndroid.dpm.UserRestriction +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.ui.Animations import com.bintianqi.owndroid.ui.theme.OwnDroidTheme import com.rosan.dhizuku.api.Dhizuku @@ -98,8 +121,8 @@ class MainActivity : FragmentActivity() { fun Home(materialYou:MutableState, blackTheme:MutableState) { val navCtrl = rememberNavController() val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE) val focusMgr = LocalFocusManager.current val pkgName = remember { mutableStateOf("") } @@ -136,7 +159,7 @@ fun Home(materialYou:MutableState, blackTheme:MutableState) { } LaunchedEffect(Unit) { val profileInited = sharedPref.getBoolean("ManagedProfileActivated", false) - val profileNotActivated = !profileInited && isProfileOwner(dpm) && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver))) + val profileNotActivated = !profileInited && dpm.isProfileOwner(context) && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver))) if(profileNotActivated) { dpm.setProfileEnabled(receiver) sharedPref.edit().putBoolean("ManagedProfileActivated", true).apply() @@ -148,11 +171,11 @@ fun Home(materialYou:MutableState, blackTheme:MutableState) { @Composable private fun HomePage(navCtrl:NavHostController, pkgName: MutableState) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val activateType = stringResource( - if(isDeviceOwner(dpm)) { R.string.device_owner } - else if(isProfileOwner(dpm)) { + if(dpm.isDeviceOwner(context)) { R.string.device_owner } + else if(dpm.isProfileOwner(context)) { if(VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver)) R.string.work_profile_owner else R.string.profile_owner } else if(dpm.isAdminActive(receiver)) R.string.device_admin else R.string.click_to_activate @@ -193,11 +216,11 @@ private fun HomePage(navCtrl:NavHostController, pkgName: MutableState) { } } HomePageItem(R.string.system_manage, R.drawable.mobile_phone_fill0, "SystemManage", navCtrl) - if(VERSION.SDK_INT >= 24 && (isDeviceOwner(dpm)) || isProfileOwner(dpm)) { HomePageItem(R.string.network, R.drawable.wifi_fill0, "Network", navCtrl) } + if(VERSION.SDK_INT >= 24 && (dpm.isDeviceOwner(context)) || dpm.isProfileOwner(context)) { HomePageItem(R.string.network, R.drawable.wifi_fill0, "Network", navCtrl) } if( - (VERSION.SDK_INT < 24 && !isDeviceOwner(dpm)) || ( + (VERSION.SDK_INT < 24 && !dpm.isDeviceOwner(context)) || ( VERSION.SDK_INT >= 24 && (dpm.isProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE) || - (isProfileOwner(dpm) && dpm.isManagedProfile(receiver))) + (dpm.isProfileOwner(context) && dpm.isManagedProfile(receiver))) ) ) { HomePageItem(R.string.work_profile, R.drawable.work_fill0, "ManagedProfile", navCtrl) diff --git a/app/src/main/java/com/bintianqi/owndroid/Receiver.kt b/app/src/main/java/com/bintianqi/owndroid/Receiver.kt index 5bb2b60..5c14f47 100644 --- a/app/src/main/java/com/bintianqi/owndroid/Receiver.kt +++ b/app/src/main/java/com/bintianqi/owndroid/Receiver.kt @@ -3,16 +3,26 @@ package com.bintianqi.owndroid import android.annotation.SuppressLint import android.app.NotificationManager import android.app.admin.DeviceAdminReceiver -import android.app.admin.DevicePolicyManager import android.content.BroadcastReceiver import android.content.ComponentName import android.content.Context import android.content.Intent -import android.content.pm.PackageInstaller.* +import android.content.pm.PackageInstaller.EXTRA_STATUS +import android.content.pm.PackageInstaller.STATUS_FAILURE +import android.content.pm.PackageInstaller.STATUS_FAILURE_ABORTED +import android.content.pm.PackageInstaller.STATUS_FAILURE_BLOCKED +import android.content.pm.PackageInstaller.STATUS_FAILURE_CONFLICT +import android.content.pm.PackageInstaller.STATUS_FAILURE_INCOMPATIBLE +import android.content.pm.PackageInstaller.STATUS_FAILURE_INVALID +import android.content.pm.PackageInstaller.STATUS_FAILURE_STORAGE +import android.content.pm.PackageInstaller.STATUS_FAILURE_TIMEOUT +import android.content.pm.PackageInstaller.STATUS_PENDING_USER_ACTION +import android.content.pm.PackageInstaller.STATUS_SUCCESS import android.util.Log import android.widget.Toast import androidx.activity.ComponentActivity -import androidx.compose.ui.platform.LocalContext +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 kotlinx.coroutines.flow.MutableStateFlow @@ -20,9 +30,9 @@ import kotlinx.coroutines.flow.MutableStateFlow class Receiver : DeviceAdminReceiver() { override fun onEnabled(context: Context, intent: Intent) { super.onEnabled(context, intent) - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager + val dpm = context.getDPM() val receiver = ComponentName(context, this::class.java) - if(dpm.isAdminActive(receiver) || isProfileOwner(dpm) || isDeviceOwner(dpm)){ + if(dpm.isAdminActive(receiver) || dpm.isProfileOwner(context) || dpm.isDeviceOwner(context)){ Toast.makeText(context, context.getString(R.string.onEnabled), Toast.LENGTH_SHORT).show() } } @@ -68,8 +78,8 @@ class PackageInstallerReceiver:BroadcastReceiver(){ class StopLockTaskModeReceiver: BroadcastReceiver() { @SuppressLint("NewApi") override fun onReceive(context: Context, intent: Intent) { - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val packages = dpm.getLockTaskPackages(receiver) dpm.setLockTaskPackages(receiver, arrayOf()) dpm.setLockTaskPackages(receiver, packages) diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/ApplicationManage.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/ApplicationManage.kt index 93ee438..f7da22e 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/ApplicationManage.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/ApplicationManage.kt @@ -18,7 +18,6 @@ import android.os.Build.VERSION import android.os.Looper import android.provider.Settings import android.widget.Toast -import androidx.activity.ComponentActivity import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.animateContentSize import androidx.compose.foundation.clickable @@ -200,10 +199,10 @@ private fun Home( modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()) ) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context, Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() Spacer(Modifier.padding(vertical = 5.dp)) - if(VERSION.SDK_INT >= 24&&isProfileOwner(dpm)&&dpm.isManagedProfile(receiver)) { + if(VERSION.SDK_INT >= 24&&dpm.isProfileOwner(context)&&dpm.isManagedProfile(receiver)) { Text(text = stringResource(R.string.scope_is_work_profile), textAlign = TextAlign.Center,modifier = Modifier.fillMaxWidth()) } SubPageItem(R.string.app_info,"", R.drawable.open_in_new) { @@ -211,7 +210,7 @@ private fun Home( intent.setData(Uri.parse("package:$pkgName")) startActivity(context, intent, null) } - if(VERSION.SDK_INT>=24 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { + if(VERSION.SDK_INT>=24 && (dpm.isDeviceOwner(context) || dpm.isProfileOwner(context))) { val getSuspendStatus = { try{ dpm.isPackageSuspended(receiver, pkgName) } catch(e:NameNotFoundException) { false } @@ -229,7 +228,7 @@ private fun Home( } ) } - if(isDeviceOwner(dpm) || isProfileOwner(dpm)) { + if(dpm.isDeviceOwner(context) || dpm.isProfileOwner(context)) { SwitchItem( title = R.string.hide, desc = stringResource(R.string.isapphidden_desc), icon = R.drawable.visibility_off_fill0, getState = { dpm.isApplicationHidden(receiver,pkgName) }, @@ -242,7 +241,7 @@ private fun Home( } ) } - if(isDeviceOwner(dpm) || isProfileOwner(dpm)) { + if(dpm.isDeviceOwner(context) || dpm.isProfileOwner(context)) { SwitchItem( title = R.string.block_uninstall, desc = "", icon = R.drawable.delete_forever_fill0, getState = { dpm.isUninstallBlocked(receiver,pkgName) }, @@ -255,44 +254,44 @@ private fun Home( } ) } - if(VERSION.SDK_INT>=24 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { + if(VERSION.SDK_INT>=24 && (dpm.isDeviceOwner(context) || dpm.isProfileOwner(context))) { SubPageItem(R.string.always_on_vpn, "", R.drawable.vpn_key_fill0) { navCtrl.navigate("AlwaysOnVpn") } } - if((VERSION.SDK_INT>=33&&isProfileOwner(dpm))||(VERSION.SDK_INT>=30&&isDeviceOwner(dpm))) { + if((VERSION.SDK_INT>=33&&dpm.isProfileOwner(context))||(VERSION.SDK_INT>=30&&dpm.isDeviceOwner(context))) { SubPageItem(R.string.ucd, "", R.drawable.do_not_touch_fill0) { navCtrl.navigate("UserControlDisabled") } } - if(VERSION.SDK_INT>=23&&(isDeviceOwner(dpm)||isProfileOwner(dpm))) { + if(VERSION.SDK_INT>=23&&(dpm.isDeviceOwner(context)||dpm.isProfileOwner(context))) { SubPageItem(R.string.permission_manage, "", R.drawable.key_fill0) { navCtrl.navigate("PermissionManage") } } - if(VERSION.SDK_INT>=30&&isProfileOwner(dpm)&&dpm.isManagedProfile(receiver)) { + if(VERSION.SDK_INT>=30&&dpm.isProfileOwner(context)&&dpm.isManagedProfile(receiver)) { SubPageItem(R.string.cross_profile_package, "", R.drawable.work_fill0) { navCtrl.navigate("CrossProfilePackage") } } - if(isProfileOwner(dpm)) { + if(dpm.isProfileOwner(context)) { SubPageItem(R.string.cross_profile_widget, "", R.drawable.widgets_fill0) { navCtrl.navigate("CrossProfileWidget") } } - if(VERSION.SDK_INT>=34&&isDeviceOwner(dpm)) { + if(VERSION.SDK_INT>=34&&dpm.isDeviceOwner(context)) { SubPageItem(R.string.credential_manage_policy, "", R.drawable.license_fill0) { navCtrl.navigate("CredentialManagePolicy") } } - if(isProfileOwner(dpm)||isDeviceOwner(dpm)) { + if(dpm.isProfileOwner(context)||dpm.isDeviceOwner(context)) { SubPageItem(R.string.permitted_accessibility_services, "", R.drawable.settings_accessibility_fill0) { navCtrl.navigate("Accessibility") } } - if(isDeviceOwner(dpm)||isProfileOwner(dpm)) { + if(dpm.isDeviceOwner(context)||dpm.isProfileOwner(context)) { SubPageItem(R.string.permitted_ime, "", R.drawable.keyboard_fill0) { navCtrl.navigate("IME") } } - if(isDeviceOwner(dpm) || isProfileOwner(dpm)) { + if(dpm.isDeviceOwner(context) || dpm.isProfileOwner(context)) { SubPageItem(R.string.enable_system_app, "", R.drawable.enable_fill0) { enableSystemAppDialog.value = true } } - if(VERSION.SDK_INT>=28&&isDeviceOwner(dpm)) { + if(VERSION.SDK_INT>=28&&dpm.isDeviceOwner(context)) { SubPageItem(R.string.keep_uninstalled_packages, "", R.drawable.delete_fill0) { navCtrl.navigate("KeepUninstalled") } } - if(VERSION.SDK_INT>=28 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { + if(VERSION.SDK_INT>=28 && (dpm.isDeviceOwner(context) || dpm.isProfileOwner(context))) { SubPageItem(R.string.clear_app_storage, "", R.drawable.mop_fill0) { if(pkgName != "") { clearAppDataDialog.value = true } } } SubPageItem(R.string.install_app, "", R.drawable.install_mobile_fill0) { navCtrl.navigate("InstallApp") } SubPageItem(R.string.uninstall_app, "", R.drawable.delete_fill0) { navCtrl.navigate("UninstallApp") } - if(VERSION.SDK_INT >= 34 && (isDeviceOwner(dpm) || dpm.isOrgProfile(receiver))) { + if(VERSION.SDK_INT >= 34 && (dpm.isDeviceOwner(context) || dpm.isOrgProfile(receiver))) { SubPageItem(R.string.set_default_dialer, "", R.drawable.call_fill0) { defaultDialerAppDialog.value = true } } Spacer(Modifier.padding(vertical = 30.dp)) @@ -304,8 +303,8 @@ private fun Home( @Composable fun AlwaysOnVPNPackage(pkgName: String) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() var lockdown by remember { mutableStateOf(false) } var pkg by remember { mutableStateOf("") } val refresh = { pkg = dpm.getAlwaysOnVpnPackage(receiver) } @@ -348,8 +347,8 @@ fun AlwaysOnVPNPackage(pkgName: String) { @Composable private fun UserCtrlDisabledPkg(pkgName:String) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val pkgList = remember { mutableStateListOf() } Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { val refresh = { @@ -405,8 +404,8 @@ private fun UserCtrlDisabledPkg(pkgName:String) { @Composable private fun PermissionManage(pkgName: String, navCtrl: NavHostController) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current var inputPermission by remember { mutableStateOf("") } var currentState by remember { mutableStateOf(context.getString(R.string.unknown)) } @@ -487,8 +486,8 @@ private fun PermissionManage(pkgName: String, navCtrl: NavHostController) { @Composable private fun CrossProfilePkg(pkgName: String) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context, Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val crossProfilePkg = remember { mutableStateListOf() } val refresh = { crossProfilePkg.clear() @@ -541,8 +540,8 @@ private fun CrossProfilePkg(pkgName: String) { @Composable private fun CrossProfileWidget(pkgName: String) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val pkgList = remember { mutableStateListOf() } val refresh = { pkgList.clear() @@ -598,7 +597,7 @@ private fun CrossProfileWidget(pkgName: String) { @Composable private fun CredentialManagePolicy(pkgName: String) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager + val dpm = context.getDPM() var policy: PackagePolicy? var policyType by remember{ mutableIntStateOf(-1) } val credentialList = remember { mutableStateListOf() } @@ -691,8 +690,8 @@ private fun CredentialManagePolicy(pkgName: String) { @Composable private fun PermittedAccessibility(pkgName: String) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val pkgList = remember { mutableStateListOf() } var allowAll by remember { mutableStateOf(false) } val refresh = { @@ -777,8 +776,8 @@ private fun PermittedAccessibility(pkgName: String) { @Composable private fun PermittedIME(pkgName: String) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val permittedIme = remember { mutableStateListOf() } var allowAll by remember { mutableStateOf(false) } val refresh = { @@ -864,8 +863,8 @@ private fun PermittedIME(pkgName: String) { @Composable private fun KeepUninstalledApp(pkgName: String) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val pkgList = remember { mutableStateListOf() } val refresh = { pkgList.clear() @@ -1004,8 +1003,8 @@ private fun InstallApp() { @Composable private fun ClearAppDataDialog(status: MutableState, pkgName: String) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() AlertDialog( title = { Text(text = stringResource(R.string.clear_app_storage)) }, text = { @@ -1048,7 +1047,7 @@ private fun ClearAppDataDialog(status: MutableState, pkgName: String) { @Composable private fun DefaultDialerAppDialog(status: MutableState, pkgName: String) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager + val dpm = context.getDPM() AlertDialog( title = { Text(stringResource(R.string.set_default_dialer)) }, text = { @@ -1082,8 +1081,8 @@ private fun DefaultDialerAppDialog(status: MutableState, pkgName: Strin @Composable private fun EnableSystemAppDialog(status: MutableState, pkgName: String) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() AlertDialog( title = { Text(stringResource(R.string.enable_system_app)) }, text = { diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/DPM.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/DPM.kt index 4680189..15ebbbc 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/DPM.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/DPM.kt @@ -14,6 +14,7 @@ import androidx.activity.ComponentActivity.CONTEXT_IGNORE_SECURITY import androidx.activity.ComponentActivity.DEVICE_POLICY_SERVICE import androidx.activity.result.ActivityResultLauncher import com.bintianqi.owndroid.PackageInstallerReceiver +import com.bintianqi.owndroid.Receiver import com.rosan.dhizuku.api.Dhizuku import com.rosan.dhizuku.api.Dhizuku.binderWrapper import com.rosan.dhizuku.api.DhizukuBinderWrapper @@ -25,16 +26,30 @@ var selectedPermission = MutableStateFlow("") lateinit var createManagedProfile: ActivityResultLauncher lateinit var addDeviceAdmin: ActivityResultLauncher -fun isDeviceOwner(dpm: DevicePolicyManager): Boolean { - return dpm.isDeviceOwnerApp("com.bintianqi.owndroid") +fun DevicePolicyManager.isDeviceOwner(context: Context): Boolean { + val sharedPref = context.getSharedPreferences("data", Context.MODE_PRIVATE) + return this.isDeviceOwnerApp( + if(sharedPref.getBoolean("dhizuku", false)) { + Dhizuku.getOwnerPackageName() + } else { + "com.bintianqi.owndroid" + } + ) } -fun isProfileOwner(dpm: DevicePolicyManager): Boolean { - return dpm.isProfileOwnerApp("com.bintianqi.owndroid") +fun DevicePolicyManager.isProfileOwner(context: Context): Boolean { + val sharedPref = context.getSharedPreferences("data", Context.MODE_PRIVATE) + return this.isProfileOwnerApp( + if(sharedPref.getBoolean("dhizuku", false)) { + Dhizuku.getOwnerPackageName() + } else { + "com.bintianqi.owndroid" + } + ) } -fun DevicePolicyManager.isOrgProfile(receiver: ComponentName):Boolean { - return VERSION.SDK_INT >= 30 && isProfileOwner(this) && isManagedProfile(receiver) && isOrganizationOwnedDeviceWithManagedProfile +fun DevicePolicyManager.isOrgProfile(receiver: ComponentName): Boolean { + return VERSION.SDK_INT >= 30 && this.isProfileOwnerApp("com.bintianqi.owndroid") && isManagedProfile(receiver) && isOrganizationOwnedDeviceWithManagedProfile } @Throws(IOException::class) @@ -77,3 +92,21 @@ fun binderWrapperDevicePolicyManager(appContext: Context): DevicePolicyManager { throw RuntimeException(e) } } + +fun Context.getDPM(): DevicePolicyManager { + val sharedPref = this.getSharedPreferences("data", Context.MODE_PRIVATE) + return if(sharedPref.getBoolean("dhizuku", false)) { + binderWrapperDevicePolicyManager(this) + } else { + this.getSystemService(DEVICE_POLICY_SERVICE) as DevicePolicyManager + } +} + +fun Context.getReceiver(): ComponentName { + val sharedPref = this.getSharedPreferences("data", Context.MODE_PRIVATE) + return if(sharedPref.getBoolean("dhizuku", false)) { + Dhizuku.getOwnerComponent() + } else { + ComponentName(this, Receiver::class.java) + } +} diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/ManagedProfile.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/ManagedProfile.kt index 82ac61e..8954687 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/ManagedProfile.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/ManagedProfile.kt @@ -1,7 +1,6 @@ package com.bintianqi.owndroid.dpm import android.annotation.SuppressLint -import android.app.admin.DevicePolicyManager import android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE import android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ALLOW_OFFLINE import android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME @@ -18,7 +17,6 @@ import android.content.* import android.os.Binder import android.os.Build.VERSION import android.widget.Toast -import androidx.activity.ComponentActivity import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -96,8 +94,8 @@ fun ManagedProfile(navCtrl: NavHostController) { @Composable private fun Home(navCtrl: NavHostController) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context, Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() Column( modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()) ) { @@ -106,7 +104,7 @@ private fun Home(navCtrl: NavHostController) { style = typography.headlineLarge, modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 15.dp) ) - if(VERSION.SDK_INT >= 30 && isProfileOwner(dpm) && dpm.isManagedProfile(receiver)) { + if(VERSION.SDK_INT >= 30 && dpm.isProfileOwner(context) && dpm.isManagedProfile(receiver)) { SubPageItem(R.string.org_owned_work_profile, "", R.drawable.corporate_fare_fill0) { navCtrl.navigate("OrgOwnedWorkProfile") } } if(VERSION.SDK_INT<24 || (VERSION.SDK_INT>=24 && dpm.isProvisioningAllowed(ACTION_PROVISION_MANAGED_PROFILE))) { @@ -115,10 +113,10 @@ private fun Home(navCtrl: NavHostController) { if(dpm.isOrgProfile(receiver)) { SubPageItem(R.string.suspend_personal_app, "", R.drawable.block_fill0) { navCtrl.navigate("SuspendPersonalApp") } } - if(isProfileOwner(dpm) && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver)))) { + if(dpm.isProfileOwner(context) && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver)))) { SubPageItem(R.string.intent_filter, "", R.drawable.filter_alt_fill0) { navCtrl.navigate("IntentFilter") } } - if(isProfileOwner(dpm) && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver)))) { + if(dpm.isProfileOwner(context) && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver)))) { SubPageItem(R.string.delete_work_profile, "", R.drawable.delete_forever_fill0) { navCtrl.navigate("DeleteWorkProfile") } } Spacer(Modifier.padding(vertical = 30.dp)) @@ -128,7 +126,7 @@ private fun Home(navCtrl: NavHostController) { @Composable private fun CreateWorkProfile() { val context = LocalContext.current - val receiver = ComponentName(context,Receiver::class.java) + val receiver = context.getReceiver() Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.create_work_profile), style = typography.headlineLarge) @@ -165,7 +163,7 @@ private fun CreateWorkProfile() { @Composable private fun OrgOwnedProfile() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager + val dpm = context.getDPM() Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.org_owned_work_profile), style = typography.headlineLarge) @@ -188,8 +186,8 @@ private fun OrgOwnedProfile() { @Composable private fun SuspendPersonalApp() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) @@ -231,8 +229,8 @@ private fun SuspendPersonalApp() { @Composable private fun IntentFilter() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { var action by remember { mutableStateOf("") } @@ -281,7 +279,7 @@ private fun IntentFilter() { @Composable private fun DeleteWorkProfile() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager + val dpm = context.getDPM() val focusMgr = LocalFocusManager.current var warning by remember { mutableStateOf(false) } var externalStorage by remember { mutableStateOf(false) } diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/Network.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/Network.kt index e718cd4..f2ac177 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/Network.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/Network.kt @@ -1,7 +1,6 @@ package com.bintianqi.owndroid.dpm import android.annotation.SuppressLint -import android.app.admin.DevicePolicyManager import android.app.admin.DevicePolicyManager.PRIVATE_DNS_MODE_OFF import android.app.admin.DevicePolicyManager.PRIVATE_DNS_MODE_OPPORTUNISTIC import android.app.admin.DevicePolicyManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME @@ -135,8 +134,8 @@ fun Network(navCtrl: NavHostController) { } if(wifiMacDialog.value && VERSION.SDK_INT >= 24) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context, Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() AlertDialog( onDismissRequest = { wifiMacDialog.value = false }, confirmButton = { TextButton(onClick = { wifiMacDialog.value = false }) { Text(stringResource(R.string.confirm)) } }, @@ -150,36 +149,36 @@ fun Network(navCtrl: NavHostController) { @Composable private fun Home(navCtrl:NavHostController, scrollState: ScrollState, wifiMacDialog: MutableState) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context, Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)) { Text( text = stringResource(R.string.network), style = typography.headlineLarge, modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 15.dp) ) - if(VERSION.SDK_INT >= 24 && (isDeviceOwner(dpm) || dpm.isOrgProfile(receiver))) { + if(VERSION.SDK_INT >= 24 && (dpm.isDeviceOwner(context) || dpm.isOrgProfile(receiver))) { SubPageItem(R.string.wifi_mac_addr, "", R.drawable.wifi_fill0) { wifiMacDialog.value = true } } if(VERSION.SDK_INT >= 30) { SubPageItem(R.string.options, "", R.drawable.tune_fill0) { navCtrl.navigate("Switches") } } - if(VERSION.SDK_INT >= 33 && (isDeviceOwner(dpm) || dpm.isOrgProfile(receiver))) { + if(VERSION.SDK_INT >= 33 && (dpm.isDeviceOwner(context) || dpm.isOrgProfile(receiver))) { SubPageItem(R.string.min_wifi_security_level, "", R.drawable.wifi_password_fill0) { navCtrl.navigate("MinWifiSecurityLevel") } } - if(VERSION.SDK_INT >= 33 && (isDeviceOwner(dpm) || dpm.isOrgProfile(receiver))) { + if(VERSION.SDK_INT >= 33 && (dpm.isDeviceOwner(context) || dpm.isOrgProfile(receiver))) { SubPageItem(R.string.wifi_ssid_policy, "", R.drawable.wifi_fill0) { navCtrl.navigate("WifiSsidPolicy") } } - if(VERSION.SDK_INT >= 29 && isDeviceOwner(dpm)) { + if(VERSION.SDK_INT >= 29 && dpm.isDeviceOwner(context)) { SubPageItem(R.string.private_dns, "", R.drawable.dns_fill0) { navCtrl.navigate("PrivateDNS") } } - if(VERSION.SDK_INT >= 26&&(isDeviceOwner(dpm) || (isProfileOwner(dpm) && dpm.isManagedProfile(receiver)))) { + if(VERSION.SDK_INT >= 26&&(dpm.isDeviceOwner(context) || (dpm.isProfileOwner(context) && dpm.isManagedProfile(receiver)))) { SubPageItem(R.string.retrieve_net_logs, "", R.drawable.description_fill0) { navCtrl.navigate("NetworkLog") } } - if(VERSION.SDK_INT >= 31 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { + if(VERSION.SDK_INT >= 31 && (dpm.isDeviceOwner(context) || dpm.isProfileOwner(context))) { SubPageItem(R.string.wifi_auth_keypair, "", R.drawable.key_fill0) { navCtrl.navigate("WifiAuthKeypair") } } - if(VERSION.SDK_INT >= 28 && isDeviceOwner(dpm)) { + if(VERSION.SDK_INT >= 28 && dpm.isDeviceOwner(context)) { SubPageItem(R.string.override_apn_settings, "", R.drawable.cell_tower_fill0) { navCtrl.navigate("APN") } } Spacer(Modifier.padding(vertical = 30.dp)) @@ -189,17 +188,17 @@ private fun Home(navCtrl:NavHostController, scrollState: ScrollState, wifiMacDia @Composable private fun Switches() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() Column(modifier = Modifier.fillMaxSize()) { Spacer(Modifier.padding(vertical = 5.dp)) - if(VERSION.SDK_INT >= 33 && isDeviceOwner(dpm)) { + if(VERSION.SDK_INT >= 33 && dpm.isDeviceOwner(context)) { SwitchItem( R.string.preferential_network_service, stringResource(R.string.developing), R.drawable.globe_fill0, { dpm.isPreferentialNetworkServiceEnabled }, { dpm.isPreferentialNetworkServiceEnabled = it } ) } - if(VERSION.SDK_INT>=30 && (isDeviceOwner(dpm) || dpm.isOrgProfile(receiver))) { + if(VERSION.SDK_INT>=30 && (dpm.isDeviceOwner(context) || dpm.isOrgProfile(receiver))) { SwitchItem(R.string.lockdown_admin_configured_network, "", R.drawable.wifi_password_fill0, { dpm.hasLockdownAdminConfiguredNetworks(receiver) }, { dpm.setConfiguredNetworksLockdownState(receiver,it) } ) @@ -211,7 +210,7 @@ private fun Switches() { @Composable private fun WifiSecLevel() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager + val dpm = context.getDPM() var selectedWifiSecLevel by remember { mutableIntStateOf(0) } LaunchedEffect(Unit) { selectedWifiSecLevel = dpm.minimumRequiredWifiSecurityLevel } Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { @@ -255,7 +254,7 @@ private fun WifiSecLevel() { @Composable private fun WifiSsidPolicy() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager + val dpm = context.getDPM() val focusMgr = LocalFocusManager.current Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { var selectedPolicyType by remember { mutableIntStateOf(-1) } @@ -363,8 +362,8 @@ private fun WifiSsidPolicy() { @Composable private fun PrivateDNS() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) @@ -433,8 +432,8 @@ private fun PrivateDNS() { @Composable private fun NetworkLog() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.retrieve_net_logs), style = typography.headlineLarge) @@ -465,7 +464,7 @@ private fun NetworkLog() { @Composable private fun WifiAuthKeypair() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager + val dpm = context.getDPM() val focusMgr = LocalFocusManager.current Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { var keyPair by remember { mutableStateOf("") } @@ -511,8 +510,8 @@ private fun WifiAuthKeypair() { @Composable private fun APN() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { val setting = dpm.getOverrideApns(receiver) diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/Password.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/Password.kt index 629c5e7..5aff7df 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/Password.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/Password.kt @@ -2,23 +2,64 @@ package com.bintianqi.owndroid.dpm import android.annotation.SuppressLint import android.app.KeyguardManager -import android.app.admin.DevicePolicyManager -import android.app.admin.DevicePolicyManager.* +import android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PASSWORD +import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_BIOMETRICS +import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FACE +import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL +import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE +import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT +import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_IRIS +import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_REMOTE_INPUT +import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA +import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS +import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL +import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS +import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS +import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL +import android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_HIGH +import android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_LOW +import android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_MEDIUM +import android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE +import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC +import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC +import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK +import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX +import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC +import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX +import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING +import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED +import android.app.admin.DevicePolicyManager.RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT +import android.app.admin.DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY import android.content.ComponentName import android.content.Context import android.content.Intent import android.os.Build.VERSION import android.widget.Toast -import androidx.activity.ComponentActivity import androidx.compose.animation.AnimatedVisibility -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.ScrollState +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material3.* +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.MaterialTheme.colorScheme import androidx.compose.material3.MaterialTheme.typography -import androidx.compose.runtime.* +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha import androidx.compose.ui.platform.LocalContext @@ -35,7 +76,12 @@ import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController import com.bintianqi.owndroid.R import com.bintianqi.owndroid.Receiver -import com.bintianqi.owndroid.ui.* +import com.bintianqi.owndroid.ui.Animations +import com.bintianqi.owndroid.ui.CheckBoxItem +import com.bintianqi.owndroid.ui.Information +import com.bintianqi.owndroid.ui.RadioButtonItem +import com.bintianqi.owndroid.ui.SubPageItem +import com.bintianqi.owndroid.ui.TopBar @Composable fun Password(navCtrl: NavHostController) { @@ -81,8 +127,8 @@ fun Password(navCtrl: NavHostController) { @Composable private fun Home(navCtrl:NavHostController,scrollState: ScrollState) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context, Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)) { Text( text = stringResource(R.string.password_and_keyguard), @@ -90,19 +136,19 @@ private fun Home(navCtrl:NavHostController,scrollState: ScrollState) { modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 15.dp) ) SubPageItem(R.string.password_info, "", R.drawable.info_fill0) { navCtrl.navigate("PasswordInfo") } - if(VERSION.SDK_INT >= 26 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { + if(VERSION.SDK_INT >= 26 && (dpm.isDeviceOwner(context) || dpm.isProfileOwner(context))) { SubPageItem(R.string.reset_password_token, "", R.drawable.key_vertical_fill0) { navCtrl.navigate("ResetPasswordToken") } } - if(dpm.isAdminActive(receiver) || isDeviceOwner(dpm) || isProfileOwner(dpm)) { + if(dpm.isAdminActive(receiver) || dpm.isDeviceOwner(context) || dpm.isProfileOwner(context)) { SubPageItem(R.string.reset_password, "", R.drawable.lock_reset_fill0) { navCtrl.navigate("ResetPassword") } } - if(VERSION.SDK_INT >= 31 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { + if(VERSION.SDK_INT >= 31 && (dpm.isDeviceOwner(context) || dpm.isProfileOwner(context))) { SubPageItem(R.string.required_password_complexity, "", R.drawable.password_fill0) { navCtrl.navigate("RequirePasswordComplexity") } } if(dpm.isAdminActive(receiver)) { SubPageItem(R.string.disable_keyguard_features, "", R.drawable.screen_lock_portrait_fill0) { navCtrl.navigate("DisableKeyguardFeatures") } } - if(isDeviceOwner(dpm)) { + if(dpm.isDeviceOwner(context)) { SubPageItem(R.string.max_time_to_lock, "", R.drawable.schedule_fill0) { navCtrl.navigate("MaxTimeToLock") } SubPageItem(R.string.pwd_expiration_timeout, "", R.drawable.lock_clock_fill0) { navCtrl.navigate("PasswordTimeout") } SubPageItem(R.string.max_pwd_fail, "", R.drawable.no_encryption_fill0) { navCtrl.navigate("MaxPasswordFail") } @@ -110,10 +156,10 @@ private fun Home(navCtrl:NavHostController,scrollState: ScrollState) { if(dpm.isAdminActive(receiver)){ SubPageItem(R.string.pwd_history, "", R.drawable.history_fill0) { navCtrl.navigate("PasswordHistoryLength") } } - if(VERSION.SDK_INT >= 26 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { + if(VERSION.SDK_INT >= 26 && (dpm.isDeviceOwner(context) || dpm.isProfileOwner(context))) { SubPageItem(R.string.required_strong_auth_timeout, "", R.drawable.fingerprint_off_fill0) { navCtrl.navigate("RequiredStrongAuthTimeout") } } - if(isDeviceOwner(dpm) || isProfileOwner(dpm)) { + if(dpm.isDeviceOwner(context) || dpm.isProfileOwner(context)) { SubPageItem(R.string.required_password_quality, "", R.drawable.password_fill0) { navCtrl.navigate("RequirePasswordQuality") } } Spacer(Modifier.padding(vertical = 30.dp)) @@ -123,8 +169,8 @@ private fun Home(navCtrl:NavHostController,scrollState: ScrollState) { @Composable private fun PasswordInfo() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context, Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.password_info), style = typography.headlineLarge) @@ -139,14 +185,14 @@ private fun PasswordInfo() { val pwdComplex = passwordComplexity[dpm.passwordComplexity] Text(text = stringResource(R.string.current_password_complexity_is, pwdComplex?:stringResource(R.string.unknown))) } - if(isDeviceOwner(dpm) || isProfileOwner(dpm)) { + if(dpm.isDeviceOwner(context) || dpm.isProfileOwner(context)) { Text(stringResource(R.string.is_password_sufficient, dpm.isActivePasswordSufficient)) } if(dpm.isAdminActive(receiver)) { val pwdFailedAttempts = dpm.currentFailedPasswordAttempts Text(text = stringResource(R.string.password_failed_attempts_is, pwdFailedAttempts)) } - if(VERSION.SDK_INT >= 28 && isProfileOwner(dpm) && dpm.isManagedProfile(receiver)) { + if(VERSION.SDK_INT >= 28 && dpm.isProfileOwner(context) && dpm.isManagedProfile(receiver)) { val unifiedPwd = dpm.isUsingUnifiedPassword(receiver) Text(stringResource(R.string.is_using_unified_password, unifiedPwd)) } @@ -157,8 +203,8 @@ private fun PasswordInfo() { @Composable private fun ResetPasswordToken() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val tokenByteArray by remember { mutableStateOf(byteArrayOf(1,1,4,5,1,4,1,9,1,9,8,1,0,1,1,4,5,1,4,1,9,1,9,8,1,0,1,1,4,5,1,4,1,9,1,9,8,1,0)) } Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) @@ -211,8 +257,8 @@ private fun ResetPasswordToken() { @Composable private fun ResetPassword() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current var newPwd by remember { mutableStateOf("") } val tokenByteArray by remember { mutableStateOf(byteArrayOf(1,1,4,5,1,4,1,9,1,9,8,1,0,1,1,4,5,1,4,1,9,1,9,8,1,0,1,1,4,5,1,4,1,9,1,9,8,1,0)) } @@ -271,7 +317,7 @@ private fun ResetPassword() { confirmed=false }, colors = ButtonDefaults.buttonColors(containerColor = colorScheme.error, contentColor = colorScheme.onError), - enabled = confirmed && (isDeviceOwner(dpm) || isProfileOwner(dpm)), + enabled = confirmed && (dpm.isDeviceOwner(context) || dpm.isProfileOwner(context)), modifier = Modifier.fillMaxWidth() ) { Text(stringResource(R.string.reset_password_with_token)) @@ -298,7 +344,7 @@ private fun ResetPassword() { @Composable private fun PasswordComplexity() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager + val dpm = context.getDPM() val passwordComplexity = mapOf( PASSWORD_COMPLEXITY_NONE to stringResource(R.string.password_complexity_none), PASSWORD_COMPLEXITY_LOW to stringResource(R.string.password_complexity_low), @@ -356,8 +402,8 @@ private fun PasswordComplexity() { @Composable private fun ScreenTimeout() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current var inputContent by remember { mutableStateOf("") } LaunchedEffect(Unit) { inputContent = dpm.getMaximumTimeToLock(receiver).toString() } @@ -390,8 +436,8 @@ private fun ScreenTimeout() { @Composable private fun RequiredStrongAuthTimeout() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current var input by remember { mutableStateOf("") } LaunchedEffect(Unit) { input = dpm.getRequiredStrongAuthTimeout(receiver).toString() } @@ -424,8 +470,8 @@ private fun RequiredStrongAuthTimeout() { @Composable private fun MaxFailedPasswordForWipe() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current var inputContent by remember { mutableStateOf("") } LaunchedEffect(Unit) { inputContent = dpm.getMaximumFailedPasswordsForWipe(receiver).toString() } @@ -457,8 +503,8 @@ private fun MaxFailedPasswordForWipe() { @Composable private fun PasswordExpiration() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current var inputContent by remember { mutableStateOf("") } LaunchedEffect(Unit) { inputContent = dpm.getPasswordExpirationTimeout(receiver).toString() } @@ -488,8 +534,8 @@ private fun PasswordExpiration() { @Composable private fun PasswordHistoryLength() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current var inputContent by remember { mutableStateOf("") } LaunchedEffect(Unit) { inputContent = dpm.getPasswordHistoryLength(receiver).toString() } @@ -521,8 +567,8 @@ private fun PasswordHistoryLength() { @Composable private fun DisableKeyguardFeatures() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() var state by remember { mutableIntStateOf(-1) } var shortcuts by remember { mutableStateOf(false) } var biometrics by remember { mutableStateOf(false) } @@ -618,8 +664,8 @@ private fun DisableKeyguardFeatures() { @Composable private fun PasswordQuality() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val passwordQuality = mapOf( PASSWORD_QUALITY_UNSPECIFIED to stringResource(R.string.password_quality_unspecified), PASSWORD_QUALITY_SOMETHING to stringResource(R.string.password_quality_something), diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/Permissions.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/Permissions.kt index b8edcd8..cf5b4cb 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/Permissions.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/Permissions.kt @@ -10,7 +10,6 @@ import android.content.pm.PackageManager import android.os.Build.VERSION import android.os.RemoteException import android.widget.Toast -import androidx.activity.ComponentActivity import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.* import androidx.compose.foundation.layout.* @@ -90,8 +89,8 @@ fun DpmPermissions(navCtrl:NavHostController) { @Composable private fun Home(localNavCtrl:NavHostController,listScrollState:ScrollState) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context, Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE) var dhizukuStatus by remember { mutableStateOf(sharedPref.getBoolean("dhizuku", false)) } Column(modifier = Modifier.fillMaxSize().verticalScroll(listScrollState)) { @@ -132,37 +131,37 @@ private fun Home(localNavCtrl:NavHostController,listScrollState:ScrollState) { R.string.device_admin, stringResource(if(dpm.isAdminActive(receiver)) R.string.activated else R.string.deactivated), operation = { localNavCtrl.navigate("DeviceAdmin") } ) - if(!isDeviceOwner(dpm)) { + if(!dpm.isDeviceOwner(context)) { SubPageItem( - R.string.profile_owner, stringResource(if(isProfileOwner(dpm)) R.string.activated else R.string.deactivated), + R.string.profile_owner, stringResource(if(dpm.isProfileOwner(context)) R.string.activated else R.string.deactivated), operation = { localNavCtrl.navigate("ProfileOwner") } ) } - if(!isProfileOwner(dpm)) { + if(!dpm.isProfileOwner(context)) { SubPageItem( - R.string.device_owner, stringResource(if(isDeviceOwner(dpm)) R.string.activated else R.string.deactivated), + R.string.device_owner, stringResource(if(dpm.isDeviceOwner(context)) R.string.activated else R.string.deactivated), operation = { localNavCtrl.navigate("DeviceOwner") } ) } SubPageItem(R.string.shizuku,"") { localNavCtrl.navigate("Shizuku") } SubPageItem(R.string.device_info, "", R.drawable.perm_device_information_fill0) { localNavCtrl.navigate("DeviceInfo") } - if((VERSION.SDK_INT >= 26 && isDeviceOwner(dpm)) || (VERSION.SDK_INT>=24 && isProfileOwner(dpm))) { + if((VERSION.SDK_INT >= 26 && dpm.isDeviceOwner(context)) || (VERSION.SDK_INT>=24 && dpm.isProfileOwner(context))) { SubPageItem(R.string.org_name, "", R.drawable.corporate_fare_fill0) { localNavCtrl.navigate("OrgName") } } - if(VERSION.SDK_INT >= 31 && (isProfileOwner(dpm) || isDeviceOwner(dpm))) { + if(VERSION.SDK_INT >= 31 && (dpm.isProfileOwner(context) || dpm.isDeviceOwner(context))) { SubPageItem(R.string.org_id, "", R.drawable.corporate_fare_fill0) { localNavCtrl.navigate("OrgID") } SubPageItem(R.string.enrollment_specific_id, "", R.drawable.id_card_fill0) { localNavCtrl.navigate("SpecificID") } } - if(isDeviceOwner(dpm) || isProfileOwner(dpm)) { + if(dpm.isDeviceOwner(context) || dpm.isProfileOwner(context)) { SubPageItem(R.string.disable_account_management, "", R.drawable.account_circle_fill0) { localNavCtrl.navigate("DisableAccountManagement") } } - if(VERSION.SDK_INT >= 24 && (isDeviceOwner(dpm) || dpm.isOrgProfile(receiver))) { + if(VERSION.SDK_INT >= 24 && (dpm.isDeviceOwner(context) || dpm.isOrgProfile(receiver))) { SubPageItem(R.string.device_owner_lock_screen_info, "", R.drawable.screen_lock_portrait_fill0) { localNavCtrl.navigate("LockScreenInfo") } } if(VERSION.SDK_INT >= 24 && dpm.isAdminActive(receiver)) { SubPageItem(R.string.support_msg, "", R.drawable.chat_fill0) { localNavCtrl.navigate("SupportMsg") } } - if(VERSION.SDK_INT >= 28 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { + if(VERSION.SDK_INT >= 28 && (dpm.isDeviceOwner(context) || dpm.isProfileOwner(context))) { SubPageItem(R.string.transfer_ownership, "", R.drawable.admin_panel_settings_fill0) { localNavCtrl.navigate("TransformOwnership") } } Spacer(Modifier.padding(vertical = 30.dp)) @@ -173,8 +172,8 @@ private fun Home(localNavCtrl:NavHostController,listScrollState:ScrollState) { @Composable private fun LockScreenInfo() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current var infoText by remember { mutableStateOf(dpm.deviceOwnerLockScreenInfo?.toString() ?: "") } Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) { @@ -211,8 +210,8 @@ private fun LockScreenInfo() { @Composable private fun DeviceAdmin() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() var showDeactivateButton by remember { mutableStateOf(dpm.isAdminActive(receiver)) } var deactivateDialog by remember { mutableStateOf(false) } Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) { @@ -223,7 +222,7 @@ private fun DeviceAdmin() { AnimatedVisibility(showDeactivateButton) { Button( onClick = { deactivateDialog = true }, - enabled = !isProfileOwner(dpm) && !isDeviceOwner(dpm), + enabled = !dpm.isProfileOwner(context) && !dpm.isDeviceOwner(context), colors = ButtonDefaults.buttonColors(containerColor = colorScheme.error, contentColor = colorScheme.onError) ) { Text(stringResource(R.string.deactivate)) @@ -276,14 +275,14 @@ private fun DeviceAdmin() { @Composable private fun ProfileOwner() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) - var showDeactivateButton by remember { mutableStateOf(isProfileOwner(dpm)) } + val dpm = context.getDPM() + val receiver = context.getReceiver() + var showDeactivateButton by remember { mutableStateOf(dpm.isProfileOwner(context)) } var deactivateDialog by remember { mutableStateOf(false) } Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.profile_owner), style = typography.headlineLarge) - Text(stringResource(if(isProfileOwner(dpm)) R.string.activated else R.string.deactivated), style = typography.titleLarge) + Text(stringResource(if(dpm.isProfileOwner(context)) R.string.activated else R.string.deactivated), style = typography.titleLarge) Spacer(Modifier.padding(vertical = 5.dp)) if(VERSION.SDK_INT >= 24) { AnimatedVisibility(showDeactivateButton) { @@ -324,8 +323,8 @@ private fun ProfileOwner() { co.launch{ delay(300) deactivateDialog = false - showDeactivateButton = isProfileOwner(dpm) - backToHomeStateFlow.value = !isProfileOwner(dpm) + showDeactivateButton = dpm.isProfileOwner(context) + backToHomeStateFlow.value = !dpm.isProfileOwner(context) } } ) { @@ -339,13 +338,13 @@ private fun ProfileOwner() { @Composable private fun DeviceOwner() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - var showDeactivateButton by remember { mutableStateOf(isDeviceOwner(dpm)) } + val dpm = context.getDPM() + var showDeactivateButton by remember { mutableStateOf(dpm.isDeviceOwner(context)) } var deactivateDialog by remember { mutableStateOf(false) } Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.device_owner), style = typography.headlineLarge) - Text(text = stringResource(if(isDeviceOwner(dpm)) R.string.activated else R.string.deactivated), style = typography.titleLarge) + Text(text = stringResource(if(dpm.isDeviceOwner(context)) R.string.activated else R.string.deactivated), style = typography.titleLarge) Spacer(Modifier.padding(vertical = 5.dp)) AnimatedVisibility(showDeactivateButton) { Button( @@ -383,8 +382,8 @@ private fun DeviceOwner() { co.launch{ delay(300) deactivateDialog = false - showDeactivateButton = isDeviceOwner(dpm) - backToHomeStateFlow.value = !isDeviceOwner(dpm) + showDeactivateButton = dpm.isDeviceOwner(context) + backToHomeStateFlow.value = !dpm.isDeviceOwner(context) } } ) { @@ -398,13 +397,13 @@ private fun DeviceOwner() { @Composable fun DeviceInfo() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.device_info), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) - if(VERSION.SDK_INT>=34 && (isDeviceOwner(dpm) || dpm.isOrgProfile(receiver))) { + if(VERSION.SDK_INT>=34 && (dpm.isDeviceOwner(context) || dpm.isOrgProfile(receiver))) { val financed = dpm.isDeviceFinanced Text(stringResource(R.string.is_device_financed, financed)) } @@ -457,7 +456,7 @@ fun DeviceInfo() { @Composable private fun OrgID() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager + val dpm = context.getDPM() val focusMgr = LocalFocusManager.current Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { var orgId by remember { mutableStateOf("") } @@ -495,7 +494,7 @@ private fun OrgID() { @Composable private fun SpecificID() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager + val dpm = context.getDPM() Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) { val specificId = dpm.enrollmentSpecificId Spacer(Modifier.padding(vertical = 10.dp)) @@ -514,8 +513,8 @@ private fun SpecificID() { @Composable private fun OrgName() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) { var orgName by remember { mutableStateOf(try{dpm.getOrganizationName(receiver).toString() }catch(e:SecurityException) {""}) } @@ -546,8 +545,8 @@ private fun OrgName() { @Composable private fun SupportMsg() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current var shortMsg by remember { mutableStateOf(dpm.getShortSupportMessage(receiver)?.toString() ?: "") } var longMsg by remember { mutableStateOf(dpm.getLongSupportMessage(receiver)?.toString() ?: "") } @@ -605,8 +604,8 @@ private fun SupportMsg() { @Composable private fun DisableAccountManagement() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) { Spacer(Modifier.padding(vertical = 10.dp)) @@ -659,8 +658,8 @@ private fun DisableAccountManagement() { @Composable private fun TransformOwnership() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current val focusRequester = FocusRequester() Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) { diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/ShizukuActivate.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/ShizukuActivate.kt index 6c187e5..1c32ee7 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/ShizukuActivate.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/ShizukuActivate.kt @@ -1,6 +1,5 @@ package com.bintianqi.owndroid.dpm -import android.app.admin.DevicePolicyManager import android.content.ComponentName import android.content.Context import android.content.ServiceConnection @@ -9,7 +8,6 @@ import android.os.Binder import android.os.Build.VERSION import android.os.IBinder import android.widget.Toast -import androidx.activity.ComponentActivity import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Column @@ -36,7 +34,6 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.bintianqi.owndroid.IUserService import com.bintianqi.owndroid.R -import com.bintianqi.owndroid.Receiver import kotlinx.coroutines.delay import kotlinx.coroutines.launch import rikka.shizuku.Shizuku @@ -46,16 +43,16 @@ private var waitGrantPermission = false @Composable fun ShizukuActivate() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context, Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val coScope = rememberCoroutineScope() val outputTextScrollState = rememberScrollState() var enabled by remember { mutableStateOf(false) } var bindShizuku by remember { mutableStateOf(false) } var outputText by remember { mutableStateOf("") } var showDeviceAdminButton by remember { mutableStateOf(!dpm.isAdminActive(receiver)) } - var showProfileOwnerButton by remember { mutableStateOf(!isProfileOwner(dpm)) } - var showDeviceOwnerButton by remember { mutableStateOf(!isDeviceOwner(dpm)) } + var showProfileOwnerButton by remember { mutableStateOf(!dpm.isProfileOwner(context)) } + var showDeviceOwnerButton by remember { mutableStateOf(!dpm.isDeviceOwner(context)) } var showOrgProfileOwnerButton by remember { mutableStateOf(true) } val service by shizukuService.collectAsState() LaunchedEffect(service) { @@ -143,7 +140,7 @@ fun ShizukuActivate() { outputText = service!!.execute(context.getString(R.string.dpm_activate_po_command)) outputTextScrollState.animateScrollTo(0) delay(500) - showProfileOwnerButton = !isProfileOwner(dpm) + showProfileOwnerButton = !dpm.isProfileOwner(context) } }, enabled = enabled @@ -159,7 +156,7 @@ fun ShizukuActivate() { outputText = service!!.execute(context.getString(R.string.dpm_activate_do_command)) outputTextScrollState.animateScrollTo(0) delay(500) - showDeviceOwnerButton = !isDeviceOwner(dpm) + showDeviceOwnerButton = !dpm.isDeviceOwner(context) } }, enabled = enabled @@ -168,7 +165,7 @@ fun ShizukuActivate() { } } - if(VERSION.SDK_INT >= 30 && isProfileOwner(dpm) && dpm.isManagedProfile(receiver) && !dpm.isOrganizationOwnedDeviceWithManagedProfile) { + if(VERSION.SDK_INT >= 30 && dpm.isProfileOwner(context) && dpm.isManagedProfile(receiver) && !dpm.isOrganizationOwnedDeviceWithManagedProfile) { AnimatedVisibility(showOrgProfileOwnerButton) { Button( onClick = { diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/SystemManager.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/SystemManager.kt index 0045898..3f0e8e7 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/SystemManager.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/SystemManager.kt @@ -6,7 +6,6 @@ import android.app.AlertDialog import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent -import android.app.admin.DevicePolicyManager import android.app.admin.DevicePolicyManager.FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY import android.app.admin.DevicePolicyManager.InstallSystemUpdateCallback import android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK @@ -174,8 +173,8 @@ fun SystemManage(navCtrl:NavHostController) { @Composable private fun Home(navCtrl: NavHostController, scrollState: ScrollState, rebootDialog: MutableState, bugReportDialog: MutableState) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context, Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val sharedPref = context.getSharedPreferences("data", Context.MODE_PRIVATE) val dangerousFeatures = sharedPref.getBoolean("dangerous_features", false) Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)) { @@ -184,48 +183,48 @@ private fun Home(navCtrl: NavHostController, scrollState: ScrollState, rebootDia style = typography.headlineLarge, modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 15.dp) ) - if(isDeviceOwner(dpm) || isProfileOwner(dpm)) { + if(dpm.isDeviceOwner(context) || dpm.isProfileOwner(context)) { SubPageItem(R.string.options, "", R.drawable.tune_fill0) { navCtrl.navigate("Switches") } } SubPageItem(R.string.keyguard, "", R.drawable.screen_lock_portrait_fill0) { navCtrl.navigate("Keyguard") } - if(VERSION.SDK_INT >= 24 && isDeviceOwner(dpm)) { + if(VERSION.SDK_INT >= 24 && dpm.isDeviceOwner(context)) { SubPageItem(R.string.reboot, "", R.drawable.restart_alt_fill0) { rebootDialog.value = true } } - if(isDeviceOwner(dpm) && ((VERSION.SDK_INT >= 28 && dpm.isAffiliatedUser) || VERSION.SDK_INT >= 24)) { + if(dpm.isDeviceOwner(context) && ((VERSION.SDK_INT >= 28 && dpm.isAffiliatedUser) || VERSION.SDK_INT >= 24)) { SubPageItem(R.string.bug_report, "", R.drawable.bug_report_fill0) { bugReportDialog.value = true } } - if(VERSION.SDK_INT >= 28 && (isDeviceOwner(dpm) || dpm.isOrgProfile(receiver))) { + if(VERSION.SDK_INT >= 28 && (dpm.isDeviceOwner(context) || dpm.isOrgProfile(receiver))) { SubPageItem(R.string.edit_time, "", R.drawable.schedule_fill0) { navCtrl.navigate("EditTime") } SubPageItem(R.string.edit_timezone, "", R.drawable.schedule_fill0) { navCtrl.navigate("EditTimeZone") } } - if(VERSION.SDK_INT >= 23 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { + if(VERSION.SDK_INT >= 23 && (dpm.isDeviceOwner(context) || dpm.isProfileOwner(context))) { SubPageItem(R.string.permission_policy, "", R.drawable.key_fill0) { navCtrl.navigate("PermissionPolicy") } } - if(VERSION.SDK_INT >= 34 && isDeviceOwner(dpm)) { + if(VERSION.SDK_INT >= 34 && dpm.isDeviceOwner(context)) { SubPageItem(R.string.mte_policy, "", R.drawable.memory_fill0) { navCtrl.navigate("MTEPolicy") } } - if(VERSION.SDK_INT >= 31 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { + if(VERSION.SDK_INT >= 31 && (dpm.isDeviceOwner(context) || dpm.isProfileOwner(context))) { SubPageItem(R.string.nearby_streaming_policy, "", R.drawable.share_fill0) { navCtrl.navigate("NearbyStreamingPolicy") } } - if(VERSION.SDK_INT >= 28 && isDeviceOwner(dpm)) { + if(VERSION.SDK_INT >= 28 && dpm.isDeviceOwner(context)) { SubPageItem(R.string.lock_task_mode, "", R.drawable.lock_fill0) { navCtrl.navigate("LockTaskMode") } } - if(isDeviceOwner(dpm) || isProfileOwner(dpm)) { + if(dpm.isDeviceOwner(context) || dpm.isProfileOwner(context)) { SubPageItem(R.string.ca_cert, "", R.drawable.license_fill0) { navCtrl.navigate("CaCert") } } - if(VERSION.SDK_INT >= 26 && (isDeviceOwner(dpm) || dpm.isOrgProfile(receiver))) { + if(VERSION.SDK_INT >= 26 && (dpm.isDeviceOwner(context) || dpm.isOrgProfile(receiver))) { SubPageItem(R.string.security_logs, "", R.drawable.description_fill0) { navCtrl.navigate("SecurityLogs") } } - if(VERSION.SDK_INT >= 23 && (isDeviceOwner(dpm) || dpm.isOrgProfile(receiver))) { + if(VERSION.SDK_INT >= 23 && (dpm.isDeviceOwner(context) || dpm.isOrgProfile(receiver))) { SubPageItem(R.string.system_update_policy, "", R.drawable.system_update_fill0) { navCtrl.navigate("SystemUpdatePolicy") } } - if(VERSION.SDK_INT >= 29 && (isDeviceOwner(dpm) || dpm.isOrgProfile(receiver))) { + if(VERSION.SDK_INT >= 29 && (dpm.isDeviceOwner(context) || dpm.isOrgProfile(receiver))) { SubPageItem(R.string.install_system_update, "", R.drawable.system_update_fill0) { navCtrl.navigate("InstallSystemUpdate") } } - if(VERSION.SDK_INT >= 30 && (isDeviceOwner(dpm) || dpm.isOrgProfile(receiver))) { + if(VERSION.SDK_INT >= 30 && (dpm.isDeviceOwner(context) || dpm.isOrgProfile(receiver))) { SubPageItem(R.string.frp_policy, "", R.drawable.device_reset_fill0) { navCtrl.navigate("FRP") } } - if(dangerousFeatures && dpm.isAdminActive(receiver) && !(VERSION.SDK_INT >= 24 && isProfileOwner(dpm) && dpm.isManagedProfile(receiver))) { + if(dangerousFeatures && dpm.isAdminActive(receiver) && !(VERSION.SDK_INT >= 24 && dpm.isProfileOwner(context) && dpm.isManagedProfile(receiver))) { SubPageItem(R.string.wipe_data, "", R.drawable.device_reset_fill0) { navCtrl.navigate("WipeData") } } Spacer(Modifier.padding(vertical = 30.dp)) @@ -236,26 +235,26 @@ private fun Home(navCtrl: NavHostController, scrollState: ScrollState, rebootDia @Composable private fun Switches() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context, Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) - if(isDeviceOwner(dpm) || isProfileOwner(dpm)) { + if(dpm.isDeviceOwner(context) || dpm.isProfileOwner(context)) { SwitchItem(R.string.disable_cam,"", R.drawable.photo_camera_fill0, { dpm.getCameraDisabled(null) }, { dpm.setCameraDisabled(receiver,it) } ) } - if(isDeviceOwner(dpm) || isProfileOwner(dpm)) { + if(dpm.isDeviceOwner(context) || dpm.isProfileOwner(context)) { SwitchItem(R.string.disable_screen_capture, stringResource(R.string.also_disable_aosp_screen_record), R.drawable.screenshot_fill0, { dpm.getScreenCaptureDisabled(null) }, { dpm.setScreenCaptureDisabled(receiver,it) } ) } - if(VERSION.SDK_INT >= 34 && (isDeviceOwner(dpm) || (isProfileOwner(dpm) && dpm.isAffiliatedUser))) { + if(VERSION.SDK_INT >= 34 && (dpm.isDeviceOwner(context) || (dpm.isProfileOwner(context) && dpm.isAffiliatedUser))) { SwitchItem(R.string.disable_status_bar, "", R.drawable.notifications_fill0, { dpm.isStatusBarDisabled}, { dpm.setStatusBarDisabled(receiver,it) } ) } - if(isDeviceOwner(dpm) || dpm.isOrgProfile(receiver)) { + if(dpm.isDeviceOwner(context) || dpm.isOrgProfile(receiver)) { if(VERSION.SDK_INT >= 30) { SwitchItem(R.string.auto_time, "", R.drawable.schedule_fill0, { dpm.getAutoTimeEnabled(receiver) }, { dpm.setAutoTimeEnabled(receiver,it) } @@ -267,27 +266,27 @@ private fun Switches() { SwitchItem(R.string.require_auto_time, "", R.drawable.schedule_fill0, { dpm.autoTimeRequired}, { dpm.setAutoTimeRequired(receiver,it) }) } } - if(isDeviceOwner(dpm) || isProfileOwner(dpm)) { + if(dpm.isDeviceOwner(context) || dpm.isProfileOwner(context)) { SwitchItem(R.string.master_mute, "", R.drawable.volume_up_fill0, { dpm.isMasterVolumeMuted(receiver) }, { dpm.setMasterVolumeMuted(receiver,it) } ) } - if(VERSION.SDK_INT >= 26 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { + if(VERSION.SDK_INT >= 26 && (dpm.isDeviceOwner(context) || dpm.isProfileOwner(context))) { SwitchItem(R.string.backup_service, "", R.drawable.backup_fill0, { dpm.isBackupServiceEnabled(receiver) }, { dpm.setBackupServiceEnabled(receiver,it) } ) } - if(VERSION.SDK_INT >= 23 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { + if(VERSION.SDK_INT >= 23 && (dpm.isDeviceOwner(context) || dpm.isProfileOwner(context))) { SwitchItem(R.string.disable_bt_contact_share, "", R.drawable.account_circle_fill0, { dpm.getBluetoothContactSharingDisabled(receiver) }, { dpm.setBluetoothContactSharingDisabled(receiver,it) } ) } - if(VERSION.SDK_INT >= 30 && isDeviceOwner(dpm)) { + if(VERSION.SDK_INT >= 30 && dpm.isDeviceOwner(context)) { SwitchItem(R.string.common_criteria_mode, stringResource(R.string.common_criteria_mode_desc),R.drawable.security_fill0, { dpm.isCommonCriteriaModeEnabled(receiver) }, { dpm.setCommonCriteriaModeEnabled(receiver,it) } ) } - if(VERSION.SDK_INT >= 31 && (isDeviceOwner(dpm) || dpm.isOrgProfile(receiver))) { + if(VERSION.SDK_INT >= 31 && (dpm.isDeviceOwner(context) || dpm.isOrgProfile(receiver))) { SwitchItem( R.string.usb_signal, "", R.drawable.usb_fill0, { dpm.isUsbDataSignalingEnabled }, { @@ -306,8 +305,8 @@ private fun Switches() { @Composable private fun Keyguard() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.keyguard), style = typography.headlineLarge) @@ -317,7 +316,7 @@ private fun Keyguard() { onClick = { Toast.makeText(context, if(dpm.setKeyguardDisabled(receiver,true)) R.string.success else R.string.failed, Toast.LENGTH_SHORT).show() }, - enabled = isDeviceOwner(dpm) || (VERSION.SDK_INT >= 28 && isProfileOwner(dpm) && dpm.isAffiliatedUser), + enabled = dpm.isDeviceOwner(context) || (VERSION.SDK_INT >= 28 && dpm.isProfileOwner(context) && dpm.isAffiliatedUser), modifier = Modifier.fillMaxWidth() ) { Text(stringResource(R.string.disable)) @@ -326,7 +325,7 @@ private fun Keyguard() { onClick = { Toast.makeText(context, if(dpm.setKeyguardDisabled(receiver,false)) R.string.success else R.string.failed, Toast.LENGTH_SHORT).show() }, - enabled = isDeviceOwner(dpm) || (VERSION.SDK_INT >= 28 && isProfileOwner(dpm) && dpm.isAffiliatedUser), + enabled = dpm.isDeviceOwner(context) || (VERSION.SDK_INT >= 28 && dpm.isProfileOwner(context) && dpm.isAffiliatedUser), modifier = Modifier.fillMaxWidth() ) { Text(stringResource(R.string.enable)) @@ -358,8 +357,8 @@ private fun Keyguard() { @Composable private fun BugReportDialog(status: MutableState) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() AlertDialog( onDismissRequest = { status.value = false }, title = { Text(stringResource(R.string.bug_report)) }, @@ -388,8 +387,8 @@ private fun BugReportDialog(status: MutableState) { @Composable private fun RebootDialog(status: MutableState) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() AlertDialog( onDismissRequest = { status.value = false }, title = { Text(stringResource(R.string.reboot)) }, @@ -415,8 +414,8 @@ private fun RebootDialog(status: MutableState) { @Composable private fun EditTime() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) @@ -453,9 +452,9 @@ private fun EditTime() { @Composable private fun EditTimeZone() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager + val dpm = context.getDPM() val focusMgr = LocalFocusManager.current - val receiver = ComponentName(context,Receiver::class.java) + val receiver = context.getReceiver() var expanded by remember { mutableStateOf(false) } var inputTimezone by remember { mutableStateOf("") } Column( @@ -506,8 +505,8 @@ private fun EditTimeZone() { @Composable private fun PermissionPolicy() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { var selectedPolicy by remember { mutableIntStateOf(dpm.getPermissionPolicy(receiver)) } Spacer(Modifier.padding(vertical = 10.dp)) @@ -533,7 +532,7 @@ private fun PermissionPolicy() { @Composable private fun MTEPolicy() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager + val dpm = context.getDPM() Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.mte_policy), style = typography.headlineLarge) @@ -578,7 +577,7 @@ private fun MTEPolicy() { @Composable private fun NearbyStreamingPolicy() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager + val dpm = context.getDPM() Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { var appPolicy by remember { mutableIntStateOf(dpm.nearbyAppStreamingPolicy) } Spacer(Modifier.padding(vertical = 10.dp)) @@ -656,8 +655,8 @@ private fun NearbyStreamingPolicy() { @Composable private fun LockTaskMode() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current val coroutine = rememberCoroutineScope() Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { @@ -838,8 +837,8 @@ private fun LockTaskMode() { @Composable private fun CaCert() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val uri by fileUriFlow.collectAsState() var exist by remember { mutableStateOf(false) } val uriPath = uri.path ?: "" @@ -922,8 +921,8 @@ private fun CaCert() { @Composable private fun SecurityLogs() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context, Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.security_logs), style = typography.headlineLarge) @@ -967,9 +966,9 @@ private fun SecurityLogs() { @Composable fun FactoryResetProtection() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager + val dpm = context.getDPM() val focusMgr = LocalFocusManager.current - val receiver = ComponentName(context,Receiver::class.java) + val receiver = context.getReceiver() var usePolicy by remember { mutableStateOf(false) } var enabled by remember { mutableStateOf(false) } var unsupported by remember { mutableStateOf(false) } @@ -1070,8 +1069,8 @@ fun FactoryResetProtection() { private fun WipeData() { val context = LocalContext.current val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current var warning by remember { mutableStateOf(false) } var wipeDevice by remember { mutableStateOf(false) } @@ -1092,7 +1091,7 @@ private fun WipeData() { stringResource(R.string.wipe_external_storage), externalStorage, { externalStorage = it } ) - if(VERSION.SDK_INT >= 22 && isDeviceOwner(dpm)) { + if(VERSION.SDK_INT >= 22 && dpm.isDeviceOwner(context)) { CheckBoxItem(stringResource(R.string.wipe_reset_protection_data), protectionData, { protectionData = it } ) @@ -1120,7 +1119,7 @@ private fun WipeData() { Text("WipeData") } } - if (VERSION.SDK_INT >= 34 && (isDeviceOwner(dpm) || dpm.isOrgProfile(receiver))) { + if (VERSION.SDK_INT >= 34 && (dpm.isDeviceOwner(context) || dpm.isOrgProfile(receiver))) { Button( onClick = { focusMgr.clearFocus() @@ -1180,8 +1179,8 @@ private fun WipeData() { @Composable private fun SysUpdatePolicy() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) @@ -1270,8 +1269,8 @@ private fun SysUpdatePolicy() { @Composable fun InstallSystemUpdate() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val callback = object: InstallSystemUpdateCallback() { override fun onInstallUpdateError(errorCode: Int, errorMessage: String) { super.onInstallUpdateError(errorCode, errorMessage) diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/UserManager.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/UserManager.kt index 0648413..e5fe40a 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/UserManager.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/UserManager.kt @@ -14,7 +14,6 @@ import android.os.UserHandle import android.os.UserManager import android.provider.MediaStore import android.widget.Toast -import androidx.activity.ComponentActivity import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.ScrollState import androidx.compose.foundation.layout.Arrangement @@ -109,7 +108,7 @@ fun UserManage(navCtrl: NavHostController) { @Composable private fun Home(navCtrl: NavHostController,scrollState: ScrollState) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager + val dpm = context.getDPM() Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)) { Text( text = stringResource(R.string.user_manager), @@ -117,22 +116,22 @@ private fun Home(navCtrl: NavHostController,scrollState: ScrollState) { modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 15.dp) ) SubPageItem(R.string.user_info, "", R.drawable.person_fill0) { navCtrl.navigate("UserInfo") } - if(isDeviceOwner(dpm)) { + if(dpm.isDeviceOwner(context)) { SubPageItem(R.string.user_operation, "", R.drawable.sync_alt_fill0) { navCtrl.navigate("UserOperation") } } - if(VERSION.SDK_INT >= 24 && isDeviceOwner(dpm)) { + if(VERSION.SDK_INT >= 24 && dpm.isDeviceOwner(context)) { SubPageItem(R.string.create_user, "", R.drawable.person_add_fill0) { navCtrl.navigate("CreateUser") } } - if(isDeviceOwner(dpm) || isProfileOwner(dpm)) { + if(dpm.isDeviceOwner(context) || dpm.isProfileOwner(context)) { SubPageItem(R.string.edit_username, "", R.drawable.edit_fill0) { navCtrl.navigate("EditUsername") } } - if(VERSION.SDK_INT >= 23 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { + if(VERSION.SDK_INT >= 23 && (dpm.isDeviceOwner(context) || dpm.isProfileOwner(context))) { SubPageItem(R.string.change_user_icon, "", R.drawable.account_circle_fill0) { navCtrl.navigate("ChangeUserIcon") } } - if(VERSION.SDK_INT >= 28 && isDeviceOwner(dpm)) { + if(VERSION.SDK_INT >= 28 && dpm.isDeviceOwner(context)) { SubPageItem(R.string.user_session_msg, "", R.drawable.notifications_fill0) { navCtrl.navigate("UserSessionMessage") } } - if(VERSION.SDK_INT >= 26 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { + if(VERSION.SDK_INT >= 26 && (dpm.isDeviceOwner(context) || dpm.isProfileOwner(context))) { SubPageItem(R.string.affiliation_id, "", R.drawable.id_card_fill0) { navCtrl.navigate("AffiliationID") } } Spacer(Modifier.padding(vertical = 30.dp)) @@ -143,8 +142,8 @@ private fun Home(navCtrl: NavHostController,scrollState: ScrollState) { @Composable private fun CurrentUserInfo() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context, Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) @@ -159,7 +158,7 @@ private fun CurrentUserInfo() { if (VERSION.SDK_INT >= 28) { val logoutable = dpm.isLogoutEnabled Text(text = stringResource(R.string.user_can_logout, logoutable)) - if(isDeviceOwner(dpm) || isProfileOwner(dpm)) { + if(dpm.isDeviceOwner(context) || dpm.isProfileOwner(context)) { val ephemeralUser = dpm.isEphemeralUser(receiver) Text(text = stringResource(R.string.is_ephemeral_user, ephemeralUser)) } @@ -175,8 +174,8 @@ private fun CurrentUserInfo() { private fun UserOperation() { val context = LocalContext.current val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) @@ -209,7 +208,7 @@ private fun UserOperation() { } Spacer(Modifier.padding(vertical = 5.dp)) if(VERSION.SDK_INT > 28) { - if(isProfileOwner(dpm)&&dpm.isAffiliatedUser) { + if(dpm.isProfileOwner(context)&&dpm.isAffiliatedUser) { Button( onClick = { val result = dpm.logoutUser(receiver) @@ -281,8 +280,8 @@ private fun UserOperation() { private fun CreateUser() { val context = LocalContext.current val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current var userName by remember { mutableStateOf("") } Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { @@ -339,8 +338,8 @@ private fun CreateUser() { @Composable private fun AffiliationID() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current var input by remember { mutableStateOf("") } var list by remember { mutableStateOf("") } @@ -405,8 +404,8 @@ private fun AffiliationID() { @Composable private fun Username() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current var inputUsername by remember { mutableStateOf("") } Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { @@ -444,8 +443,8 @@ private fun Username() { @Composable private fun UserSessionMessage() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() val focusMgr = LocalFocusManager.current val getStart = dpm.getStartUserSessionMessage(receiver)?:"" val getEnd = dpm.getEndUserSessionMessage(receiver)?:"" @@ -501,8 +500,8 @@ private fun UserSessionMessage() { @Composable private fun UserIcon() { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() var getContent by remember { mutableStateOf(false) } val canApply = fileUriFlow.collectAsState().value != Uri.parse("") Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/UserRestriction.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/UserRestriction.kt index fd25984..97b807e 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/UserRestriction.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/UserRestriction.kt @@ -1,13 +1,10 @@ package com.bintianqi.owndroid.dpm import android.annotation.SuppressLint -import android.app.admin.DevicePolicyManager -import android.content.ComponentName import android.content.Context import android.os.Build.VERSION import android.os.UserManager import android.widget.Toast -import androidx.activity.ComponentActivity import androidx.annotation.DrawableRes import androidx.annotation.StringRes import androidx.compose.foundation.ScrollState @@ -33,7 +30,6 @@ import androidx.navigation.compose.composable import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController import com.bintianqi.owndroid.R -import com.bintianqi.owndroid.Receiver import com.bintianqi.owndroid.ui.Animations import com.bintianqi.owndroid.ui.SubPageItem import com.bintianqi.owndroid.ui.SwitchItem @@ -98,8 +94,8 @@ fun UserRestriction(navCtrl: NavHostController) { @Composable private fun Home(navCtrl:NavHostController, scrollState: ScrollState) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context, Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)) { Text( text = stringResource(R.string.user_restrict), @@ -107,8 +103,8 @@ private fun Home(navCtrl:NavHostController, scrollState: ScrollState) { modifier = Modifier.padding(top = 8.dp, bottom = 7.dp, start = 15.dp) ) Text(text = stringResource(R.string.switch_to_disable_feature), modifier = Modifier.padding(start = 15.dp)) - if(isProfileOwner(dpm)) { Text(text = stringResource(R.string.profile_owner_is_restricted), modifier = Modifier.padding(start = 15.dp)) } - if(isProfileOwner(dpm) && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver)))) { + if(dpm.isProfileOwner(context)) { Text(text = stringResource(R.string.profile_owner_is_restricted), modifier = Modifier.padding(start = 15.dp)) } + if(dpm.isProfileOwner(context) && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver)))) { Text(text = stringResource(R.string.some_features_invalid_in_work_profile), modifier = Modifier.padding(start = 15.dp)) } Spacer(Modifier.padding(vertical = 2.dp)) @@ -193,11 +189,11 @@ private fun UserRestrictionItem( leadIcon:Int ) { val context = LocalContext.current - val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context, Receiver::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() SwitchItem( itemName,restrictionDescription,leadIcon, - { if(isDeviceOwner(dpm)||isProfileOwner(dpm)) { dpm.getUserRestrictions(receiver).getBoolean(restriction) }else{ false } }, + { if(dpm.isDeviceOwner(context)||dpm.isProfileOwner(context)) { dpm.getUserRestrictions(receiver).getBoolean(restriction) }else{ false } }, { try{ if(it) { @@ -206,12 +202,12 @@ private fun UserRestrictionItem( dpm.clearUserRestriction(receiver,restriction) } }catch(e:SecurityException) { - if(isProfileOwner(dpm)) { + if(dpm.isProfileOwner(context)) { Toast.makeText(context, R.string.require_device_owner, Toast.LENGTH_SHORT).show() } } }, - isDeviceOwner(dpm)||isProfileOwner(dpm) + dpm.isDeviceOwner(context)||dpm.isProfileOwner(context) ) }