From 88484a932deed05c204f33c9fe49873051fc3c1d Mon Sep 17 00:00:00 2001 From: BinTianqi Date: Sun, 26 May 2024 19:29:56 +0800 Subject: [PATCH] reformat code --- .github/workflows/build.yml | 2 +- .../main/java/com/bintianqi/owndroid/Auth.kt | 24 +- .../com/bintianqi/owndroid/MainActivity.kt | 100 +-- .../bintianqi/owndroid/ManageSpaceActivity.kt | 2 +- .../bintianqi/owndroid/PermissionPicker.kt | 78 +- .../com/bintianqi/owndroid/PkgSelector.kt | 48 +- .../java/com/bintianqi/owndroid/Receiver.kt | 2 +- .../java/com/bintianqi/owndroid/Setting.kt | 76 +- .../main/java/com/bintianqi/owndroid/Utils.kt | 18 +- .../owndroid/dpm/ApplicationManage.kt | 343 ++++----- .../bintianqi/owndroid/dpm/ManagedProfile.kt | 138 ++-- .../com/bintianqi/owndroid/dpm/Network.kt | 527 +++++++------- .../com/bintianqi/owndroid/dpm/Password.kt | 445 ++++++------ .../com/bintianqi/owndroid/dpm/Permissions.kt | 263 ++++--- .../bintianqi/owndroid/dpm/ShizukuActivate.kt | 58 +- .../bintianqi/owndroid/dpm/ShizukuService.kt | 8 +- .../bintianqi/owndroid/dpm/SystemManager.kt | 681 +++++++++--------- .../com/bintianqi/owndroid/dpm/UserManager.kt | 288 ++++---- .../bintianqi/owndroid/dpm/UserRestriction.kt | 258 +++---- .../com/bintianqi/owndroid/ui/Animations.kt | 10 +- .../com/bintianqi/owndroid/ui/Components.kt | 97 +-- .../com/bintianqi/owndroid/ui/theme/Theme.kt | 10 +- 22 files changed, 1759 insertions(+), 1717 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fb1409e..f076b88 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -60,4 +60,4 @@ jobs: uses: actions/upload-artifact@v4 with: name: OwnDroid-CI-${{ env.SHORT_SHA }}-release-signed.apk - path: app/build/outputs/apk/debug/app-debug.apk + path: app/build/outputs/apk/debug/app-release.apk diff --git a/app/src/main/java/com/bintianqi/owndroid/Auth.kt b/app/src/main/java/com/bintianqi/owndroid/Auth.kt index 726b17c..39d1352 100644 --- a/app/src/main/java/com/bintianqi/owndroid/Auth.kt +++ b/app/src/main/java/com/bintianqi/owndroid/Auth.kt @@ -28,12 +28,12 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.launch @Composable -fun AuthScreen(activity: FragmentActivity, showAuth: MutableState){ +fun AuthScreen(activity: FragmentActivity, showAuth: MutableState) { val context = activity.applicationContext val coroutineScope = rememberCoroutineScope() - var canStartAuth by remember{ mutableStateOf(true) } - var fallback by remember{ mutableStateOf(false) } - var startFade by remember{ mutableStateOf(false) } + var canStartAuth by remember { mutableStateOf(true) } + var fallback by remember { mutableStateOf(false) } + var startFade by remember { mutableStateOf(false) } val alpha by animateFloatAsState( targetValue = if(startFade) 0F else 1F, label = "AuthScreenFade", @@ -57,7 +57,7 @@ fun AuthScreen(activity: FragmentActivity, showAuth: MutableState){ } override fun onAuthenticationError(errorCode: Int, errString: CharSequence) { super.onAuthenticationError(errorCode, errString) - when(errorCode){ + when(errorCode) { BiometricPrompt.ERROR_NO_DEVICE_CREDENTIAL -> onAuthSucceed() BiometricPrompt.ERROR_NEGATIVE_BUTTON -> fallback = true else -> canStartAuth = true @@ -65,7 +65,7 @@ fun AuthScreen(activity: FragmentActivity, showAuth: MutableState){ } } LaunchedEffect(fallback) { - if(fallback){ + if(fallback) { val fallbackPromptInfo = promptInfo .setAllowedAuthenticators(BiometricManager.Authenticators.DEVICE_CREDENTIAL) .setSubtitle(context.getText(R.string.auth_with_password)) @@ -85,8 +85,8 @@ fun AuthScreen(activity: FragmentActivity, showAuth: MutableState){ horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center, modifier = Modifier.fillMaxSize().background(MaterialTheme.colorScheme.background) - ){ - LaunchedEffect(Unit){ + ) { + LaunchedEffect(Unit) { delay(300) startAuth(activity, promptInfo, callback) canStartAuth = false @@ -102,20 +102,20 @@ fun AuthScreen(activity: FragmentActivity, showAuth: MutableState){ canStartAuth = false }, enabled = canStartAuth - ){ + ) { Text(text = stringResource(R.string.start)) } } } } -private fun startAuth(activity: FragmentActivity, basicPromptInfo: Builder, callback: AuthenticationCallback){ +private fun startAuth(activity: FragmentActivity, basicPromptInfo: Builder, callback: AuthenticationCallback) { val context = activity.applicationContext val promptInfo = basicPromptInfo val bioManager = BiometricManager.from(context) val sharedPref = context.getSharedPreferences("data", Context.MODE_PRIVATE) - if(sharedPref.getBoolean("bio_auth", false)){ - when(BiometricManager.BIOMETRIC_SUCCESS){ + if(sharedPref.getBoolean("bio_auth", false)) { + when(BiometricManager.BIOMETRIC_SUCCESS) { bioManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG) -> promptInfo .setAllowedAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG) diff --git a/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt b/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt index f510707..d4e613d 100644 --- a/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt +++ b/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt @@ -57,17 +57,17 @@ class MainActivity : FragmentActivity() { WindowCompat.setDecorFitsSystemWindows(window, false) super.onCreate(savedInstanceState) val sharedPref = applicationContext.getSharedPreferences("data", Context.MODE_PRIVATE) - if(sharedPref.getBoolean("auth", false)){ + if(sharedPref.getBoolean("auth", false)) { showAuth.value = true } val locale = applicationContext.resources?.configuration?.locale - zhCN = locale==Locale.SIMPLIFIED_CHINESE||locale==Locale.CHINESE||locale==Locale.CHINA + zhCN = locale == Locale.SIMPLIFIED_CHINESE || locale == Locale.CHINESE || locale == Locale.CHINA setContent { - val materialYou = mutableStateOf(sharedPref.getBoolean("material_you",true)) + val materialYou = mutableStateOf(sharedPref.getBoolean("material_you", true)) val blackTheme = mutableStateOf(sharedPref.getBoolean("black_theme", false)) - OwnDroidTheme(materialYou.value, blackTheme.value){ + OwnDroidTheme(materialYou.value, blackTheme.value) { Home(materialYou, blackTheme) - if(showAuth.value){ + if(showAuth.value) { AuthScreen(this, showAuth) } } @@ -80,7 +80,7 @@ class MainActivity : FragmentActivity() { if( sharedPref.getBoolean("auth", false) && sharedPref.getBoolean("lock_in_background", false) - ){ + ) { showAuth.value = true } } @@ -90,7 +90,7 @@ class MainActivity : FragmentActivity() { @SuppressLint("UnrememberedMutableState") @ExperimentalMaterial3Api @Composable -fun Home(materialYou:MutableState, blackTheme:MutableState){ +fun Home(materialYou:MutableState, blackTheme:MutableState) { val navCtrl = rememberNavController() val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager @@ -100,7 +100,7 @@ fun Home(materialYou:MutableState, blackTheme:MutableState){ val pkgName = mutableStateOf("") val dialogStatus = mutableIntStateOf(0) val backToHome by backToHomeStateFlow.collectAsState() - LaunchedEffect(Unit){ + LaunchedEffect(Unit) { if(backToHome) { navCtrl.navigateUp(); backToHomeStateFlow.value = false } } NavHost( @@ -110,49 +110,49 @@ fun Home(materialYou:MutableState, blackTheme:MutableState){ .fillMaxSize() .background(colorScheme.background) .imePadding() - .pointerInput(Unit) {detectTapGestures(onTap = {focusMgr.clearFocus()})}, + .pointerInput(Unit) { detectTapGestures(onTap = { focusMgr.clearFocus() }) }, enterTransition = Animations.navHostEnterTransition, exitTransition = Animations.navHostExitTransition, popEnterTransition = Animations.navHostPopEnterTransition, popExitTransition = Animations.navHostPopExitTransition - ){ - composable(route = "HomePage"){ HomePage(navCtrl, pkgName) } - composable(route = "SystemManage"){ SystemManage(navCtrl) } - composable(route = "ManagedProfile"){ ManagedProfile(navCtrl) } - composable(route = "Permissions"){ DpmPermissions(navCtrl) } - composable(route = "ApplicationManage"){ ApplicationManage(navCtrl, pkgName, dialogStatus)} - composable(route = "UserRestriction"){ UserRestriction(navCtrl) } - composable(route = "UserManage"){ UserManage(navCtrl) } - composable(route = "Password"){ Password(navCtrl) } - composable(route = "AppSetting"){ AppSetting(navCtrl, materialYou, blackTheme) } - composable(route = "Network"){ Network(navCtrl) } - composable(route = "PackageSelector"){ PackageSelector(navCtrl, pkgName) } - composable(route = "PermissionPicker"){ PermissionPicker(navCtrl) } + ) { + composable(route = "HomePage") { HomePage(navCtrl, pkgName) } + composable(route = "SystemManage") { SystemManage(navCtrl) } + composable(route = "ManagedProfile") { ManagedProfile(navCtrl) } + composable(route = "Permissions") { DpmPermissions(navCtrl) } + composable(route = "ApplicationManage") { ApplicationManage(navCtrl, pkgName, dialogStatus) } + composable(route = "UserRestriction") { UserRestriction(navCtrl) } + composable(route = "UserManage") { UserManage(navCtrl) } + composable(route = "Password") { Password(navCtrl) } + composable(route = "AppSetting") { AppSetting(navCtrl, materialYou, blackTheme) } + composable(route = "Network") { Network(navCtrl) } + composable(route = "PackageSelector") { PackageSelector(navCtrl, pkgName) } + composable(route = "PermissionPicker") { PermissionPicker(navCtrl) } } - LaunchedEffect(Unit){ - val profileInited = sharedPref.getBoolean("ManagedProfileActivated",false) - val profileNotActivated = !profileInited&&isProfileOwner(dpm)&&(VERSION.SDK_INT<24||(VERSION.SDK_INT>=24&&dpm.isManagedProfile(receiver))) - if(profileNotActivated){ + LaunchedEffect(Unit) { + val profileInited = sharedPref.getBoolean("ManagedProfileActivated", false) + val profileNotActivated = !profileInited && isProfileOwner(dpm) && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver))) + if(profileNotActivated) { dpm.setProfileEnabled(receiver) - sharedPref.edit().putBoolean("ManagedProfileActivated",true).apply() + sharedPref.edit().putBoolean("ManagedProfileActivated", true).apply() Toast.makeText(context, R.string.work_profile_activated, Toast.LENGTH_SHORT).show() } } } @Composable -private fun HomePage(navCtrl:NavHostController, pkgName: MutableState){ +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 activateType = stringResource( - if(isDeviceOwner(dpm)){R.string.device_owner} - else if(isProfileOwner(dpm)){ - if(VERSION.SDK_INT>=24&&dpm.isManagedProfile(receiver)){R.string.work_profile_owner}else{R.string.profile_owner} + if(isDeviceOwner(dpm)) { R.string.device_owner } + else if(isProfileOwner(dpm)) { + 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} + else if(dpm.isAdminActive(receiver)) R.string.device_admin else R.string.click_to_activate ) - LaunchedEffect(Unit){ pkgName.value = "" } + LaunchedEffect(Unit) { pkgName.value = "" } Column(modifier = Modifier.background(colorScheme.background).statusBarsPadding().verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 25.dp)) Text( @@ -166,55 +166,55 @@ private fun HomePage(navCtrl:NavHostController, pkgName: MutableState){ .padding(vertical = 8.dp, horizontal = 8.dp) .clip(RoundedCornerShape(15)) .background(color = colorScheme.primary) - .clickable(onClick = {navCtrl.navigate("Permissions")}) + .clickable(onClick = { navCtrl.navigate("Permissions") }) .padding(vertical = 16.dp), verticalAlignment = Alignment.CenterVertically ) { Spacer(modifier = Modifier.padding(start = 22.dp)) Icon( - painter = painterResource(if(dpm.isAdminActive(receiver)){ R.drawable.check_circle_fill1 }else{ R.drawable.block_fill0 }), + painter = painterResource(if(dpm.isAdminActive(receiver)) R.drawable.check_circle_fill1 else R.drawable.block_fill0), contentDescription = null, tint = colorScheme.onPrimary ) Spacer(modifier = Modifier.padding(start = 10.dp)) Column { Text( - text = stringResource(if(dpm.isAdminActive(receiver)){R.string.activated}else{R.string.deactivated}), + text = stringResource(if(dpm.isAdminActive(receiver)) R.string.activated else R.string.deactivated), style = typography.headlineSmall, color = colorScheme.onPrimary, modifier = Modifier.padding(bottom = 2.dp) ) - if(activateType!=""){ Text(text = activateType, color = colorScheme.onPrimary) } + if(activateType != "") { Text(text = activateType, color = colorScheme.onPrimary) } } } 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 && (isDeviceOwner(dpm)) || isProfileOwner(dpm)) { HomePageItem(R.string.network, R.drawable.wifi_fill0, "Network", navCtrl) } if( - (VERSION.SDK_INT<24&&!isDeviceOwner(dpm))||( - VERSION.SDK_INT>=24&&(dpm.isProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE)|| - (isProfileOwner(dpm)&&dpm.isManagedProfile(receiver))) + (VERSION.SDK_INT < 24 && !isDeviceOwner(dpm)) || ( + VERSION.SDK_INT >= 24 && (dpm.isProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE) || + (isProfileOwner(dpm) && dpm.isManagedProfile(receiver))) ) - ){ - HomePageItem(R.string.work_profile, R.drawable.work_fill0, "ManagedProfile",navCtrl) + ) { + HomePageItem(R.string.work_profile, R.drawable.work_fill0, "ManagedProfile", navCtrl) } HomePageItem(R.string.app_manager, R.drawable.apps_fill0, "ApplicationManage", navCtrl) - if(VERSION.SDK_INT>=24){ + if(VERSION.SDK_INT>=24) { HomePageItem(R.string.user_restrict, R.drawable.person_off, "UserRestriction", navCtrl) } - HomePageItem(R.string.user_manager,R.drawable.manage_accounts_fill0,"UserManage",navCtrl) - HomePageItem(R.string.password_and_keyguard, R.drawable.password_fill0, "Password",navCtrl) - HomePageItem(R.string.setting, R.drawable.settings_fill0, "AppSetting",navCtrl) + HomePageItem(R.string.user_manager,R.drawable.manage_accounts_fill0,"UserManage", navCtrl) + HomePageItem(R.string.password_and_keyguard, R.drawable.password_fill0, "Password", navCtrl) + HomePageItem(R.string.setting, R.drawable.settings_fill0, "AppSetting", navCtrl) Spacer(Modifier.padding(vertical = 20.dp)) } } @Composable -fun HomePageItem(name:Int, imgVector:Int, navTo:String, navCtrl:NavHostController){ +fun HomePageItem(name: Int, imgVector: Int, navTo: String, navCtrl: NavHostController) { Row( modifier = Modifier .fillMaxWidth() .clip(RoundedCornerShape(25)) - .clickable(onClick = {navCtrl.navigate(navTo)}) + .clickable(onClick = { navCtrl.navigate(navTo) }) .padding(vertical = 13.dp), verticalAlignment = Alignment.CenterVertically ) { @@ -229,7 +229,7 @@ fun HomePageItem(name:Int, imgVector:Int, navTo:String, navCtrl:NavHostControlle text = stringResource(name), style = typography.headlineSmall, color = colorScheme.onBackground, - modifier = Modifier.padding(bottom = if(zhCN){2}else{0}.dp) + modifier = Modifier.padding(bottom = if(zhCN) { 2 } else { 0 }.dp) ) } } diff --git a/app/src/main/java/com/bintianqi/owndroid/ManageSpaceActivity.kt b/app/src/main/java/com/bintianqi/owndroid/ManageSpaceActivity.kt index 11c6705..be6f0d3 100644 --- a/app/src/main/java/com/bintianqi/owndroid/ManageSpaceActivity.kt +++ b/app/src/main/java/com/bintianqi/owndroid/ManageSpaceActivity.kt @@ -32,7 +32,7 @@ class ManageSpaceActivity: FragmentActivity() { WindowCompat.setDecorFitsSystemWindows(window, false) super.onCreate(savedInstanceState) val sharedPref = applicationContext.getSharedPreferences("data", Context.MODE_PRIVATE) - val materialYou = sharedPref.getBoolean("material_you",true) + val materialYou = sharedPref.getBoolean("material_you", true) val blackTheme = sharedPref.getBoolean("black_theme", false) setContent { OwnDroidTheme(materialYou, blackTheme) { diff --git a/app/src/main/java/com/bintianqi/owndroid/PermissionPicker.kt b/app/src/main/java/com/bintianqi/owndroid/PermissionPicker.kt index d8999d5..b2b8012 100644 --- a/app/src/main/java/com/bintianqi/owndroid/PermissionPicker.kt +++ b/app/src/main/java/com/bintianqi/owndroid/PermissionPicker.kt @@ -19,20 +19,20 @@ import com.bintianqi.owndroid.ui.NavIcon @OptIn(ExperimentalMaterial3Api::class) @Composable -fun PermissionPicker(navCtrl: NavHostController){ +fun PermissionPicker(navCtrl: NavHostController) { Scaffold( topBar = { TopAppBar( - title = {Text(text = stringResource(R.string.permission_picker))}, - navigationIcon = {NavIcon{navCtrl.navigateUp()}}, + title = { Text(text = stringResource(R.string.permission_picker)) }, + navigationIcon = { NavIcon{ navCtrl.navigateUp() } }, colors = TopAppBarDefaults.topAppBarColors(containerColor = MaterialTheme.colorScheme.background) ) } - ){ paddingValues-> + ) { paddingValues-> LazyColumn( modifier = Modifier.fillMaxSize().padding(top = paddingValues.calculateTopPadding()) - ){ - items(permissionList()){ + ) { + items(permissionList()) { Column( modifier = Modifier .fillMaxWidth() @@ -42,53 +42,53 @@ fun PermissionPicker(navCtrl: NavHostController){ navCtrl.navigateUp() } .padding(vertical = 6.dp, horizontal = 8.dp) - ){ + ) { Text(text = it.first) Text(text = stringResource(it.second), modifier = Modifier.alpha(0.8F)) } } - items(1){ Spacer(Modifier.padding(vertical = 30.dp)) } + items(1) { Spacer(Modifier.padding(vertical = 30.dp)) } } } } private fun permissionList():List>{ val list = mutableListOf>() - list.add(Pair(Manifest.permission.READ_EXTERNAL_STORAGE,R.string.permission_READ_EXTERNAL_STORAGE)) - list.add(Pair(Manifest.permission.WRITE_EXTERNAL_STORAGE,R.string.permission_WRITE_EXTERNAL_STORAGE)) - if(VERSION.SDK_INT>=33){ - list.add(Pair(Manifest.permission.READ_MEDIA_AUDIO,R.string.permission_READ_MEDIA_AUDIO)) - list.add(Pair(Manifest.permission.READ_MEDIA_VIDEO,R.string.permission_READ_MEDIA_VIDEO)) - list.add(Pair(Manifest.permission.READ_MEDIA_IMAGES,R.string.permission_READ_MEDIA_IMAGES)) + list.add(Pair(Manifest.permission.READ_EXTERNAL_STORAGE, R.string.permission_READ_EXTERNAL_STORAGE)) + list.add(Pair(Manifest.permission.WRITE_EXTERNAL_STORAGE, R.string.permission_WRITE_EXTERNAL_STORAGE)) + if(VERSION.SDK_INT >= 33) { + list.add(Pair(Manifest.permission.READ_MEDIA_AUDIO, R.string.permission_READ_MEDIA_AUDIO)) + list.add(Pair(Manifest.permission.READ_MEDIA_VIDEO, R.string.permission_READ_MEDIA_VIDEO)) + list.add(Pair(Manifest.permission.READ_MEDIA_IMAGES, R.string.permission_READ_MEDIA_IMAGES)) } - list.add(Pair(Manifest.permission.CAMERA,R.string.permission_CAMERA)) - list.add(Pair(Manifest.permission.RECORD_AUDIO,R.string.permission_RECORD_AUDIO)) - list.add(Pair(Manifest.permission.ACCESS_COARSE_LOCATION,R.string.permission_ACCESS_COARSE_LOCATION)) - list.add(Pair(Manifest.permission.ACCESS_FINE_LOCATION,R.string.permission_ACCESS_FINE_LOCATION)) - if(VERSION.SDK_INT>=29){ - list.add(Pair(Manifest.permission.ACCESS_BACKGROUND_LOCATION,R.string.permission_ACCESS_BACKGROUND_LOCATION)) + list.add(Pair(Manifest.permission.CAMERA, R.string.permission_CAMERA)) + list.add(Pair(Manifest.permission.RECORD_AUDIO, R.string.permission_RECORD_AUDIO)) + list.add(Pair(Manifest.permission.ACCESS_COARSE_LOCATION, R.string.permission_ACCESS_COARSE_LOCATION)) + list.add(Pair(Manifest.permission.ACCESS_FINE_LOCATION, R.string.permission_ACCESS_FINE_LOCATION)) + if(VERSION.SDK_INT >= 29) { + list.add(Pair(Manifest.permission.ACCESS_BACKGROUND_LOCATION, R.string.permission_ACCESS_BACKGROUND_LOCATION)) } - list.add(Pair(Manifest.permission.READ_CONTACTS,R.string.permission_READ_CONTACTS)) - list.add(Pair(Manifest.permission.WRITE_CONTACTS,R.string.permission_WRITE_CONTACTS)) - list.add(Pair(Manifest.permission.READ_CALENDAR,R.string.permission_READ_CALENDAR)) - list.add(Pair(Manifest.permission.WRITE_CALENDAR,R.string.permission_WRITE_CALENDAR)) - list.add(Pair(Manifest.permission.CALL_PHONE,R.string.permission_CALL_PHONE)) - list.add(Pair(Manifest.permission.READ_PHONE_STATE,R.string.permission_READ_PHONE_STATE)) - list.add(Pair(Manifest.permission.READ_SMS,R.string.permission_READ_SMS)) - list.add(Pair(Manifest.permission.RECEIVE_SMS,R.string.permission_RECEIVE_SMS)) - list.add(Pair(Manifest.permission.SEND_SMS,R.string.permission_SEND_SMS)) - list.add(Pair(Manifest.permission.READ_CALL_LOG,R.string.permission_READ_CALL_LOG)) - list.add(Pair(Manifest.permission.WRITE_CALL_LOG,R.string.permission_WRITE_CALL_LOG)) - list.add(Pair(Manifest.permission.BODY_SENSORS,R.string.permission_BODY_SENSORS)) - if(VERSION.SDK_INT>=33){ - list.add(Pair(Manifest.permission.BODY_SENSORS_BACKGROUND,R.string.permission_BODY_SENSORS_BACKGROUND)) + list.add(Pair(Manifest.permission.READ_CONTACTS, R.string.permission_READ_CONTACTS)) + list.add(Pair(Manifest.permission.WRITE_CONTACTS, R.string.permission_WRITE_CONTACTS)) + list.add(Pair(Manifest.permission.READ_CALENDAR, R.string.permission_READ_CALENDAR)) + list.add(Pair(Manifest.permission.WRITE_CALENDAR, R.string.permission_WRITE_CALENDAR)) + list.add(Pair(Manifest.permission.CALL_PHONE, R.string.permission_CALL_PHONE)) + list.add(Pair(Manifest.permission.READ_PHONE_STATE, R.string.permission_READ_PHONE_STATE)) + list.add(Pair(Manifest.permission.READ_SMS, R.string.permission_READ_SMS)) + list.add(Pair(Manifest.permission.RECEIVE_SMS, R.string.permission_RECEIVE_SMS)) + list.add(Pair(Manifest.permission.SEND_SMS, R.string.permission_SEND_SMS)) + list.add(Pair(Manifest.permission.READ_CALL_LOG, R.string.permission_READ_CALL_LOG)) + list.add(Pair(Manifest.permission.WRITE_CALL_LOG, R.string.permission_WRITE_CALL_LOG)) + list.add(Pair(Manifest.permission.BODY_SENSORS, R.string.permission_BODY_SENSORS)) + if(VERSION.SDK_INT >= 33) { + list.add(Pair(Manifest.permission.BODY_SENSORS_BACKGROUND, R.string.permission_BODY_SENSORS_BACKGROUND)) } - if(VERSION.SDK_INT>29){ - list.add(Pair(Manifest.permission.ACTIVITY_RECOGNITION,R.string.permission_ACTIVITY_RECOGNITION)) + if(VERSION.SDK_INT > 29) { + list.add(Pair(Manifest.permission.ACTIVITY_RECOGNITION, R.string.permission_ACTIVITY_RECOGNITION)) } - if(VERSION.SDK_INT>=33){ - list.add(Pair(Manifest.permission.POST_NOTIFICATIONS,R.string.permission_POST_NOTIFICATIONS)) + if(VERSION.SDK_INT >= 33) { + list.add(Pair(Manifest.permission.POST_NOTIFICATIONS, R.string.permission_POST_NOTIFICATIONS)) } - //list.add(Pair(Manifest.permission.,R.string.)) + //list.add(Pair(Manifest.permission., R.string.)) return list } diff --git a/app/src/main/java/com/bintianqi/owndroid/PkgSelector.kt b/app/src/main/java/com/bintianqi/owndroid/PkgSelector.kt index 88b512a..d99c909 100644 --- a/app/src/main/java/com/bintianqi/owndroid/PkgSelector.kt +++ b/app/src/main/java/com/bintianqi/owndroid/PkgSelector.kt @@ -43,14 +43,14 @@ private val pkgs = mutableListOf() @OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) @Composable -fun PackageSelector(navCtrl:NavHostController, pkgName: MutableState){ +fun PackageSelector(navCtrl: NavHostController, pkgName: MutableState) { val context = LocalContext.current val pm = context.packageManager val apps = pm.getInstalledApplications(0) - var progress by remember{mutableIntStateOf(0)} - var show by remember{mutableStateOf(true)} - var hideProgress by remember{mutableStateOf(true)} - var filter by remember{mutableStateOf("data")} + var progress by remember { mutableIntStateOf(0) } + var show by remember { mutableStateOf(true) } + var hideProgress by remember { mutableStateOf(true) } + var filter by remember { mutableStateOf("data") } val scrollState = rememberLazyListState() val co = rememberCoroutineScope() val getPkgList: suspend ()->Unit = { @@ -58,16 +58,16 @@ fun PackageSelector(navCtrl:NavHostController, pkgName: MutableState){ progress = 0 hideProgress = false pkgs.clear() - for(pkg in apps){ + for(pkg in apps) { val srcDir = pkg.sourceDir pkgs += PkgInfo( pkg.packageName, pkg.loadLabel(pm).toString(), pkg.loadIcon(pm), - if(srcDir.contains("/data/")){ "data" } + if(srcDir.contains("/data/")) { "data" } else if( srcDir.contains("system/priv-app")||srcDir.contains("product/priv-app")|| srcDir.contains("ext/priv-app")||srcDir.contains("vendor/priv-app") - ){"priv"} - else if(srcDir.contains("apex")){"apex"} + ) {"priv"} + else if(srcDir.contains("apex")) {"apex"} else{"system"} ) withContext(Dispatchers.Main) { progress += 1 } @@ -88,17 +88,17 @@ fun PackageSelector(navCtrl:NavHostController, pkgName: MutableState){ .clip(RoundedCornerShape(50)) .combinedClickable( onClick = { - when(filter){ + when(filter) { "data"-> { - filter = "system"; co.launch {scrollState.scrollToItem(0)} + filter = "system"; co.launch {scrollState.scrollToItem(0) } Toast.makeText(context, R.string.show_system_app, Toast.LENGTH_SHORT).show() } "system"-> { - filter = "priv"; co.launch {scrollState.scrollToItem(0)} + filter = "priv"; co.launch {scrollState.scrollToItem(0) } Toast.makeText(context, R.string.show_priv_app, Toast.LENGTH_SHORT).show() } else-> { - filter = "data"; co.launch {scrollState.scrollToItem(0)} + filter = "data"; co.launch {scrollState.scrollToItem(0) } Toast.makeText(context, R.string.show_user_app, Toast.LENGTH_SHORT).show() } } @@ -127,30 +127,30 @@ fun PackageSelector(navCtrl:NavHostController, pkgName: MutableState){ title = { Text(text = stringResource(R.string.pkg_selector)) }, - navigationIcon = { NavIcon{navCtrl.navigateUp()} }, + navigationIcon = { NavIcon{navCtrl.navigateUp() } }, colors = TopAppBarDefaults.topAppBarColors(containerColor = colorScheme.background) ) } - ){paddingValues-> + ) { paddingValues-> LazyColumn( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.fillMaxSize().padding(top = paddingValues.calculateTopPadding()), state = scrollState - ){ - items(1){ + ) { + items(1) { AnimatedVisibility(!hideProgress) { - LinearProgressIndicator(progress = {progress.toFloat()/apps.size}, modifier = Modifier.fillMaxWidth()) + LinearProgressIndicator(progress = { progress.toFloat()/apps.size }, modifier = Modifier.fillMaxWidth()) } } if(show) { items(pkgs) { - if(filter==it.type){ + if(filter == it.type) { PackageItem(it, navCtrl, pkgName) } } - items(1){Spacer(Modifier.padding(vertical = 30.dp))} + items(1) { Spacer(Modifier.padding(vertical = 30.dp)) } }else{ - items(1){ + items(1) { Spacer(Modifier.padding(top = 5.dp)) Text(text = stringResource(R.string.loading), modifier = Modifier.alpha(0.8F)) } @@ -163,14 +163,14 @@ fun PackageSelector(navCtrl:NavHostController, pkgName: MutableState){ } @Composable -private fun PackageItem(pkg: PkgInfo, navCtrl: NavHostController, pkgName: MutableState){ +private fun PackageItem(pkg: PkgInfo, navCtrl: NavHostController, pkgName: MutableState) { Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier .fillMaxWidth() - .clickable{ pkgName.value = pkg.pkgName; navCtrl.navigateUp()} + .clickable{ pkgName.value = pkg.pkgName; navCtrl.navigateUp() } .padding(vertical = 3.dp) - ){ + ) { Spacer(Modifier.padding(start = 15.dp)) Image( painter = rememberDrawablePainter(pkg.icon), contentDescription = "App icon", diff --git a/app/src/main/java/com/bintianqi/owndroid/Receiver.kt b/app/src/main/java/com/bintianqi/owndroid/Receiver.kt index 47d92cf..542e784 100644 --- a/app/src/main/java/com/bintianqi/owndroid/Receiver.kt +++ b/app/src/main/java/com/bintianqi/owndroid/Receiver.kt @@ -18,7 +18,7 @@ class Receiver : DeviceAdminReceiver() { super.onEnabled(context, intent) val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val receiver = ComponentName(context, this::class.java) - if(dpm.isAdminActive(receiver)||isProfileOwner(dpm)||isDeviceOwner(dpm)){ + if(dpm.isAdminActive(receiver) || isProfileOwner(dpm) || isDeviceOwner(dpm)){ Toast.makeText(context, context.getString(R.string.onEnabled), Toast.LENGTH_SHORT).show() } } diff --git a/app/src/main/java/com/bintianqi/owndroid/Setting.kt b/app/src/main/java/com/bintianqi/owndroid/Setting.kt index a8aa3e4..337edd8 100644 --- a/app/src/main/java/com/bintianqi/owndroid/Setting.kt +++ b/app/src/main/java/com/bintianqi/owndroid/Setting.kt @@ -24,22 +24,14 @@ import androidx.navigation.compose.rememberNavController import com.bintianqi.owndroid.ui.* @Composable -fun AppSetting(navCtrl:NavHostController, materialYou: MutableState, blackTheme: MutableState){ +fun AppSetting(navCtrl:NavHostController, materialYou: MutableState, blackTheme: MutableState) { val localNavCtrl = rememberNavController() val backStackEntry by localNavCtrl.currentBackStackEntryAsState() - /*val titleMap = mapOf( - "About" to R.string.about - )*/ Scaffold( topBar = { - /*TopAppBar( - title = {Text(text = stringResource(titleMap[backStackEntry?.destination?.route]?:R.string.setting))}, - navigationIcon = {NavIcon{if(backStackEntry?.destination?.route=="Home"){navCtrl.navigateUp()}else{localNavCtrl.navigateUp()}}}, - colors = TopAppBarDefaults.topAppBarColors(containerColor = colorScheme.surfaceVariant) - )*/ TopBar(backStackEntry, navCtrl, localNavCtrl) } - ){ + ) { NavHost( navController = localNavCtrl, startDestination = "Home", enterTransition = Animations.navHostEnterTransition, @@ -47,44 +39,44 @@ fun AppSetting(navCtrl:NavHostController, materialYou: MutableState, bl popEnterTransition = Animations.navHostPopEnterTransition, popExitTransition = Animations.navHostPopExitTransition, modifier = Modifier.padding(top = it.calculateTopPadding()) - ){ - composable(route = "Home"){ Home(localNavCtrl) } - composable(route = "Theme"){ ThemeSettings(materialYou, blackTheme) } - composable(route = "Auth"){ AuthSettings() } - composable(route = "About"){ About() } + ) { + composable(route = "Home") { Home(localNavCtrl) } + composable(route = "Theme") { ThemeSettings(materialYou, blackTheme) } + composable(route = "Auth") { AuthSettings() } + composable(route = "About") { About() } } } } @Composable -private fun Home(navCtrl: NavHostController){ - Column(modifier = Modifier.fillMaxSize()){ - SubPageItem(R.string.theme,"",R.drawable.format_paint_fill0){navCtrl.navigate("Theme")} - SubPageItem(R.string.security,"",R.drawable.lock_fill0){navCtrl.navigate("Auth")} - SubPageItem(R.string.about,"",R.drawable.info_fill0){navCtrl.navigate("About")} +private fun Home(navCtrl: NavHostController) { + Column(modifier = Modifier.fillMaxSize()) { + SubPageItem(R.string.theme, "", R.drawable.format_paint_fill0) { navCtrl.navigate("Theme") } + SubPageItem(R.string.security, "", R.drawable.lock_fill0) { navCtrl.navigate("Auth") } + SubPageItem(R.string.about, "", R.drawable.info_fill0) { navCtrl.navigate("About") } } } @Composable -private fun ThemeSettings(materialYou:MutableState, blackTheme:MutableState){ +private fun ThemeSettings(materialYou:MutableState, blackTheme:MutableState) { val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE) Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) { - if(VERSION.SDK_INT>=31){ + if(VERSION.SDK_INT>=31) { SwitchItem( R.string.material_you_color, stringResource(R.string.dynamic_color_desc), null, { sharedPref.getBoolean("material_you",true) }, { - sharedPref.edit().putBoolean("material_you",it).apply() + sharedPref.edit().putBoolean("material_you", it).apply() materialYou.value = it } ) } - if(isSystemInDarkTheme()){ + if(isSystemInDarkTheme()) { SwitchItem( R.string.amoled_black, stringResource(R.string.blackTheme_desc), null, { sharedPref.getBoolean("black_theme",false) }, { - sharedPref.edit().putBoolean("black_theme",it).apply() + sharedPref.edit().putBoolean("black_theme", it).apply() blackTheme.value = it } ) @@ -93,7 +85,7 @@ private fun ThemeSettings(materialYou:MutableState, blackTheme:MutableS } @Composable -private fun AuthSettings(){ +private fun AuthSettings() { val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE) var auth by remember{ mutableStateOf(sharedPref.getBoolean("auth",false)) } Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) { @@ -101,28 +93,28 @@ private fun AuthSettings(){ R.string.lock_owndroid, "", null, { auth }, { - sharedPref.edit().putBoolean("auth",it).apply() - auth = sharedPref.getBoolean("auth",false) + sharedPref.edit().putBoolean("auth", it).apply() + auth = sharedPref.getBoolean("auth", false) } ) - if(auth){ + if(auth) { SwitchItem( R.string.enable_bio_auth, "", null, - { sharedPref.getBoolean("bio_auth",false) }, - { sharedPref.edit().putBoolean("bio_auth",it).apply() } + { sharedPref.getBoolean("bio_auth", false) }, + { sharedPref.edit().putBoolean("bio_auth", it).apply() } ) SwitchItem( R.string.lock_in_background, stringResource(R.string.developing), null, - { sharedPref.getBoolean("lock_in_background",false) }, - { sharedPref.edit().putBoolean("lock_in_background",it).apply() } + { sharedPref.getBoolean("lock_in_background", false) }, + { sharedPref.edit().putBoolean("lock_in_background", it).apply() } ) } SwitchItem( R.string.protect_storage, "", null, - { sharedPref.getBoolean("protect_storage",false) }, - { sharedPref.edit().putBoolean("protect_storage",it).apply() } + { sharedPref.getBoolean("protect_storage", false) }, + { sharedPref.edit().putBoolean("protect_storage", it).apply() } ) - Box(modifier = Modifier.padding(horizontal = 8.dp)){ + Box(modifier = Modifier.padding(horizontal = 8.dp)) { Information { Text(text = stringResource(R.string.auth_on_start)) } @@ -131,26 +123,26 @@ private fun AuthSettings(){ } @Composable -private fun About(){ +private fun About() { val context = LocalContext.current val pkgInfo = context.packageManager.getPackageInfo(context.packageName,0) val verCode = pkgInfo.versionCode val verName = pkgInfo.versionName - Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) - Column(modifier = Modifier.padding(horizontal = 8.dp)){ + Column(modifier = Modifier.padding(horizontal = 8.dp)) { Text(text = stringResource(R.string.about), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) Text(text = stringResource(R.string.app_name)+" v$verName ($verCode)") Text(text = stringResource(R.string.about_desc)) Spacer(Modifier.padding(vertical = 5.dp)) } - SubPageItem(R.string.user_guide,"",R.drawable.open_in_new){shareLink(context, "https://github.com/BinTianqi/AndroidOwner/blob/master/Guide.md")} - SubPageItem(R.string.source_code,"",R.drawable.open_in_new){shareLink(context, "https://github.com/BinTianqi/AndroidOwner")} + SubPageItem(R.string.user_guide, "", R.drawable.open_in_new) { shareLink(context, "https://github.com/BinTianqi/AndroidOwner/blob/master/Guide.md") } + SubPageItem(R.string.source_code, "", R.drawable.open_in_new) { shareLink(context, "https://github.com/BinTianqi/AndroidOwner") } } } -fun shareLink(inputContext:Context,link:String){ +fun shareLink(inputContext:Context,link:String) { val uri = Uri.parse(link) val intent = Intent(Intent.ACTION_VIEW, uri) inputContext.startActivity(Intent.createChooser(intent, "Open in browser"),null) diff --git a/app/src/main/java/com/bintianqi/owndroid/Utils.kt b/app/src/main/java/com/bintianqi/owndroid/Utils.kt index 1ea983e..9085970 100644 --- a/app/src/main/java/com/bintianqi/owndroid/Utils.kt +++ b/app/src/main/java/com/bintianqi/owndroid/Utils.kt @@ -22,16 +22,16 @@ var zhCN = true fun uriToStream( context: Context, uri: Uri?, - operation:(stream: InputStream)->Unit + operation: (stream: InputStream)->Unit ){ if(uri!=null){ try{ val stream = context.contentResolver.openInputStream(uri) - if(stream!=null) { operation(stream) } + if(stream != null) { operation(stream) } stream?.close() } - catch(e: FileNotFoundException){ Toast.makeText(context, R.string.file_not_exist, Toast.LENGTH_SHORT).show() } - catch(e: IOException){ Toast.makeText(context, R.string.io_exception, Toast.LENGTH_SHORT).show() } + catch(e: FileNotFoundException) { Toast.makeText(context, R.string.file_not_exist, Toast.LENGTH_SHORT).show() } + catch(e: IOException) { Toast.makeText(context, R.string.io_exception, Toast.LENGTH_SHORT).show() } } } @@ -39,18 +39,18 @@ fun List.toText():String{ var output = "" var isFirst = true for(each in listIterator()){ - if(isFirst){isFirst=false}else{output+="\n"} + if(isFirst) { isFirst = false } else { output+="\n" } output+=each } return output } -fun Set.toText():String{ +fun Set.toText(): String{ var output = "" var isFirst = true for(each in iterator()){ - if(isFirst){isFirst=false}else{output+="\n"} - output+=each + if(isFirst) { isFirst = false } else { output+="\n" } + output += each } return output } @@ -67,7 +67,7 @@ fun writeClipBoard(context: Context, string: String):Boolean{ fun registerActivityResult(context: ComponentActivity){ - getFile = context.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {activityResult -> + getFile = context.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { activityResult -> activityResult.data.let { if(it==null){ Toast.makeText(context.applicationContext, R.string.file_not_exist, Toast.LENGTH_SHORT).show() 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 1e19d6b..0f715bb 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/ApplicationManage.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/ApplicationManage.kt @@ -67,7 +67,7 @@ private var dialogDismissButtonAction = {} private var dialogGetStatus = { false } @Composable -fun ApplicationManage(navCtrl:NavHostController, pkgName: MutableState, dialogStatus: MutableIntState){ +fun ApplicationManage(navCtrl:NavHostController, pkgName: MutableState, dialogStatus: MutableIntState) { val focusMgr = LocalFocusManager.current val localNavCtrl = rememberNavController() val backStackEntry by localNavCtrl.currentBackStackEntryAsState() @@ -88,18 +88,15 @@ fun ApplicationManage(navCtrl:NavHostController, pkgName: MutableState, ) Scaffold( topBar = { - /*TopAppBar( - title = {Text(text = stringResource(titleMap[backStackEntry?.destination?.route]?:R.string.app_manage))}, - navigationIcon = {NavIcon{if(backStackEntry?.destination?.route=="Home"){navCtrl.navigateUp()}else{localNavCtrl.navigateUp()}}}, - colors = TopAppBarDefaults.topAppBarColors(containerColor = colorScheme.surfaceVariant) - )*/ - TopBar(backStackEntry, navCtrl, localNavCtrl){Text(text = stringResource(titleMap[backStackEntry?.destination?.route] ?: R.string.app_manager))} + TopBar(backStackEntry, navCtrl, localNavCtrl) { + Text(text = stringResource(titleMap[backStackEntry?.destination?.route] ?: R.string.app_manager)) + } } - ){ paddingValues-> + ) { paddingValues-> Column( modifier = Modifier.fillMaxSize().padding(top = paddingValues.calculateTopPadding()) ) { - if(backStackEntry?.destination?.route!="InstallApp"){ + if(backStackEntry?.destination?.route!="InstallApp") { TextField( value = pkgName.value, onValueChange = { pkgName.value = it }, @@ -123,31 +120,31 @@ fun ApplicationManage(navCtrl:NavHostController, pkgName: MutableState, exitTransition = Animations.navHostExitTransition, popEnterTransition = Animations.navHostPopEnterTransition, popExitTransition = Animations.navHostPopExitTransition - ){ - composable(route = "Home"){Home(localNavCtrl, pkgName.value, dialogStatus)} - composable(route = "UserControlDisabled"){UserCtrlDisabledPkg(pkgName.value)} - composable(route = "PermissionManage"){PermissionManage(pkgName.value, navCtrl)} - composable(route = "CrossProfilePackage"){CrossProfilePkg(pkgName.value)} - composable(route = "CrossProfileWidget"){CrossProfileWidget(pkgName.value)} - composable(route = "CredentialManagePolicy"){CredentialManagePolicy(pkgName.value)} - composable(route = "Accessibility"){PermittedAccessibility(pkgName.value)} - composable(route = "IME"){PermittedIME(pkgName.value)} - composable(route = "KeepUninstalled"){KeepUninstalledApp(pkgName.value)} - composable(route = "InstallApp"){InstallApp()} - composable(route = "UninstallApp"){UninstallApp(pkgName.value)} - composable(route = "ClearAppData"){ClearAppData(pkgName.value)} - composable(route = "DefaultDialer"){DefaultDialerApp(pkgName.value)} + ) { + composable(route = "Home") { Home(localNavCtrl, pkgName.value, dialogStatus) } + composable(route = "UserControlDisabled") { UserCtrlDisabledPkg(pkgName.value) } + composable(route = "PermissionManage") { PermissionManage(pkgName.value, navCtrl) } + composable(route = "CrossProfilePackage") { CrossProfilePkg(pkgName.value) } + composable(route = "CrossProfileWidget") { CrossProfileWidget(pkgName.value) } + composable(route = "CredentialManagePolicy") { CredentialManagePolicy(pkgName.value) } + composable(route = "Accessibility") { PermittedAccessibility(pkgName.value) } + composable(route = "IME") { PermittedIME(pkgName.value) } + composable(route = "KeepUninstalled") { KeepUninstalledApp(pkgName.value) } + composable(route = "InstallApp") { InstallApp() } + composable(route = "UninstallApp") { UninstallApp(pkgName.value) } + composable(route = "ClearAppData") { ClearAppData(pkgName.value) } + composable(route = "DefaultDialer") { DefaultDialerApp(pkgName.value) } } } } - if(dialogStatus.intValue!=0){ + if(dialogStatus.intValue!=0) { LocalFocusManager.current.clearFocus() AppControlDialog(dialogStatus) } } @Composable -private fun Home(navCtrl:NavHostController, pkgName: String, dialogStatus: MutableIntState){ +private fun Home(navCtrl:NavHostController, pkgName: String, dialogStatus: MutableIntState) { Column( modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()) ) { @@ -155,19 +152,19 @@ private fun Home(navCtrl:NavHostController, pkgName: String, dialogStatus: Mutab val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val receiver = ComponentName(context, Receiver::class.java) Spacer(Modifier.padding(vertical = 5.dp)) - if(VERSION.SDK_INT>=24&&isProfileOwner(dpm)&&dpm.isManagedProfile(receiver)){ + if(VERSION.SDK_INT >= 24&&isProfileOwner(dpm)&&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){ + SubPageItem(R.string.app_info,"", R.drawable.open_in_new) { val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) intent.setData(Uri.parse("package:$pkgName")) startActivity(context, intent, null) } - if(VERSION.SDK_INT>=24&&(isDeviceOwner(dpm)||isProfileOwner(dpm))){ + if(VERSION.SDK_INT>=24 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { val getSuspendStatus = { try{ dpm.isPackageSuspended(receiver, pkgName) } - catch(e:NameNotFoundException){ false } - catch(e:IllegalArgumentException){ false } + catch(e:NameNotFoundException) { false } + catch(e:IllegalArgumentException) { false } } SwitchItem( title = R.string.suspend, desc = "", icon = R.drawable.block_fill0, @@ -181,7 +178,7 @@ private fun Home(navCtrl:NavHostController, pkgName: String, dialogStatus: Mutab } ) } - if(isDeviceOwner(dpm) || isProfileOwner(dpm)){ + if(isDeviceOwner(dpm) || isProfileOwner(dpm)) { SwitchItem( title = R.string.hide, desc = stringResource(R.string.isapphidden_desc), icon = R.drawable.visibility_off_fill0, getState = { dpm.isApplicationHidden(receiver,pkgName) }, @@ -207,7 +204,7 @@ private fun Home(navCtrl:NavHostController, pkgName: String, dialogStatus: Mutab } ) } - if(VERSION.SDK_INT>=24&&(isDeviceOwner(dpm)||isProfileOwner(dpm))){ + if(VERSION.SDK_INT>=24 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { val setAlwaysOnVpn: (Boolean)->Unit = { try { dpm.setAlwaysOnVpnPackage(receiver, pkgName, it) @@ -219,7 +216,7 @@ private fun Home(navCtrl:NavHostController, pkgName: String, dialogStatus: Mutab } SwitchItem( title = R.string.always_on_vpn, desc = "", icon = R.drawable.vpn_key_fill0, - getState = {pkgName == dpm.getAlwaysOnVpnPackage(receiver)}, + getState = { pkgName == dpm.getAlwaysOnVpnPackage(receiver) }, onCheckedChange = setAlwaysOnVpn, onClickBlank = { dialogGetStatus = { pkgName == dpm.getAlwaysOnVpnPackage(receiver) } @@ -229,37 +226,37 @@ private fun Home(navCtrl:NavHostController, pkgName: String, dialogStatus: Mutab } ) } - if((VERSION.SDK_INT>=33&&isProfileOwner(dpm))||(VERSION.SDK_INT>=30&&isDeviceOwner(dpm))){ - SubPageItem(R.string.ucd,"",R.drawable.do_not_touch_fill0){navCtrl.navigate("UserControlDisabled")} + if((VERSION.SDK_INT>=33&&isProfileOwner(dpm))||(VERSION.SDK_INT>=30&&isDeviceOwner(dpm))) { + SubPageItem(R.string.ucd, "", R.drawable.do_not_touch_fill0) { navCtrl.navigate("UserControlDisabled") } } - if(VERSION.SDK_INT>=23&&(isDeviceOwner(dpm)||isProfileOwner(dpm))){ - SubPageItem(R.string.permission_manage,"",R.drawable.key_fill0){navCtrl.navigate("PermissionManage")} + if(VERSION.SDK_INT>=23&&(isDeviceOwner(dpm)||isProfileOwner(dpm))) { + SubPageItem(R.string.permission_manage, "", R.drawable.key_fill0) { navCtrl.navigate("PermissionManage") } } - if(VERSION.SDK_INT>=30&&isProfileOwner(dpm)&&dpm.isManagedProfile(receiver)){ - SubPageItem(R.string.cross_profile_package,"",R.drawable.work_fill0){navCtrl.navigate("CrossProfilePackage")} + if(VERSION.SDK_INT>=30&&isProfileOwner(dpm)&&dpm.isManagedProfile(receiver)) { + SubPageItem(R.string.cross_profile_package, "", R.drawable.work_fill0) { navCtrl.navigate("CrossProfilePackage") } } - if(isProfileOwner(dpm)){ - SubPageItem(R.string.cross_profile_widget,"",R.drawable.widgets_fill0){navCtrl.navigate("CrossProfileWidget")} + if(isProfileOwner(dpm)) { + SubPageItem(R.string.cross_profile_widget, "", R.drawable.widgets_fill0) { navCtrl.navigate("CrossProfileWidget") } } - if(VERSION.SDK_INT>=34&&isDeviceOwner(dpm)){ - SubPageItem(R.string.credential_manage_policy,"",R.drawable.license_fill0){navCtrl.navigate("CredentialManagePolicy")} + if(VERSION.SDK_INT>=34&&isDeviceOwner(dpm)) { + SubPageItem(R.string.credential_manage_policy, "", R.drawable.license_fill0) { navCtrl.navigate("CredentialManagePolicy") } } - if(isProfileOwner(dpm)||isDeviceOwner(dpm)){ - SubPageItem(R.string.permitted_accessibility_app,"",R.drawable.settings_accessibility_fill0){navCtrl.navigate("Accessibility")} + if(isProfileOwner(dpm)||isDeviceOwner(dpm)) { + SubPageItem(R.string.permitted_accessibility_app, "", R.drawable.settings_accessibility_fill0) { navCtrl.navigate("Accessibility") } } - if(isDeviceOwner(dpm)||isProfileOwner(dpm)){ - SubPageItem(R.string.permitted_ime,"",R.drawable.keyboard_fill0){navCtrl.navigate("IME")} + if(isDeviceOwner(dpm)||isProfileOwner(dpm)) { + SubPageItem(R.string.permitted_ime, "", R.drawable.keyboard_fill0) { navCtrl.navigate("IME") } } - if(VERSION.SDK_INT>=28&&isDeviceOwner(dpm)){ - SubPageItem(R.string.keep_uninstalled_pkgs,"",R.drawable.delete_fill0){navCtrl.navigate("KeepUninstalled")} + if(VERSION.SDK_INT>=28&&isDeviceOwner(dpm)) { + SubPageItem(R.string.keep_uninstalled_pkgs, "", R.drawable.delete_fill0) { navCtrl.navigate("KeepUninstalled") } } - if(VERSION.SDK_INT>=28){ - SubPageItem(R.string.clear_app_data,"",R.drawable.mop_fill0){navCtrl.navigate("ClearAppData")} + if(VERSION.SDK_INT>=28) { + SubPageItem(R.string.clear_app_data, "", R.drawable.mop_fill0) { navCtrl.navigate("ClearAppData") } } - 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){ - SubPageItem(R.string.set_default_dialer,"",R.drawable.call_fill0){navCtrl.navigate("DefaultDialer")} + 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) { + SubPageItem(R.string.set_default_dialer, "", R.drawable.call_fill0) { navCtrl.navigate("DefaultDialer") } } Spacer(Modifier.padding(vertical = 30.dp)) LaunchedEffect(Unit) { fileUriFlow.value = Uri.parse("") } @@ -268,11 +265,11 @@ private fun Home(navCtrl:NavHostController, pkgName: String, dialogStatus: Mutab @SuppressLint("NewApi") @Composable -private fun UserCtrlDisabledPkg(pkgName:String){ +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) - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { var pkgList = dpm.getUserControlDisabledPackages(receiver) var listText by remember{mutableStateOf("")} val refresh = { @@ -280,21 +277,21 @@ private fun UserCtrlDisabledPkg(pkgName:String){ listText = pkgList.toText() } var inited by remember{mutableStateOf(false)} - if(!inited){refresh();inited=true} + if(!inited) { refresh();inited=true } Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.ucd), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) Text(text = stringResource(R.string.ucd_desc)) Spacer(Modifier.padding(vertical = 5.dp)) Text(text = stringResource(R.string.app_list_is)) - SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize()){ - Text(text = if(listText==""){stringResource(R.string.none)}else{listText}) + SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize()) { + Text(text = if(listText=="") { stringResource(R.string.none)}else{listText}) } Spacer(Modifier.padding(vertical = 5.dp)) - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { Button( onClick = { - if(pkgName!=""){ + if(pkgName!="") { pkgList.add(pkgName) dpm.setUserControlDisabledPackages(receiver,pkgList) refresh() @@ -303,13 +300,13 @@ private fun UserCtrlDisabledPkg(pkgName:String){ } }, modifier = Modifier.fillMaxWidth(0.49F) - ){ + ) { Text(stringResource(R.string.add)) } Button( onClick = { - val result = if(pkgName!=""){pkgList.remove(pkgName)}else{false} - if(result){ + val result = if(pkgName!="") { pkgList.remove(pkgName)}else{false} + if(result) { dpm.setUserControlDisabledPackages(receiver,pkgList) refresh() }else{ @@ -317,14 +314,14 @@ private fun UserCtrlDisabledPkg(pkgName:String){ } }, modifier = Modifier.fillMaxWidth(0.96F) - ){ + ) { Text(stringResource(R.string.remove)) } } Button( onClick = { dpm.setUserControlDisabledPackages(receiver, listOf()); refresh() }, modifier = Modifier.fillMaxWidth() - ){ + ) { Text(stringResource(R.string.clear_list)) } Spacer(Modifier.padding(vertical = 30.dp)) @@ -333,7 +330,7 @@ private fun UserCtrlDisabledPkg(pkgName:String){ @SuppressLint("NewApi") @Composable -private fun PermissionManage(pkgName: String, navCtrl: NavHostController){ +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) @@ -352,34 +349,34 @@ private fun PermissionManage(pkgName: String, navCtrl: NavHostController){ } } LaunchedEffect(pkgName) { - if(pkgName!=""){currentState = grantState[dpm.getPermissionGrantState(receiver,pkgName,inputPermission)]!!} + if(pkgName!="") { currentState = grantState[dpm.getPermissionGrantState(receiver,pkgName,inputPermission)]!! } } - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.permission_manage), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) OutlinedTextField( value = inputPermission, - label = { Text(stringResource(R.string.permission))}, + label = { Text(stringResource(R.string.permission)) }, onValueChange = { inputPermission = it; selectedPermission = inputPermission currentState = grantState[dpm.getPermissionGrantState(receiver,pkgName,inputPermission)]!! }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Ascii, imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth(), trailingIcon = { Icon(painter = painterResource(R.drawable.checklist_fill0), contentDescription = null, modifier = Modifier .clip(RoundedCornerShape(50)) - .clickable(onClick = {navCtrl.navigate("PermissionPicker")}) + .clickable(onClick = { navCtrl.navigate("PermissionPicker") }) .padding(3.dp)) } ) Spacer(Modifier.padding(vertical = 5.dp)) Text(stringResource(R.string.current_state, currentState)) Spacer(Modifier.padding(vertical = 5.dp)) - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { Button( onClick = { dpm.setPermissionGrantState(receiver,pkgName,inputPermission, PERMISSION_GRANT_STATE_GRANTED) @@ -414,11 +411,11 @@ private fun PermissionManage(pkgName: String, navCtrl: NavHostController){ @SuppressLint("NewApi") @Composable -private fun CrossProfilePkg(pkgName: String){ +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) - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.cross_profile_package), style = typography.headlineLarge) var list by remember{mutableStateOf("")} @@ -426,16 +423,15 @@ private fun CrossProfilePkg(pkgName: String){ crossProfilePkg = dpm.getCrossProfilePackages(receiver) list = crossProfilePkg.toText() } - LaunchedEffect(Unit){refresh()} + LaunchedEffect(Unit) { refresh() } Text(text = stringResource(R.string.app_list_is)) - SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize()){ - Text(text = if(list==""){stringResource(R.string.none)}else{list}) + SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize()) { + Text(text = if(list=="") stringResource(R.string.none) else list) } - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { Button( onClick = { - if(pkgName!=""){ - crossProfilePkg.add(pkgName)} + if(pkgName!="") { crossProfilePkg.add(pkgName) } dpm.setCrossProfilePackages(receiver, crossProfilePkg) refresh() }, @@ -445,8 +441,7 @@ private fun CrossProfilePkg(pkgName: String){ } Button( onClick = { - if(pkgName!=""){ - crossProfilePkg.remove(pkgName)} + if(pkgName!="") { crossProfilePkg.remove(pkgName) } dpm.setCrossProfilePackages(receiver, crossProfilePkg) refresh() }, @@ -460,43 +455,43 @@ private fun CrossProfilePkg(pkgName: String){ } @Composable -private fun CrossProfileWidget(pkgName: String){ +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) - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { var pkgList: MutableList var list by remember{mutableStateOf("")} val refresh = { pkgList = dpm.getCrossProfileWidgetProviders(receiver) list = pkgList.toText() } - LaunchedEffect(Unit){refresh()} + LaunchedEffect(Unit) { refresh()} Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.cross_profile_widget), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) Text(text = stringResource(R.string.app_list_is)) - SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize()){ - Text(text = if(list==""){stringResource(R.string.none)}else{list}) + SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize()) { + Text(text = if(list=="") stringResource(R.string.none) else list) } Spacer(Modifier.padding(vertical = 5.dp)) - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { Button( onClick = { - if(pkgName!=""){dpm.addCrossProfileWidgetProvider(receiver,pkgName)} + if(pkgName!="") { dpm.addCrossProfileWidgetProvider(receiver,pkgName) } refresh() }, modifier = Modifier.fillMaxWidth(0.49F) - ){ + ) { Text(stringResource(R.string.add)) } Button( onClick = { - if(pkgName!=""){dpm.removeCrossProfileWidgetProvider(receiver,pkgName)} + if(pkgName!="") { dpm.removeCrossProfileWidgetProvider(receiver,pkgName) } refresh() }, modifier = Modifier.fillMaxWidth(0.96F) - ){ + ) { Text(stringResource(R.string.remove)) } } @@ -506,7 +501,7 @@ private fun CrossProfileWidget(pkgName: String){ @SuppressLint("NewApi") @Composable -private fun CredentialManagePolicy(pkgName: String){ +private fun CredentialManagePolicy(pkgName: String) { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val focusMgr = LocalFocusManager.current @@ -519,28 +514,42 @@ private fun CredentialManagePolicy(pkgName: String){ credentialList = policy?.packageNames ?: mutableSetOf() credentialList = credentialList.toMutableSet() } - LaunchedEffect(Unit){refreshPolicy(); credentialListText = credentialList.toText()} - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + LaunchedEffect(Unit) { refreshPolicy(); credentialListText = credentialList.toText() } + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.credential_manage_policy), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) - RadioButtonItem(stringResource(R.string.none),{policyType==-1},{policyType=-1}) - RadioButtonItem(stringResource(R.string.blacklist),{policyType==PACKAGE_POLICY_BLOCKLIST},{policyType=PACKAGE_POLICY_BLOCKLIST}) - RadioButtonItem(stringResource(R.string.whitelist),{policyType==PACKAGE_POLICY_ALLOWLIST},{policyType=PACKAGE_POLICY_ALLOWLIST}) - RadioButtonItem(stringResource(R.string.whitelist_and_system_app),{policyType==PACKAGE_POLICY_ALLOWLIST_AND_SYSTEM},{policyType=PACKAGE_POLICY_ALLOWLIST_AND_SYSTEM}) + RadioButtonItem( + stringResource(R.string.none), + { policyType==-1 }, { policyType=-1 } + ) + RadioButtonItem( + stringResource(R.string.blacklist), + { policyType==PACKAGE_POLICY_BLOCKLIST }, + { policyType=PACKAGE_POLICY_BLOCKLIST } + ) + RadioButtonItem( + stringResource(R.string.whitelist), + {policyType==PACKAGE_POLICY_ALLOWLIST}, + {policyType=PACKAGE_POLICY_ALLOWLIST} + ) + RadioButtonItem( + stringResource(R.string.whitelist_and_system_app), + { policyType==PACKAGE_POLICY_ALLOWLIST_AND_SYSTEM }, + { policyType=PACKAGE_POLICY_ALLOWLIST_AND_SYSTEM } + ) Spacer(Modifier.padding(vertical = 5.dp)) AnimatedVisibility(policyType!=-1) { Column { Text(stringResource(R.string.app_list_is)) - SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize(scrollAnim())){ - Text(text = if(credentialListText!=""){ credentialListText }else{ stringResource(R.string.none) }) + SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize(scrollAnim())) { + Text(text = if(credentialListText!="") credentialListText else stringResource(R.string.none)) } Spacer(Modifier.padding(vertical = 10.dp)) - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { Button( onClick = { - if(pkgName!=""){ - credentialList.add(pkgName)} + if(pkgName!="") { credentialList.add(pkgName) } credentialListText = credentialList.toText() }, modifier = Modifier.fillMaxWidth(0.49F) @@ -549,8 +558,7 @@ private fun CredentialManagePolicy(pkgName: String){ } Button( onClick = { - if(pkgName!=""){ - credentialList.remove(pkgName)} + if(pkgName!="") { credentialList.remove(pkgName) } credentialListText = credentialList.toText() }, modifier = Modifier.fillMaxWidth(0.96F) @@ -564,13 +572,13 @@ private fun CredentialManagePolicy(pkgName: String){ onClick = { focusMgr.clearFocus() try{ - if(policyType!=-1&&credentialList.isNotEmpty()){ + if(policyType!=-1&&credentialList.isNotEmpty()) { dpm.credentialManagerPolicy = PackagePolicy(policyType, credentialList) }else{ dpm.credentialManagerPolicy = null } Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() - }catch(e:java.lang.IllegalArgumentException){ + }catch(e:java.lang.IllegalArgumentException) { Toast.makeText(context, R.string.fail, Toast.LENGTH_SHORT).show() }finally { refreshPolicy() @@ -586,29 +594,29 @@ private fun CredentialManagePolicy(pkgName: String){ } @Composable -private fun PermittedAccessibility(pkgName: String){ +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 focusMgr = LocalFocusManager.current - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.permitted_accessibility_app), style = typography.headlineLarge) var listText by remember{ mutableStateOf("") } - LaunchedEffect(Unit){ + LaunchedEffect(Unit) { val getList = dpm.getPermittedAccessibilityServices(receiver) - if(getList!=null){ permittedAccessibility = getList } + if(getList!=null) { permittedAccessibility = getList } listText = permittedAccessibility.toText() } Spacer(Modifier.padding(vertical = 5.dp)) Text(text = stringResource(R.string.app_list_is)) - SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize()){ - Text(text = if(listText==""){stringResource(R.string.none)}else{listText}) + SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize()) { + Text(text = if(listText=="") stringResource(R.string.none) else listText) } Spacer(Modifier.padding(vertical = 5.dp)) - Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceBetween){ + Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceBetween) { Button( - onClick = { permittedAccessibility.add(pkgName); listText = permittedAccessibility.toText()}, + onClick = { permittedAccessibility.add(pkgName); listText = permittedAccessibility.toText() }, modifier = Modifier.fillMaxWidth(0.49F) ) { Text(stringResource(R.string.add)) @@ -625,11 +633,11 @@ private fun PermittedAccessibility(pkgName: String){ focusMgr.clearFocus() Toast.makeText( context, - if(dpm.setPermittedAccessibilityServices(receiver, permittedAccessibility)){R.string.success}else{R.string.fail}, + if(dpm.setPermittedAccessibilityServices(receiver, permittedAccessibility)) R.string.success else R.string.fail , Toast.LENGTH_SHORT ).show() val getList = dpm.getPermittedAccessibilityServices(receiver) - if(getList!=null){ permittedAccessibility = getList } + if(getList!=null) { permittedAccessibility = getList } listText = permittedAccessibility.toText() }, modifier = Modifier.fillMaxWidth() @@ -641,27 +649,27 @@ private fun PermittedAccessibility(pkgName: String){ } @Composable -private fun PermittedIME(pkgName: String){ +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 focusMgr = LocalFocusManager.current - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.permitted_ime), style = typography.headlineLarge) var imeListText by remember{ mutableStateOf("") } - LaunchedEffect(Unit){ + LaunchedEffect(Unit) { val getList = dpm.getPermittedInputMethods(receiver) - if(getList!=null){ permittedIme = getList } + if(getList!=null) { permittedIme = getList } imeListText = permittedIme.toText() } Spacer(Modifier.padding(vertical = 5.dp)) Text(text = stringResource(R.string.app_list_is)) - SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize(scrollAnim())){ - Text(text = if(imeListText==""){stringResource(R.string.none)}else{imeListText}) + SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize(scrollAnim())) { + Text(text = if(imeListText=="") stringResource(R.string.none) else imeListText) } Spacer(Modifier.padding(vertical = 5.dp)) - Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceBetween){ + Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceBetween) { Button( onClick = { permittedIme.add(pkgName); imeListText = permittedIme.toText() }, modifier = Modifier.fillMaxWidth(0.49F) @@ -680,11 +688,11 @@ private fun PermittedIME(pkgName: String){ focusMgr.clearFocus() Toast.makeText( context, - if(dpm.setPermittedInputMethods(receiver, permittedIme)){R.string.success}else{R.string.fail}, + if(dpm.setPermittedInputMethods(receiver, permittedIme)) R.string.success else R.string.fail, Toast.LENGTH_SHORT ).show() val getList = dpm.getPermittedInputMethods(receiver) - if(getList!=null){ permittedIme = getList } + if(getList!=null) { permittedIme = getList } imeListText = permittedIme.toText() }, modifier = Modifier.fillMaxWidth() @@ -697,34 +705,34 @@ private fun PermittedIME(pkgName: String){ @SuppressLint("NewApi") @Composable -private fun KeepUninstalledApp(pkgName: String){ +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 focusMgr = LocalFocusManager.current - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.keep_uninstalled_pkgs), style = typography.headlineLarge) - var listText by remember{mutableStateOf("")} - LaunchedEffect(Unit){ + var listText by remember{ mutableStateOf("") } + LaunchedEffect(Unit) { val getList = dpm.getKeepUninstalledPackages(receiver) - if(getList!=null){ keepUninstallPkg = getList } + if(getList!=null) { keepUninstallPkg = getList } listText = keepUninstallPkg.toText() } Spacer(Modifier.padding(vertical = 5.dp)) Text(text = stringResource(R.string.app_list_is)) - SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize(scrollAnim())){ - Text(text = if(listText==""){stringResource(R.string.none)}else{listText}) + SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize(scrollAnim())) { + Text(text = if(listText=="") stringResource(R.string.none) else listText) } Spacer(Modifier.padding(vertical = 5.dp)) - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { Button( onClick = { keepUninstallPkg.add(pkgName) listText = keepUninstallPkg.toText() }, modifier = Modifier.fillMaxWidth(0.49F) - ){ + ) { Text(stringResource(R.string.add)) } Button( @@ -733,7 +741,7 @@ private fun KeepUninstalledApp(pkgName: String){ listText = keepUninstallPkg.toText() }, modifier = Modifier.fillMaxWidth(0.96F) - ){ + ) { Text(stringResource(R.string.remove)) } } @@ -742,12 +750,12 @@ private fun KeepUninstalledApp(pkgName: String){ focusMgr.clearFocus() dpm.setKeepUninstalledPackages(receiver, keepUninstallPkg) val getList = dpm.getKeepUninstalledPackages(receiver) - if(getList!=null){ keepUninstallPkg = getList } + if(getList!=null) { keepUninstallPkg = getList } listText = keepUninstallPkg.toText() Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() }, modifier = Modifier.fillMaxWidth() - ){ + ) { Text(stringResource(R.string.apply)) } Spacer(Modifier.padding(vertical = 30.dp)) @@ -755,13 +763,13 @@ private fun KeepUninstalledApp(pkgName: String){ } @Composable -private fun UninstallApp(pkgName: String){ +private fun UninstallApp(pkgName: String) { val context = LocalContext.current - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.uninstall_app), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) - Column(modifier = Modifier.fillMaxWidth()){ + Column(modifier = Modifier.fillMaxWidth()) { Button( onClick = { val intent = Intent(context, PackageInstallerReceiver::class.java) @@ -788,11 +796,11 @@ private fun UninstallApp(pkgName: String){ } @Composable -private fun InstallApp(){ +private fun InstallApp() { val context = LocalContext.current val focusMgr = LocalFocusManager.current val selected = fileUriFlow.collectAsState().value != Uri.parse("") - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.install_app), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) @@ -810,9 +818,9 @@ private fun InstallApp(){ } AnimatedVisibility(selected) { Spacer(Modifier.padding(vertical = 3.dp)) - Column(modifier = Modifier.fillMaxWidth()){ + Column(modifier = Modifier.fillMaxWidth()) { Button( - onClick = { uriToStream(context, fileUriFlow.value){stream -> installPackage(context,stream)} }, + onClick = { uriToStream(context, fileUriFlow.value) { stream -> installPackage(context,stream)} }, modifier = Modifier.fillMaxWidth() ) { Text(stringResource(R.string.silent_install)) @@ -835,12 +843,12 @@ private fun InstallApp(){ @SuppressLint("NewApi") @Composable -private fun ClearAppData(pkgName: String){ +private fun ClearAppData(pkgName: String) { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val receiver = ComponentName(context,Receiver::class.java) val focusMgr = LocalFocusManager.current - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Button( onClick = { @@ -848,13 +856,16 @@ private fun ClearAppData(pkgName: String){ val onClear = DevicePolicyManager.OnClearApplicationUserDataListener { pkg: String, succeed: Boolean -> Looper.prepare() focusMgr.clearFocus() - val toastText = if(pkg!=""){"$pkg\n"}else{""} + context.getString(R.string.clear_data) + context.getString(if(succeed){R.string.success}else{R.string.fail}) + val toastText = + if(pkg!="") { "$pkg\n" }else{ "" } + + context.getString(R.string.clear_data) + + context.getString(if(succeed) { R.string.success } else { R.string.fail }) Toast.makeText(context, toastText, Toast.LENGTH_SHORT).show() Looper.loop() } dpm.clearApplicationUserData(receiver, pkgName, executor, onClear) }, - enabled = isDeviceOwner(dpm)||isProfileOwner(dpm), + enabled = isDeviceOwner(dpm) || isProfileOwner(dpm), modifier = Modifier.fillMaxWidth().padding(horizontal = 10.dp) ) { Text(stringResource(R.string.clear_app_data)) @@ -864,21 +875,21 @@ private fun ClearAppData(pkgName: String){ @SuppressLint("NewApi") @Composable -private fun DefaultDialerApp(pkgName: String){ +private fun DefaultDialerApp(pkgName: String) { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Button( onClick = { try{ dpm.setDefaultDialerApplication(pkgName) Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() - }catch(e:IllegalArgumentException){ + }catch(e:IllegalArgumentException) { Toast.makeText(context, R.string.fail, Toast.LENGTH_SHORT).show() } }, - enabled = isDeviceOwner(dpm)||isProfileOwner(dpm), + enabled = isDeviceOwner(dpm) || isProfileOwner(dpm), modifier = Modifier.fillMaxWidth().padding(horizontal = 10.dp) ) { Text(stringResource(R.string.set_default_dialer)) @@ -887,20 +898,20 @@ private fun DefaultDialerApp(pkgName: String){ } @Composable -fun AppControlDialog(status: MutableIntState){ +fun AppControlDialog(status: MutableIntState) { val enabled = dialogGetStatus() Dialog( onDismissRequest = { status.intValue = 0 } ) { Card( modifier = Modifier.fillMaxWidth() - ){ + ) { Column( modifier = Modifier.fillMaxWidth().padding(15.dp) - ){ + ) { Text( text = stringResource( - when(status.intValue){ + when(status.intValue) { 1 -> R.string.suspend 2 -> R.string.hide 3 -> R.string.block_uninstall @@ -912,27 +923,27 @@ fun AppControlDialog(status: MutableIntState){ modifier = Modifier.padding(start = 5.dp) ) Text( - text = stringResource(R.string.current_status_is) + stringResource(if(enabled){R.string.enabled}else{R.string.disabled}), + text = stringResource(R.string.current_status_is) + stringResource(if(enabled) R.string.enabled else R.string.disabled), modifier = Modifier.padding(start = 5.dp, top = 5.dp, bottom = 5.dp) ) Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween - ){ + ) { TextButton( onClick = { status.intValue = 0 } - ){ + ) { Text(text = stringResource(R.string.cancel)) } Row{ TextButton( onClick = { dialogDismissButtonAction(); status.intValue = 0 } - ){ + ) { Text(text = stringResource(R.string.disable)) } TextButton( onClick = { dialogConfirmButtonAction(); status.intValue = 0 } - ){ + ) { Text(text = stringResource(R.string.enable)) } } @@ -943,7 +954,7 @@ fun AppControlDialog(status: MutableIntState){ } @Throws(IOException::class) -private fun installPackage(context: Context, inputStream: InputStream){ +private fun installPackage(context: Context, inputStream: InputStream) { val packageInstaller = context.packageManager.packageInstaller val params = PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL) val sessionId = packageInstaller.createSession(params) 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 3ef994a..e516060 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/ManagedProfile.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/ManagedProfile.kt @@ -43,23 +43,11 @@ import com.bintianqi.owndroid.ui.* fun ManagedProfile(navCtrl: NavHostController) { val localNavCtrl = rememberNavController() val backStackEntry by localNavCtrl.currentBackStackEntryAsState() - /*val titleMap = mapOf( - "OrgOwnedWorkProfile" to R.string.org_owned_work_profile, - "CreateWorkProfile" to R.string.create_work_profile, - "SuspendPersonalApp" to R.string.suspend_personal_app, - "IntentFilter" to R.string.intent_filter, - "OrgID" to R.string.org_id - )*/ Scaffold( topBar = { - /*TopAppBar( - title = {Text(text = stringResource(titleMap[backStackEntry?.destination?.route]?:R.string.work_profile))}, - navigationIcon = {NavIcon{if(backStackEntry?.destination?.route=="Home"){navCtrl.navigateUp()}else{localNavCtrl.navigateUp()}}}, - colors = TopAppBarDefaults.topAppBarColors(containerColor = colorScheme.surfaceVariant) - )*/ - TopBar(backStackEntry,navCtrl, localNavCtrl) + TopBar(backStackEntry, navCtrl, localNavCtrl) } - ){ + ) { NavHost( navController = localNavCtrl, startDestination = "Home", enterTransition = Animations.navHostEnterTransition, @@ -67,69 +55,75 @@ fun ManagedProfile(navCtrl: NavHostController) { popEnterTransition = Animations.navHostPopEnterTransition, popExitTransition = Animations.navHostPopExitTransition, modifier = Modifier.padding(top = it.calculateTopPadding()) - ){ - composable(route = "Home"){Home(localNavCtrl)} - composable(route = "OrgOwnedWorkProfile"){OrgOwnedProfile()} - composable(route = "CreateWorkProfile"){CreateWorkProfile()} - composable(route = "SuspendPersonalApp"){SuspendPersonalApp()} - composable(route = "IntentFilter"){IntentFilter()} - composable(route = "OrgID"){OrgID()} + ) { + composable(route = "Home") { Home(localNavCtrl) } + composable(route = "OrgOwnedWorkProfile") { OrgOwnedProfile() } + composable(route = "CreateWorkProfile") { CreateWorkProfile() } + composable(route = "SuspendPersonalApp") { SuspendPersonalApp() } + composable(route = "IntentFilter") { IntentFilter() } + composable(route = "OrgID") { OrgID() } } } } @Composable -private fun Home(navCtrl: NavHostController){ +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) - Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())){ - Text(text = stringResource(R.string.work_profile), 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)){ - SubPageItem(R.string.org_owned_work_profile,"",R.drawable.corporate_fare_fill0){navCtrl.navigate("OrgOwnedWorkProfile")} + Column( + modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()) + ) { + Text( + text = stringResource(R.string.work_profile), + 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)) { + 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))){ - SubPageItem(R.string.create_work_profile,"",R.drawable.work_fill0){navCtrl.navigate("CreateWorkProfile")} + if(VERSION.SDK_INT<24 || (VERSION.SDK_INT>=24 && dpm.isProvisioningAllowed(ACTION_PROVISION_MANAGED_PROFILE))) { + SubPageItem(R.string.create_work_profile, "", R.drawable.work_fill0) { navCtrl.navigate("CreateWorkProfile") } } - if(VERSION.SDK_INT>=30&&isProfileOwner(dpm)&&dpm.isManagedProfile(receiver)&&dpm.isOrganizationOwnedDeviceWithManagedProfile){ - SubPageItem(R.string.suspend_personal_app,"",R.drawable.block_fill0){navCtrl.navigate("SuspendPersonalApp")} + if(VERSION.SDK_INT >= 30&&isProfileOwner(dpm) && dpm.isManagedProfile(receiver) && dpm.isOrganizationOwnedDeviceWithManagedProfile) { + 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)))){ - 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)))) { + SubPageItem(R.string.intent_filter, "", R.drawable.filter_alt_fill0) { navCtrl.navigate("IntentFilter") } } - if(VERSION.SDK_INT>=31&&(isProfileOwner(dpm)&&dpm.isManagedProfile(receiver))){ - SubPageItem(R.string.org_id,"",R.drawable.corporate_fare_fill0){navCtrl.navigate("OrgID")} + if(VERSION.SDK_INT>=31 && (isProfileOwner(dpm) && dpm.isManagedProfile(receiver))) { + SubPageItem(R.string.org_id, "", R.drawable.corporate_fare_fill0) { navCtrl.navigate("OrgID") } } Spacer(Modifier.padding(vertical = 30.dp)) } } @Composable -private fun CreateWorkProfile(){ +private fun CreateWorkProfile() { val context = LocalContext.current val receiver = ComponentName(context,Receiver::class.java) - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + 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) Spacer(Modifier.padding(vertical = 5.dp)) - var skipEncrypt by remember{mutableStateOf(false)} - if(VERSION.SDK_INT>=24){ - CheckBoxItem(stringResource(R.string.skip_encryption),{skipEncrypt},{skipEncrypt=!skipEncrypt}) + var skipEncrypt by remember { mutableStateOf(false) } + if(VERSION.SDK_INT>=24) { + CheckBoxItem(stringResource(R.string.skip_encryption), { skipEncrypt }, { skipEncrypt=!skipEncrypt }) } Spacer(Modifier.padding(vertical = 5.dp)) Button( onClick = { try { val intent = Intent(ACTION_PROVISION_MANAGED_PROFILE) - if(VERSION.SDK_INT>=23){ + if(VERSION.SDK_INT>=23) { intent.putExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,receiver) }else{ intent.putExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME, context.packageName) } - if(VERSION.SDK_INT>=24){intent.putExtra(EXTRA_PROVISIONING_SKIP_ENCRYPTION,skipEncrypt)} - if(VERSION.SDK_INT>=33){intent.putExtra(EXTRA_PROVISIONING_ALLOW_OFFLINE,true)} + if(VERSION.SDK_INT>=24) { intent.putExtra(EXTRA_PROVISIONING_SKIP_ENCRYPTION,skipEncrypt) } + if(VERSION.SDK_INT>=33) { intent.putExtra(EXTRA_PROVISIONING_ALLOW_OFFLINE,true) } createManagedProfile.launch(intent) - }catch(e:ActivityNotFoundException){ + }catch(e:ActivityNotFoundException) { Toast.makeText(context, R.string.unsupported, Toast.LENGTH_SHORT).show() } }, @@ -142,16 +136,16 @@ private fun CreateWorkProfile(){ @SuppressLint("NewApi") @Composable -private fun OrgOwnedProfile(){ +private fun OrgOwnedProfile() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + 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) Spacer(Modifier.padding(vertical = 5.dp)) Text(text = stringResource(R.string.is_org_owned_profile,dpm.isOrganizationOwnedDeviceWithManagedProfile)) Spacer(Modifier.padding(vertical = 5.dp)) - if(!dpm.isOrganizationOwnedDeviceWithManagedProfile){ + if(!dpm.isOrganizationOwnedDeviceWithManagedProfile) { SelectionContainer { Text( text = stringResource(R.string.activate_org_profile_command, Binder.getCallingUid()/100000), @@ -165,20 +159,20 @@ private fun OrgOwnedProfile(){ @SuppressLint("NewApi") @Composable -private fun OrgID(){ +private fun OrgID() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val focusMgr = LocalFocusManager.current - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ - var orgId by remember{mutableStateOf("")} + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { + var orgId by remember { mutableStateOf("") } Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.org_id), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) OutlinedTextField( value = orgId, onValueChange = {orgId=it}, - label = {Text(stringResource(R.string.org_id))}, + label = { Text(stringResource(R.string.org_id)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Ascii, imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth() ) Spacer(Modifier.padding(vertical = 2.dp)) @@ -193,38 +187,44 @@ private fun OrgID(){ }, enabled = orgId.length in 6..64, modifier = Modifier.fillMaxWidth() - ){ + ) { Text(stringResource(R.string.apply)) } Spacer(Modifier.padding(vertical = 5.dp)) - Information{Text(text = stringResource(R.string.get_specific_id_after_set_org_id))} + Information{ Text(text = stringResource(R.string.get_specific_id_after_set_org_id)) } } } @SuppressLint("NewApi") @Composable -private fun SuspendPersonalApp(){ +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 focusMgr = LocalFocusManager.current - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) SwitchItem( - R.string.suspend_personal_app,"",null,{dpm.getPersonalAppsSuspendedReasons(receiver)!=PERSONAL_APPS_NOT_SUSPENDED}, - {dpm.setPersonalAppsSuspended(receiver,it)} + R.string.suspend_personal_app, "", null, + { dpm.getPersonalAppsSuspendedReasons(receiver)!=PERSONAL_APPS_NOT_SUSPENDED }, + { dpm.setPersonalAppsSuspended(receiver,it) } ) - var time by remember{mutableStateOf("")} + var time by remember { mutableStateOf("") } time = dpm.getManagedProfileMaximumTimeOff(receiver).toString() Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.profile_max_time_off), style = typography.titleLarge) Text(text = stringResource(R.string.profile_max_time_out_desc)) - Text(text = stringResource(R.string.personal_app_suspended_because_timeout, dpm.getPersonalAppsSuspendedReasons(receiver)==PERSONAL_APPS_SUSPENDED_PROFILE_TIMEOUT)) + Text( + text = stringResource( + R.string.personal_app_suspended_because_timeout, + dpm.getPersonalAppsSuspendedReasons(receiver) == PERSONAL_APPS_SUSPENDED_PROFILE_TIMEOUT + ) + ) OutlinedTextField( - value = time, onValueChange = {time=it}, modifier = Modifier.focusable().fillMaxWidth().padding(vertical = 2.dp), - label = {Text(stringResource(R.string.time_unit_ms))}, + value = time, onValueChange = { time=it }, modifier = Modifier.focusable().fillMaxWidth().padding(vertical = 2.dp), + label = { Text(stringResource(R.string.time_unit_ms)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}) + keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus() }) ) Text(text = stringResource(R.string.cannot_less_than_72_hours)) Button( @@ -240,21 +240,21 @@ private fun SuspendPersonalApp(){ } @Composable -private fun IntentFilter(){ +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 focusMgr = LocalFocusManager.current - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ - var action by remember{mutableStateOf("")} + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { + var action by remember { mutableStateOf("") } Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.intent_filter), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) OutlinedTextField( - value = action, onValueChange = {action = it}, - label = {Text("Action")}, + value = action, onValueChange = { action = it }, + label = { Text("Action") }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Ascii, imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth() ) Spacer(Modifier.padding(vertical = 5.dp)) @@ -283,7 +283,7 @@ private fun IntentFilter(){ Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() }, modifier = Modifier.fillMaxWidth() - ){ + ) { Text(stringResource(R.string.clear_cross_profile_filters)) } } 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 7a206f2..ddcda1b 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/Network.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/Network.kt @@ -48,28 +48,14 @@ import com.bintianqi.owndroid.ui.* var ssidSet = mutableSetOf() @Composable -fun Network(navCtrl: NavHostController){ +fun Network(navCtrl: NavHostController) { val localNavCtrl = rememberNavController() val backStackEntry by localNavCtrl.currentBackStackEntryAsState() val scrollState = rememberScrollState() - /*val titleMap = mapOf( - "Home" to R.string.network, - "MinWifiSecurityLevel" to R.string.min_wifi_security_level, - "WifiSsidPolicy" to R.string.wifi_ssid_policy, - "PrivateDNS" to R.string.private_dns, - "NetLog" to R.string.retrieve_net_logs, - "WifiKeypair" to R.string.wifi_keypair, - "APN" to R.string.apn_settings - )*/ Scaffold( topBar = { - /*TopAppBar( - title = {Text(text = stringResource(titleMap[backStackEntry?.destination?.route]?:R.string.network))}, - navigationIcon = {NavIcon{if(backStackEntry?.destination?.route=="Home"){navCtrl.navigateUp()}else{localNavCtrl.navigateUp()}}}, - colors = TopAppBarDefaults.topAppBarColors(containerColor = colorScheme.surfaceVariant) - )*/ - TopBar(backStackEntry,navCtrl,localNavCtrl){ - if(backStackEntry?.destination?.route=="Home"&&scrollState.maxValue>80){ + TopBar(backStackEntry,navCtrl,localNavCtrl) { + if(backStackEntry?.destination?.route == "Home" && scrollState.maxValue > 80) { Text( text = stringResource(R.string.network), modifier = Modifier.alpha((maxOf(scrollState.value-30,0)).toFloat()/80) @@ -77,7 +63,7 @@ fun Network(navCtrl: NavHostController){ } } } - ){ + ) { NavHost( navController = localNavCtrl, startDestination = "Home", enterTransition = Animations.navHostEnterTransition, @@ -85,72 +71,76 @@ fun Network(navCtrl: NavHostController){ popEnterTransition = Animations.navHostPopEnterTransition, popExitTransition = Animations.navHostPopExitTransition, modifier = Modifier.padding(top = it.calculateTopPadding()) - ){ - composable(route = "Home"){Home(localNavCtrl,scrollState)} - composable(route = "Switches"){Switches()} - composable(route = "MinWifiSecurityLevel"){WifiSecLevel()} - composable(route = "WifiSsidPolicy"){WifiSsidPolicy()} - composable(route = "PrivateDNS"){PrivateDNS()} - composable(route = "NetLog"){NetLog()} - composable(route = "WifiKeypair"){WifiKeypair()} - composable(route = "APN"){APN()} + ) { + composable(route = "Home") { Home(localNavCtrl,scrollState) } + composable(route = "Switches") { Switches() } + composable(route = "MinWifiSecurityLevel") { WifiSecLevel() } + composable(route = "WifiSsidPolicy") { WifiSsidPolicy() } + composable(route = "PrivateDNS") { PrivateDNS() } + composable(route = "NetLog") { NetLog() } + composable(route = "WifiKeypair") { WifiKeypair() } + composable(route = "APN") { APN() } } } } @Composable -private fun Home(navCtrl:NavHostController,scrollState: ScrollState){ +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) - 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)){ + 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)) { val wifimac = dpm.getWifiMacAddress(receiver) Text(text = "WiFi MAC: $wifimac", modifier = Modifier.padding(start = 15.dp)) } Spacer(Modifier.padding(vertical = 3.dp)) - if(VERSION.SDK_INT>=30){ - SubPageItem(R.string.options,"",R.drawable.tune_fill0){navCtrl.navigate("Switches")} + if(VERSION.SDK_INT >= 30) { + SubPageItem(R.string.options, "", R.drawable.tune_fill0) { navCtrl.navigate("Switches") } } - if(VERSION.SDK_INT>=33){ - SubPageItem(R.string.min_wifi_security_level,"",R.drawable.wifi_password_fill0){navCtrl.navigate("MinWifiSecurityLevel")} + if(VERSION.SDK_INT >= 33) { + SubPageItem(R.string.min_wifi_security_level, "", R.drawable.wifi_password_fill0) { navCtrl.navigate("MinWifiSecurityLevel") } } - if(VERSION.SDK_INT>=33&&(isDeviceOwner(dpm)||(isProfileOwner(dpm)&&dpm.isOrganizationOwnedDeviceWithManagedProfile))){ - SubPageItem(R.string.wifi_ssid_policy,"",R.drawable.wifi_fill0){navCtrl.navigate("WifiSsidPolicy")} + if(VERSION.SDK_INT >= 33 && (isDeviceOwner(dpm) || (isProfileOwner(dpm) && dpm.isOrganizationOwnedDeviceWithManagedProfile))) { + SubPageItem(R.string.wifi_ssid_policy, "", R.drawable.wifi_fill0) { navCtrl.navigate("WifiSsidPolicy") } } - if(VERSION.SDK_INT>=29&&isDeviceOwner(dpm)){ - SubPageItem(R.string.private_dns,"",R.drawable.dns_fill0){navCtrl.navigate("PrivateDNS")} + if(VERSION.SDK_INT >= 29 && isDeviceOwner(dpm)) { + SubPageItem(R.string.private_dns, "", R.drawable.dns_fill0) { navCtrl.navigate("PrivateDNS") } } - if(VERSION.SDK_INT>=26&&(isDeviceOwner(dpm)||(isProfileOwner(dpm)&&dpm.isManagedProfile(receiver)))){ - SubPageItem(R.string.retrieve_net_logs,"",R.drawable.description_fill0){navCtrl.navigate("NetLog")} + if(VERSION.SDK_INT >= 26&&(isDeviceOwner(dpm) || (isProfileOwner(dpm) && dpm.isManagedProfile(receiver)))) { + SubPageItem(R.string.retrieve_net_logs, "", R.drawable.description_fill0) { navCtrl.navigate("NetLog") } } - if(VERSION.SDK_INT>=31&&(isDeviceOwner(dpm)||isProfileOwner(dpm))){ - SubPageItem(R.string.wifi_keypair,"",R.drawable.key_fill0){navCtrl.navigate("WifiKeypair")} + if(VERSION.SDK_INT >= 31 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { + SubPageItem(R.string.wifi_keypair, "", R.drawable.key_fill0) { navCtrl.navigate("WifiKeypair") } } - if(VERSION.SDK_INT>=28&&isDeviceOwner(dpm)){ - SubPageItem(R.string.apn_settings,"",R.drawable.cell_tower_fill0){navCtrl.navigate("APN")} + if(VERSION.SDK_INT >= 28 && isDeviceOwner(dpm)) { + SubPageItem(R.string.apn_settings, "", R.drawable.cell_tower_fill0) { navCtrl.navigate("APN") } } Spacer(Modifier.padding(vertical = 30.dp)) } } @Composable -private fun Switches(){ +private fun Switches() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val receiver = ComponentName(context,Receiver::class.java) - Column(modifier = Modifier.fillMaxSize()){ + Column(modifier = Modifier.fillMaxSize()) { Spacer(Modifier.padding(vertical = 5.dp)) - if(VERSION.SDK_INT>=33&&isDeviceOwner(dpm)){ + if(VERSION.SDK_INT >= 33 && isDeviceOwner(dpm)) { SwitchItem( - R.string.preferential_network_service, stringResource(R.string.developing),R.drawable.globe_fill0, - {dpm.isPreferentialNetworkServiceEnabled},{dpm.isPreferentialNetworkServiceEnabled = it} + 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)||(isProfileOwner(dpm)&&dpm.isOrganizationOwnedDeviceWithManagedProfile))){ - SwitchItem(R.string.wifi_lockdown,"",R.drawable.wifi_password_fill0, - {dpm.hasLockdownAdminConfiguredNetworks(receiver)},{dpm.setConfiguredNetworksLockdownState(receiver,it)} + if(VERSION.SDK_INT>=30&&(isDeviceOwner(dpm)||(isProfileOwner(dpm)&&dpm.isOrganizationOwnedDeviceWithManagedProfile))) { + SwitchItem(R.string.wifi_lockdown, "", R.drawable.wifi_password_fill0, + { dpm.hasLockdownAdminConfiguredNetworks(receiver) }, { dpm.setConfiguredNetworksLockdownState(receiver,it) } ) } } @@ -158,27 +148,43 @@ private fun Switches(){ @SuppressLint("NewApi") @Composable -private fun WifiSecLevel(){ +private fun WifiSecLevel() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ - var selectedWifiSecLevel by remember{mutableIntStateOf(dpm.minimumRequiredWifiSecurityLevel)} + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { + var selectedWifiSecLevel by remember { mutableIntStateOf(dpm.minimumRequiredWifiSecurityLevel) } Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.min_wifi_security_level), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) - RadioButtonItem(stringResource(R.string.wifi_security_level_open), {selectedWifiSecLevel==WIFI_SECURITY_OPEN}, {selectedWifiSecLevel= WIFI_SECURITY_OPEN}) - RadioButtonItem("WEP, WPA(2)-PSK", {selectedWifiSecLevel==WIFI_SECURITY_PERSONAL}, {selectedWifiSecLevel= WIFI_SECURITY_PERSONAL}) - RadioButtonItem("WPA-EAP", {selectedWifiSecLevel==WIFI_SECURITY_ENTERPRISE_EAP}, {selectedWifiSecLevel= WIFI_SECURITY_ENTERPRISE_EAP}) - RadioButtonItem("WPA3-192bit", {selectedWifiSecLevel==WIFI_SECURITY_ENTERPRISE_192}, {selectedWifiSecLevel= WIFI_SECURITY_ENTERPRISE_192}) + RadioButtonItem( + stringResource(R.string.wifi_security_level_open), + { selectedWifiSecLevel == WIFI_SECURITY_OPEN }, + { selectedWifiSecLevel = WIFI_SECURITY_OPEN } + ) + RadioButtonItem( + "WEP, WPA(2)-PSK", + { selectedWifiSecLevel == WIFI_SECURITY_PERSONAL }, + { selectedWifiSecLevel = WIFI_SECURITY_PERSONAL } + ) + RadioButtonItem( + "WPA-EAP", + { selectedWifiSecLevel == WIFI_SECURITY_ENTERPRISE_EAP }, + { selectedWifiSecLevel = WIFI_SECURITY_ENTERPRISE_EAP } + ) + RadioButtonItem( + "WPA3-192bit", + { selectedWifiSecLevel == WIFI_SECURITY_ENTERPRISE_192 }, + { selectedWifiSecLevel = WIFI_SECURITY_ENTERPRISE_192 } + ) Spacer(Modifier.padding(vertical = 5.dp)) Button( - enabled = isDeviceOwner(dpm)||(isProfileOwner(dpm)&&dpm.isOrganizationOwnedDeviceWithManagedProfile), + enabled = isDeviceOwner(dpm) || (isProfileOwner(dpm) && dpm.isOrganizationOwnedDeviceWithManagedProfile), onClick = { - dpm.minimumRequiredWifiSecurityLevel=selectedWifiSecLevel + dpm.minimumRequiredWifiSecurityLevel = selectedWifiSecLevel Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() }, modifier = Modifier.fillMaxWidth() - ){ + ) { Text(stringResource(R.string.apply)) } } @@ -186,29 +192,41 @@ private fun WifiSecLevel(){ @SuppressLint("NewApi") @Composable -private fun WifiSsidPolicy(){ +private fun WifiSsidPolicy() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val focusMgr = LocalFocusManager.current - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { var policy = dpm.wifiSsidPolicy - var selectedPolicyType by remember{mutableIntStateOf(policy?.policyType ?: -1)} - var inputSsid by remember{mutableStateOf("")} - var ssidList by remember{mutableStateOf("")} + var selectedPolicyType by remember { mutableIntStateOf(policy?.policyType ?: -1) } + var inputSsid by remember { mutableStateOf("") } + var ssidList by remember { mutableStateOf("") } val refreshPolicy = { policy = dpm.wifiSsidPolicy selectedPolicyType = policy?.policyType ?: -1 ssidSet = policy?.ssids ?: mutableSetOf() } - LaunchedEffect(Unit){refreshPolicy(); ssidList= ssidSet.toText()} + LaunchedEffect(Unit) { refreshPolicy(); ssidList= ssidSet.toText() } Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.wifi_ssid_policy), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) - RadioButtonItem(stringResource(R.string.none),{selectedPolicyType==-1},{selectedPolicyType=-1}) - RadioButtonItem(stringResource(R.string.whitelist),{selectedPolicyType==WIFI_SSID_POLICY_TYPE_ALLOWLIST},{selectedPolicyType=WIFI_SSID_POLICY_TYPE_ALLOWLIST}) - RadioButtonItem(stringResource(R.string.blacklist),{selectedPolicyType==WIFI_SSID_POLICY_TYPE_DENYLIST},{selectedPolicyType=WIFI_SSID_POLICY_TYPE_DENYLIST}) - Column(modifier = Modifier.animateContentSize(scrollAnim()).horizontalScroll(rememberScrollState())){ - if(ssidList!=""){ + RadioButtonItem( + stringResource(R.string.none), + { selectedPolicyType == -1 }, + { selectedPolicyType = -1 } + ) + RadioButtonItem( + stringResource(R.string.whitelist), + { selectedPolicyType == WIFI_SSID_POLICY_TYPE_ALLOWLIST }, + { selectedPolicyType = WIFI_SSID_POLICY_TYPE_ALLOWLIST } + ) + RadioButtonItem( + stringResource(R.string.blacklist), + { selectedPolicyType == WIFI_SSID_POLICY_TYPE_DENYLIST }, + { selectedPolicyType = WIFI_SSID_POLICY_TYPE_DENYLIST } + ) + Column(modifier = Modifier.animateContentSize(scrollAnim()).horizontalScroll(rememberScrollState())) { + if(ssidList!="") { Spacer(Modifier.padding(vertical = 5.dp)) Text(stringResource(R.string.ssid_list_is)) SelectionContainer{ @@ -219,21 +237,21 @@ private fun WifiSsidPolicy(){ Spacer(Modifier.padding(vertical = 5.dp)) OutlinedTextField( value = inputSsid, - label = { Text("SSID")}, - onValueChange = {inputSsid = it}, + label = { Text("SSID") }, + onValueChange = {inputSsid = it }, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth() ) Spacer(Modifier.padding(vertical = 5.dp)) - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { Button( onClick = { - if(inputSsid==""){ + if(inputSsid=="") { Toast.makeText(context, R.string.cannot_be_empty, Toast.LENGTH_SHORT).show() - }else if(WifiSsid.fromBytes(inputSsid.toByteArray()) in ssidSet){ + } else if (WifiSsid.fromBytes(inputSsid.toByteArray()) in ssidSet) { Toast.makeText(context, R.string.already_exist, Toast.LENGTH_SHORT).show() - }else{ + } else { ssidSet.add(WifiSsid.fromBytes(inputSsid.toByteArray())) ssidList = ssidSet.toText() } @@ -245,13 +263,13 @@ private fun WifiSsidPolicy(){ } Button( onClick = { - if(inputSsid==""){ + if(inputSsid=="") { Toast.makeText(context, R.string.cannot_be_empty, Toast.LENGTH_SHORT).show() - }else if(WifiSsid.fromBytes(inputSsid.toByteArray()) in ssidSet){ + } else if (WifiSsid.fromBytes(inputSsid.toByteArray()) in ssidSet) { ssidSet.remove(WifiSsid.fromBytes(inputSsid.toByteArray())) inputSsid = "" ssidList = ssidSet.toText() - }else{ + } else { Toast.makeText(context, R.string.not_exist, Toast.LENGTH_SHORT).show() } }, @@ -263,8 +281,8 @@ private fun WifiSsidPolicy(){ Button( onClick = { focusMgr.clearFocus() - if(selectedPolicyType==-1){ - if(policy==null&&ssidSet.isNotEmpty()){ + if(selectedPolicyType == -1) { + if(policy==null && ssidSet.isNotEmpty()) { Toast.makeText(context, R.string.please_select_a_policy, Toast.LENGTH_SHORT).show() }else{ dpm.wifiSsidPolicy = null @@ -272,7 +290,7 @@ private fun WifiSsidPolicy(){ Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() } }else{ - dpm.wifiSsidPolicy = if(ssidSet.size==0){ null }else{ WifiSsidPolicy(selectedPolicyType, ssidSet) } + dpm.wifiSsidPolicy = if(ssidSet.size==0) { null }else{ WifiSsidPolicy(selectedPolicyType, ssidSet) } refreshPolicy() Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() } @@ -287,12 +305,12 @@ private fun WifiSsidPolicy(){ @SuppressLint("NewApi") @Composable -private fun PrivateDNS(){ +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 focusMgr = LocalFocusManager.current - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.private_dns), style = typography.headlineLarge) val dnsStatus = mapOf( @@ -306,7 +324,7 @@ private fun PrivateDNS(){ PRIVATE_DNS_SET_ERROR_HOST_NOT_SERVING to stringResource(R.string.host_not_serving_dns_tls), PRIVATE_DNS_SET_ERROR_FAILURE_SETTING to stringResource(R.string.fail) ) - var status by remember{mutableStateOf(dnsStatus[dpm.getGlobalPrivateDnsMode(receiver)])} + var status by remember { mutableStateOf(dnsStatus[dpm.getGlobalPrivateDnsMode(receiver)]) } Spacer(Modifier.padding(vertical = 5.dp)) Text(text = stringResource(R.string.current_state, status?:stringResource(R.string.unknown))) AnimatedVisibility(visible = dpm.getGlobalPrivateDnsMode(receiver)!=PRIVATE_DNS_MODE_OPPORTUNISTIC) { @@ -323,13 +341,13 @@ private fun PrivateDNS(){ } } Spacer(Modifier.padding(vertical = 10.dp)) - var inputHost by remember{mutableStateOf(dpm.getGlobalPrivateDnsHost(receiver) ?: "")} + var inputHost by remember { mutableStateOf(dpm.getGlobalPrivateDnsHost(receiver) ?: "") } OutlinedTextField( value = inputHost, - onValueChange = {inputHost=it}, - label = {Text(stringResource(R.string.dns_hostname))}, + onValueChange = { inputHost=it }, + label = { Text(stringResource(R.string.dns_hostname)) }, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth() ) Spacer(Modifier.padding(vertical = 3.dp)) @@ -337,14 +355,14 @@ private fun PrivateDNS(){ onClick = { focusMgr.clearFocus() val result: Int - try{ + try { result = dpm.setGlobalPrivateDnsModeSpecifiedHost(receiver,inputHost) Toast.makeText(context, operationResult[result], Toast.LENGTH_SHORT).show() - }catch(e:IllegalArgumentException){ + } catch(e:IllegalArgumentException) { Toast.makeText(context, R.string.invalid_hostname, Toast.LENGTH_SHORT).show() - }catch(e:SecurityException){ + } catch(e:SecurityException) { Toast.makeText(context, R.string.security_exception, Toast.LENGTH_SHORT).show() - }finally { + } finally { status = dnsStatus[dpm.getGlobalPrivateDnsMode(receiver)] } }, @@ -357,23 +375,23 @@ private fun PrivateDNS(){ @SuppressLint("NewApi") @Composable -private fun NetLog(){ +private fun NetLog() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val receiver = ComponentName(context,Receiver::class.java) - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + 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) Spacer(Modifier.padding(vertical = 5.dp)) Text(text = stringResource(R.string.developing)) Spacer(Modifier.padding(vertical = 5.dp)) - SwitchItem(R.string.enable,"",null,{dpm.isNetworkLoggingEnabled(receiver)},{dpm.setNetworkLoggingEnabled(receiver,it)}) + SwitchItem(R.string.enable,"",null, {dpm.isNetworkLoggingEnabled(receiver) }, {dpm.setNetworkLoggingEnabled(receiver,it) }) Spacer(Modifier.padding(vertical = 5.dp)) Button( onClick = { val log = dpm.retrieveNetworkLogs(receiver,1234567890) - if(log!=null){ - for(i in log){ Log.d("NetLog",i.toString()) } + if(log != null) { + for(i in log) { Log.d("NetLog",i.toString()) } Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() }else{ Log.d("NetLog",context.getString(R.string.none)) @@ -389,32 +407,32 @@ private fun NetLog(){ @SuppressLint("NewApi") @Composable -private fun WifiKeypair(){ +private fun WifiKeypair() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val focusMgr = LocalFocusManager.current - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ - var keyPair by remember{mutableStateOf("")} + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { + var keyPair by remember { mutableStateOf("") } Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.wifi_keypair), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) OutlinedTextField( value = keyPair, - label = { Text(stringResource(R.string.keypair))}, - onValueChange = {keyPair = it}, + label = { Text(stringResource(R.string.keypair)) }, + onValueChange = { keyPair = it }, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth() ) Spacer(Modifier.padding(vertical = 5.dp)) - val isExist = try{dpm.isKeyPairGrantedToWifiAuth(keyPair)}catch(e:java.lang.IllegalArgumentException){false} + val isExist = try{ dpm.isKeyPairGrantedToWifiAuth(keyPair) }catch(e:java.lang.IllegalArgumentException) { false } Text(stringResource(R.string.already_exist)+":$isExist") Spacer(Modifier.padding(vertical = 5.dp)) - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { Button( onClick = { val result = dpm.grantKeyPairToWifiAuth(keyPair) - Toast.makeText(context, if(result){R.string.success}else{R.string.fail}, Toast.LENGTH_SHORT).show() + Toast.makeText(context, if(result) R.string.success else R.string.fail, Toast.LENGTH_SHORT).show() }, modifier = Modifier.fillMaxWidth(0.49F) ) { @@ -423,7 +441,7 @@ private fun WifiKeypair(){ Button( onClick = { val result = dpm.revokeKeyPairFromWifiAuth(keyPair) - Toast.makeText(context, if(result){R.string.success}else{R.string.fail}, Toast.LENGTH_SHORT).show() + Toast.makeText(context, if(result) R.string.success else R.string.fail, Toast.LENGTH_SHORT).show() }, modifier = Modifier.fillMaxWidth(0.96F) ) { @@ -435,31 +453,31 @@ private fun WifiKeypair(){ @SuppressLint("NewApi") @Composable -private fun APN(){ +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 focusMgr = LocalFocusManager.current - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { val setting = dpm.getOverrideApns(receiver) - var inputNum by remember{mutableStateOf("0")} - var nextStep by remember{mutableStateOf(false)} + var inputNum by remember { mutableStateOf("0") } + var nextStep by remember { mutableStateOf(false) } val builder = Builder() Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.apn_settings), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) Text(text = stringResource(id = R.string.developing)) Spacer(Modifier.padding(vertical = 5.dp)) - SwitchItem(R.string.enable,"",null,{dpm.isOverrideApnEnabled(receiver)},{dpm.setOverrideApnsEnabled(receiver,it)}) + SwitchItem(R.string.enable, "", null, { dpm.isOverrideApnEnabled(receiver) }, { dpm.setOverrideApnsEnabled(receiver,it) }) Text(text = stringResource(R.string.total_apn_amount, setting.size)) - if(setting.size>0){ + if(setting.size>0) { Text(text = stringResource(R.string.select_a_apn_or_create, setting.size)) TextField( value = inputNum, - label = { Text("APN")}, - onValueChange = {inputNum = it}, + label = { Text("APN") }, + onValueChange = { inputNum = it }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth().padding(vertical = 2.dp), enabled = !nextStep ) @@ -467,59 +485,59 @@ private fun APN(){ Text(text = stringResource(R.string.no_apn_you_should_create_one)) } Button( - onClick = {focusMgr.clearFocus(); nextStep=!nextStep}, + onClick = { focusMgr.clearFocus(); nextStep =! nextStep }, modifier = Modifier.fillMaxWidth(), - enabled = inputNum!=""&&(nextStep||inputNum=="0"||setting[inputNum.toInt()-1]!=null) + enabled = inputNum != "" && (nextStep || inputNum=="0" || setting[inputNum.toInt()-1] != null) ) { - Text(stringResource(if(nextStep){R.string.previous_step}else{R.string.next_step})) + Text(stringResource(if(nextStep) R.string.previous_step else R.string.next_step)) } var result = Builder().build() AnimatedVisibility(nextStep) { - var carrierEnabled by remember{mutableStateOf(false)} - var inputApnName by remember{mutableStateOf("")} - var user by remember{mutableStateOf("")} - var profileId by remember{mutableStateOf("")} - var selectedAuthType by remember{mutableIntStateOf(AUTH_TYPE_NONE)} - var carrierId by remember{mutableStateOf("$UNKNOWN_CARRIER_ID")} - var apnTypeBitmask by remember{mutableStateOf("")} - var entryName by remember{mutableStateOf("")} - var mmsProxyAddress by remember{mutableStateOf("")} - var mmsProxyPort by remember{mutableStateOf("")} - var proxyAddress by remember{mutableStateOf("")} - var proxyPort by remember{mutableStateOf("")} - var mmsc by remember{mutableStateOf("")} - var mtuV4 by remember{mutableStateOf("")} - var mtuV6 by remember{mutableStateOf("")} - var mvnoType by remember{mutableIntStateOf(-1)} - var networkTypeBitmask by remember{mutableStateOf("")} - var operatorNumeric by remember{mutableStateOf("")} - var password by remember{mutableStateOf("")} - var persistent by remember{mutableStateOf(false)} - var protocol by remember{mutableIntStateOf(-1)} - var roamingProtocol by remember{mutableIntStateOf(-1)} - var id by remember{mutableIntStateOf(0)} + var carrierEnabled by remember { mutableStateOf(false) } + var inputApnName by remember { mutableStateOf("") } + var user by remember { mutableStateOf("") } + var profileId by remember { mutableStateOf("") } + var selectedAuthType by remember { mutableIntStateOf(AUTH_TYPE_NONE) } + var carrierId by remember { mutableStateOf("$UNKNOWN_CARRIER_ID") } + var apnTypeBitmask by remember { mutableStateOf("") } + var entryName by remember { mutableStateOf("") } + var mmsProxyAddress by remember { mutableStateOf("") } + var mmsProxyPort by remember { mutableStateOf("") } + var proxyAddress by remember { mutableStateOf("") } + var proxyPort by remember { mutableStateOf("") } + var mmsc by remember { mutableStateOf("") } + var mtuV4 by remember { mutableStateOf("") } + var mtuV6 by remember { mutableStateOf("") } + var mvnoType by remember { mutableIntStateOf(-1) } + var networkTypeBitmask by remember { mutableStateOf("") } + var operatorNumeric by remember { mutableStateOf("") } + var password by remember { mutableStateOf("") } + var persistent by remember { mutableStateOf(false) } + var protocol by remember { mutableIntStateOf(-1) } + var roamingProtocol by remember { mutableIntStateOf(-1) } + var id by remember { mutableIntStateOf(0) } - if(inputNum!="0"){ + if(inputNum!="0") { val current = setting[inputNum.toInt()-1] id = current.id carrierEnabled = current.isEnabled inputApnName = current.apnName user = current.user - if(VERSION.SDK_INT>=33){profileId = current.profileId.toString()} + if(VERSION.SDK_INT>=33) {profileId = current.profileId.toString() } selectedAuthType = current.authType apnTypeBitmask = current.apnTypeBitmask.toString() entryName = current.entryName - if(VERSION.SDK_INT>=29){mmsProxyAddress = current.mmsProxyAddressAsString} + if(VERSION.SDK_INT>=29) {mmsProxyAddress = current.mmsProxyAddressAsString} mmsProxyPort = current.mmsProxyPort.toString() - if(VERSION.SDK_INT>=29){proxyAddress = current.proxyAddressAsString} + if(VERSION.SDK_INT>=29) {proxyAddress = current.proxyAddressAsString} proxyPort = current.proxyPort.toString() mmsc = current.mmsc.toString() - if(VERSION.SDK_INT>=33){ mtuV4 = current.mtuV4.toString(); mtuV6 = current.mtuV6.toString() } + if(VERSION.SDK_INT>=33) { mtuV4 = current.mtuV4.toString(); mtuV6 = current.mtuV6.toString() } mvnoType = current.mvnoType networkTypeBitmask = current.networkTypeBitmask.toString() operatorNumeric = current.operatorNumeric password = current.password - if(VERSION.SDK_INT>=33){persistent = current.isPersistent} + if(VERSION.SDK_INT>=33) {persistent = current.isPersistent} protocol = current.protocol roamingProtocol = current.roamingProtocol } @@ -529,55 +547,59 @@ private fun APN(){ Text(text = "APN", style = typography.titleLarge) TextField( value = inputApnName, - onValueChange = {inputApnName=it}, - label = {Text(stringResource(R.string.name))}, + onValueChange = {inputApnName=it }, + label = { Text(stringResource(R.string.name)) }, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) ) - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically){ + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { Text(text = stringResource(R.string.enable), style = typography.titleLarge) - Switch(checked = carrierEnabled, onCheckedChange = {carrierEnabled=it}) + Switch(checked = carrierEnabled, onCheckedChange = {carrierEnabled=it }) } Text(text = stringResource(R.string.user_name), style = typography.titleLarge) TextField( value = user, - onValueChange = {user=it}, - label = {Text(stringResource(R.string.user_name))}, + onValueChange = { user=it }, + label = { Text(stringResource(R.string.user_name)) }, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) ) - if(VERSION.SDK_INT>=33){ + if(VERSION.SDK_INT>=33) { Text(text = stringResource(R.string.profile_id), style = typography.titleLarge) TextField( value = profileId, - onValueChange = {profileId=it}, - label = {Text("ID")}, + onValueChange = { profileId=it }, + label = { Text("ID") }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) ) } Text(text = stringResource(R.string.auth_type), style = typography.titleLarge) - RadioButtonItem("无",{selectedAuthType==AUTH_TYPE_NONE},{selectedAuthType=AUTH_TYPE_NONE}) - RadioButtonItem("CHAP",{selectedAuthType==AUTH_TYPE_CHAP},{selectedAuthType=AUTH_TYPE_CHAP}) - RadioButtonItem("PAP",{selectedAuthType==AUTH_TYPE_PAP},{selectedAuthType=AUTH_TYPE_PAP}) - RadioButtonItem("PAP/CHAP",{selectedAuthType==AUTH_TYPE_PAP_OR_CHAP},{selectedAuthType=AUTH_TYPE_PAP_OR_CHAP}) + RadioButtonItem(stringResource(R.string.none), { selectedAuthType==AUTH_TYPE_NONE }, { selectedAuthType=AUTH_TYPE_NONE }) + RadioButtonItem("CHAP", { selectedAuthType==AUTH_TYPE_CHAP }, { selectedAuthType=AUTH_TYPE_CHAP }) + RadioButtonItem("PAP", { selectedAuthType==AUTH_TYPE_PAP}, { selectedAuthType=AUTH_TYPE_PAP }) + RadioButtonItem("PAP/CHAP", { selectedAuthType==AUTH_TYPE_PAP_OR_CHAP}, { selectedAuthType=AUTH_TYPE_PAP_OR_CHAP }) - if(VERSION.SDK_INT>=29){ + if(VERSION.SDK_INT>=29) { val ts = context.getSystemService(ComponentActivity.TELEPHONY_SERVICE) as TelephonyManager carrierId = ts.simCarrierId.toString() Text(text = "CarrierID", style = typography.titleLarge) TextField( value = carrierId, - onValueChange = {carrierId=it}, - label = {Text("ID")}, + onValueChange = { carrierId=it }, + label = { Text("ID") }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) ) } @@ -585,216 +607,219 @@ private fun APN(){ Text(text = stringResource(R.string.apn_type), style = typography.titleLarge) TextField( value = apnTypeBitmask, - onValueChange = {apnTypeBitmask=it}, - label = {Text(stringResource(R.string.bitmask))}, + onValueChange = { apnTypeBitmask=it }, + label = { Text(stringResource(R.string.bitmask)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) ) Text(text = stringResource(R.string.description), style = typography.titleLarge) TextField( value = entryName, - onValueChange = {entryName=it}, - label = {Text(stringResource(R.string.description))}, + onValueChange = {entryName=it }, + label = { Text(stringResource(R.string.description)) }, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) ) Text(text = stringResource(R.string.mms_proxy), style = typography.titleLarge) - if(VERSION.SDK_INT>=29){ + if(VERSION.SDK_INT>=29) { TextField( value = mmsProxyAddress, - onValueChange = {mmsProxyAddress=it}, - label = {Text(stringResource(R.string.address))}, + onValueChange = { mmsProxyAddress=it }, + label = { Text(stringResource(R.string.address)) }, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) ) } TextField( value = mmsProxyPort, - onValueChange = {mmsProxyPort=it}, - label = {Text(stringResource(R.string.port))}, + onValueChange = { mmsProxyPort=it }, + label = { Text(stringResource(R.string.port)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) ) Text(text = stringResource(R.string.proxy), style = typography.titleLarge) - if(VERSION.SDK_INT>=29){ + if(VERSION.SDK_INT>=29) { TextField( value = proxyAddress, - onValueChange = {proxyAddress=it}, - label = {Text(stringResource(R.string.address))}, + onValueChange = { proxyAddress=it }, + label = { Text(stringResource(R.string.address)) }, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) ) } TextField( value = proxyPort, - onValueChange = {proxyPort=it}, - label = {Text(stringResource(R.string.port))}, + onValueChange = { proxyPort=it }, + label = { Text(stringResource(R.string.port)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) ) Text(text = "MMSC", style = typography.titleLarge) TextField( value = mmsc, - onValueChange = {mmsc=it}, - label = {Text("Uri")}, + onValueChange = { mmsc=it }, + label = { Text("Uri") }, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) ) - if(VERSION.SDK_INT>=33){ + if(VERSION.SDK_INT>=33) { Text(text = "MTU", style = typography.titleLarge) TextField( value = mtuV4, - onValueChange = {mtuV4=it}, - label = {Text("IPV4")}, + onValueChange = { mtuV4=it }, + label = { Text("IPV4") }, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) ) TextField( value = mtuV6, - onValueChange = {mtuV6=it}, - label = {Text("IPV6")}, + onValueChange = { mtuV6=it }, + label = { Text("IPV6") }, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) ) } Text(text = "MVNO", style = typography.titleLarge) - RadioButtonItem("SPN",{mvnoType==MVNO_TYPE_SPN},{mvnoType=MVNO_TYPE_SPN}) - RadioButtonItem("IMSI",{mvnoType==MVNO_TYPE_IMSI},{mvnoType=MVNO_TYPE_IMSI}) - RadioButtonItem("GID",{mvnoType==MVNO_TYPE_GID},{mvnoType=MVNO_TYPE_GID}) - RadioButtonItem("ICCID",{mvnoType==MVNO_TYPE_ICCID},{mvnoType=MVNO_TYPE_ICCID}) + RadioButtonItem("SPN", { mvnoType == MVNO_TYPE_SPN }, { mvnoType = MVNO_TYPE_SPN }) + RadioButtonItem("IMSI", { mvnoType == MVNO_TYPE_IMSI }, { mvnoType = MVNO_TYPE_IMSI }) + RadioButtonItem("GID", { mvnoType == MVNO_TYPE_GID }, { mvnoType = MVNO_TYPE_GID }) + RadioButtonItem("ICCID", { mvnoType == MVNO_TYPE_ICCID }, { mvnoType = MVNO_TYPE_ICCID }) Text(text = stringResource(R.string.network_type), style = typography.titleLarge) TextField( value = networkTypeBitmask, - onValueChange = {networkTypeBitmask=it}, - label = {Text(stringResource(R.string.bitmask))}, + onValueChange = { networkTypeBitmask=it }, + label = { Text(stringResource(R.string.bitmask)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) ) Text(text = "OperatorNumeric", style = typography.titleLarge) TextField( value = operatorNumeric, - onValueChange = {operatorNumeric=it}, - label = {Text("ID")}, + onValueChange = { operatorNumeric=it }, + label = { Text("ID") }, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) ) Text(text = stringResource(R.string.password), style = typography.titleLarge) TextField( value = password, - onValueChange = {password=it}, - label = {Text(stringResource(R.string.password))}, + onValueChange = { password=it }, + label = { Text(stringResource(R.string.password)) }, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth().padding(top = 2.dp, bottom = 4.dp) ) - if(VERSION.SDK_INT>=33){ - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically){ + if(VERSION.SDK_INT>=33) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { Text(text = stringResource(R.string.persistent), style = typography.titleLarge) - Switch(checked = persistent, onCheckedChange = {persistent=it}) + Switch(checked = persistent, onCheckedChange = { persistent=it }) } } Text(text = stringResource(R.string.protocol), style = typography.titleLarge) - RadioButtonItem("IPV4",{protocol==PROTOCOL_IP},{protocol=PROTOCOL_IP}) - RadioButtonItem("IPV6",{protocol==PROTOCOL_IPV6},{protocol=PROTOCOL_IPV6}) - RadioButtonItem("IPV4/IPV6",{protocol==PROTOCOL_IPV4V6},{protocol=PROTOCOL_IPV4V6}) - RadioButtonItem("PPP",{protocol==PROTOCOL_PPP},{protocol=PROTOCOL_PPP}) - if(VERSION.SDK_INT>=29){ - RadioButtonItem("non-IP",{protocol==PROTOCOL_NON_IP},{protocol=PROTOCOL_NON_IP}) - RadioButtonItem("Unstructured",{protocol==PROTOCOL_UNSTRUCTURED},{protocol=PROTOCOL_UNSTRUCTURED}) + RadioButtonItem("IPV4", { protocol == PROTOCOL_IP }, { protocol = PROTOCOL_IP }) + RadioButtonItem("IPV6", { protocol == PROTOCOL_IPV6 }, { protocol = PROTOCOL_IPV6 }) + RadioButtonItem("IPV4/IPV6", { protocol == PROTOCOL_IPV4V6 }, { protocol = PROTOCOL_IPV4V6 }) + RadioButtonItem("PPP", { protocol == PROTOCOL_PPP }, { protocol = PROTOCOL_PPP }) + if(VERSION.SDK_INT>=29) { + RadioButtonItem("non-IP", { protocol == PROTOCOL_NON_IP }, { protocol = PROTOCOL_NON_IP }) + RadioButtonItem("Unstructured", { protocol == PROTOCOL_UNSTRUCTURED }, { protocol = PROTOCOL_UNSTRUCTURED }) } Text(text = stringResource(R.string.roaming_protocol), style = typography.titleLarge) - RadioButtonItem("IPV4",{roamingProtocol==PROTOCOL_IP},{roamingProtocol=PROTOCOL_IP}) - RadioButtonItem("IPV6",{roamingProtocol==PROTOCOL_IPV6},{roamingProtocol=PROTOCOL_IPV6}) - RadioButtonItem("IPV4/IPV6",{roamingProtocol==PROTOCOL_IPV4V6},{roamingProtocol=PROTOCOL_IPV4V6}) - RadioButtonItem("PPP",{roamingProtocol==PROTOCOL_PPP},{roamingProtocol=PROTOCOL_PPP}) - if(VERSION.SDK_INT>=29){ - RadioButtonItem("non-IP",{roamingProtocol==PROTOCOL_NON_IP},{roamingProtocol=PROTOCOL_NON_IP}) - RadioButtonItem("Unstructured",{roamingProtocol==PROTOCOL_UNSTRUCTURED},{roamingProtocol=PROTOCOL_UNSTRUCTURED}) + RadioButtonItem("IPV4", { roamingProtocol == PROTOCOL_IP }, { roamingProtocol = PROTOCOL_IP }) + RadioButtonItem("IPV6", { roamingProtocol == PROTOCOL_IPV6 }, { roamingProtocol = PROTOCOL_IPV6 }) + RadioButtonItem("IPV4/IPV6", { roamingProtocol == PROTOCOL_IPV4V6 }, { roamingProtocol = PROTOCOL_IPV4V6 }) + RadioButtonItem("PPP", { roamingProtocol == PROTOCOL_PPP }, { roamingProtocol = PROTOCOL_PPP}) + if(VERSION.SDK_INT>=29) { + RadioButtonItem("non-IP", { roamingProtocol == PROTOCOL_NON_IP }, { roamingProtocol = PROTOCOL_NON_IP }) + RadioButtonItem("Unstructured", { roamingProtocol == PROTOCOL_UNSTRUCTURED }, { roamingProtocol = PROTOCOL_UNSTRUCTURED }) } - var finalStep by remember{mutableStateOf(false)} + var finalStep by remember { mutableStateOf(false) } Button( onClick = { - if(!finalStep){ + if(!finalStep) { builder.setCarrierEnabled(carrierEnabled) builder.setApnName(inputApnName) builder.setUser(user) - if(VERSION.SDK_INT>=33){builder.setProfileId(profileId.toInt())} + if(VERSION.SDK_INT>=33) { builder.setProfileId(profileId.toInt()) } builder.setAuthType(selectedAuthType) - if(VERSION.SDK_INT>=29){builder.setCarrierId(carrierId.toInt())} + if(VERSION.SDK_INT>=29) { builder.setCarrierId(carrierId.toInt()) } builder.setApnTypeBitmask(apnTypeBitmask.toInt()) builder.setEntryName(entryName) - if(VERSION.SDK_INT>=29){builder.setMmsProxyAddress(mmsProxyAddress)} + if(VERSION.SDK_INT>=29) { builder.setMmsProxyAddress(mmsProxyAddress) } builder.setMmsProxyPort(mmsProxyPort.toInt()) - if(VERSION.SDK_INT>=29){builder.setProxyAddress(proxyAddress)} + if(VERSION.SDK_INT>=29) { builder.setProxyAddress(proxyAddress) } builder.setProxyPort(proxyPort.toInt()) builder.setMmsc(mmsc.toUri()) - if(VERSION.SDK_INT>=33){ builder.setMtuV4(mtuV4.toInt()); builder.setMtuV6(mtuV6.toInt()) } + if(VERSION.SDK_INT>=33) { builder.setMtuV4(mtuV4.toInt()); builder.setMtuV6(mtuV6.toInt()) } builder.setMvnoType(mvnoType) builder.setNetworkTypeBitmask(networkTypeBitmask.toInt()) builder.setOperatorNumeric(operatorNumeric) builder.setPassword(password) - if(VERSION.SDK_INT>=33){builder.setPersistent(persistent)} + if(VERSION.SDK_INT>=33) { builder.setPersistent(persistent) } builder.setProtocol(protocol) builder.setRoamingProtocol(roamingProtocol) result = builder.build() } - finalStep=!finalStep }, modifier = Modifier.fillMaxWidth() ) { - Text(stringResource(if(finalStep){R.string.previous_step}else{R.string.next_step})) + Text(stringResource(if(finalStep) R.string.previous_step else R.string.next_step)) } AnimatedVisibility(finalStep) { - if(inputNum=="0"){ + if(inputNum=="0") { Button( - onClick = {dpm.addOverrideApn(receiver,result)}, + onClick = { dpm.addOverrideApn(receiver,result) }, modifier = Modifier.fillMaxWidth() ) { Text(stringResource(R.string.create)) } }else{ - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { Button( onClick = { val success = dpm.updateOverrideApn(receiver,id,result) - Toast.makeText(context, if(success){R.string.success}else{R.string.fail}, Toast.LENGTH_SHORT).show() + Toast.makeText(context, if(success) R.string.success else R.string.fail, Toast.LENGTH_SHORT).show() }, Modifier.fillMaxWidth(0.49F) - ){ + ) { Text(stringResource(R.string.update)) } Button( onClick = { val success = dpm.removeOverrideApn(receiver,id) - Toast.makeText(context, if(success){R.string.success}else{R.string.fail}, Toast.LENGTH_SHORT).show() + Toast.makeText(context, if(success) R.string.success else R.string.fail, Toast.LENGTH_SHORT).show() }, Modifier.fillMaxWidth(0.96F) - ){ + ) { Text(stringResource(R.string.remove)) } } 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 fe45c64..8e453c0 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/Password.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/Password.kt @@ -38,31 +38,14 @@ import com.bintianqi.owndroid.Receiver import com.bintianqi.owndroid.ui.* @Composable -fun Password(navCtrl: NavHostController){ +fun Password(navCtrl: NavHostController) { val localNavCtrl = rememberNavController() val backStackEntry by localNavCtrl.currentBackStackEntryAsState() val scrollState = rememberScrollState() - /*val titleMap = mapOf( - "ResetPasswordToken" to R.string.reset_password_token, - "PasswordInfo" to R.string.password_info, - "ResetPassword" to R.string.reset_password, - "RequirePasswordComplexity" to R.string.required_password_complexity, - "KeyguardDisabledFeatures" to R.string.keyguard_disabled_features, - "MaxTimeToLock" to R.string.max_time_to_lock, - "PasswordTimeout" to R.string.pwd_timeout, - "MaxPasswordFail" to R.string.max_pwd_fail, - "PasswordHistoryLength" to R.string.pwd_history, - "RequirePasswordQuality" to R.string.required_password_quality, - )*/ Scaffold( topBar = { - /*TopAppBar( - title = {Text(text = stringResource(titleMap[backStackEntry?.destination?.route]?:R.string.password_and_keyguard))}, - navigationIcon = {NavIcon{if(backStackEntry?.destination?.route=="Home"){navCtrl.navigateUp()}else{localNavCtrl.navigateUp()}}}, - colors = TopAppBarDefaults.topAppBarColors(containerColor = colorScheme.surfaceVariant) - )*/ - TopBar(backStackEntry,navCtrl,localNavCtrl){ - if(backStackEntry?.destination?.route=="Home"&&scrollState.maxValue>80){ + TopBar(backStackEntry,navCtrl,localNavCtrl) { + if(backStackEntry?.destination?.route == "Home" && scrollState.maxValue > 80) { Text( text = stringResource(R.string.password_and_keyguard), modifier = Modifier.alpha((maxOf(scrollState.value-30,0)).toFloat()/80) @@ -70,7 +53,7 @@ fun Password(navCtrl: NavHostController){ } } } - ){ + ) { NavHost( navController = localNavCtrl, startDestination = "Home", enterTransition = Animations.navHostEnterTransition, @@ -78,54 +61,58 @@ fun Password(navCtrl: NavHostController){ popEnterTransition = Animations.navHostPopEnterTransition, popExitTransition = Animations.navHostPopExitTransition, modifier = Modifier.padding(top = it.calculateTopPadding()) - ){ - composable(route = "Home"){Home(localNavCtrl,scrollState)} - composable(route = "PasswordInfo"){PasswordInfo()} - composable(route = "ResetPasswordToken"){ResetPasswordToken()} - composable(route = "ResetPassword"){ResetPassword()} - composable(route = "RequirePasswordComplexity"){PasswordComplexity()} - composable(route = "KeyguardDisabledFeatures"){KeyguardDisabledFeatures()} - composable(route = "MaxTimeToLock"){ScreenTimeout()} - composable(route = "PasswordTimeout"){PasswordExpiration()} - composable(route = "MaxPasswordFail"){MaxFailedPasswordForWipe()} - composable(route = "PasswordHistoryLength"){PasswordHistoryLength()} - composable(route = "RequirePasswordQuality"){PasswordQuality()} + ) { + composable(route = "Home") { Home(localNavCtrl,scrollState) } + composable(route = "PasswordInfo") { PasswordInfo() } + composable(route = "ResetPasswordToken") { ResetPasswordToken() } + composable(route = "ResetPassword") { ResetPassword() } + composable(route = "RequirePasswordComplexity") { PasswordComplexity() } + composable(route = "KeyguardDisabledFeatures") { KeyguardDisabledFeatures() } + composable(route = "MaxTimeToLock") { ScreenTimeout() } + composable(route = "PasswordTimeout") { PasswordExpiration() } + composable(route = "MaxPasswordFail") { MaxFailedPasswordForWipe() } + composable(route = "PasswordHistoryLength") { PasswordHistoryLength() } + composable(route = "RequirePasswordQuality") { PasswordQuality() } } } } @Composable -private fun Home(navCtrl:NavHostController,scrollState: ScrollState){ - Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)){ - Text(text = stringResource(R.string.password_and_keyguard), style = typography.headlineLarge, 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){ - SubPageItem(R.string.reset_password_token,"",R.drawable.key_vertical_fill0){navCtrl.navigate("ResetPasswordToken")} +private fun Home(navCtrl:NavHostController,scrollState: ScrollState) { + Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)) { + Text( + text = stringResource(R.string.password_and_keyguard), + style = typography.headlineLarge, + 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) { + SubPageItem(R.string.reset_password_token, "", R.drawable.key_vertical_fill0) { navCtrl.navigate("ResetPasswordToken") } } - SubPageItem(R.string.reset_password,"",R.drawable.lock_reset_fill0){navCtrl.navigate("ResetPassword")} - if(VERSION.SDK_INT>=31){ - SubPageItem(R.string.required_password_complexity,"",R.drawable.password_fill0){navCtrl.navigate("RequirePasswordComplexity")} + SubPageItem(R.string.reset_password, "", R.drawable.lock_reset_fill0) { navCtrl.navigate("ResetPassword") } + if(VERSION.SDK_INT >= 31) { + SubPageItem(R.string.required_password_complexity, "", R.drawable.password_fill0) { navCtrl.navigate("RequirePasswordComplexity") } } - SubPageItem(R.string.keyguard_disabled_features,"",R.drawable.screen_lock_portrait_fill0){navCtrl.navigate("KeyguardDisabledFeatures")} - SubPageItem(R.string.max_time_to_lock,"",R.drawable.schedule_fill0){navCtrl.navigate("MaxTimeToLock")} - SubPageItem(R.string.pwd_timeout,"",R.drawable.lock_clock_fill0){navCtrl.navigate("PasswordTimeout")} - SubPageItem(R.string.max_pwd_fail,"",R.drawable.no_encryption_fill0){navCtrl.navigate("MaxPasswordFail")} - SubPageItem(R.string.pwd_history,"",R.drawable.history_fill0){navCtrl.navigate("PasswordHistoryLength")} - SubPageItem(R.string.required_password_quality,"",R.drawable.password_fill0){navCtrl.navigate("RequirePasswordQuality")} + SubPageItem(R.string.keyguard_disabled_features, "", R.drawable.screen_lock_portrait_fill0) { navCtrl.navigate("KeyguardDisabledFeatures") } + SubPageItem(R.string.max_time_to_lock, "", R.drawable.schedule_fill0) { navCtrl.navigate("MaxTimeToLock") } + SubPageItem(R.string.pwd_timeout, "", R.drawable.lock_clock_fill0) { navCtrl.navigate("PasswordTimeout") } + SubPageItem(R.string.max_pwd_fail, "", R.drawable.no_encryption_fill0) { navCtrl.navigate("MaxPasswordFail") } + SubPageItem(R.string.pwd_history, "", R.drawable.history_fill0) { navCtrl.navigate("PasswordHistoryLength") } + SubPageItem(R.string.required_password_quality, "", R.drawable.password_fill0) { navCtrl.navigate("RequirePasswordQuality") } Spacer(Modifier.padding(vertical = 30.dp)) } } @Composable -private fun PasswordInfo(){ +private fun PasswordInfo() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val receiver = ComponentName(context, Receiver::class.java) - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + 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) Spacer(Modifier.padding(vertical = 5.dp)) - if(VERSION.SDK_INT>=29){ + if(VERSION.SDK_INT >= 29) { val passwordComplexity = mapOf( PASSWORD_COMPLEXITY_NONE to stringResource(R.string.password_complexity_none), PASSWORD_COMPLEXITY_LOW to stringResource(R.string.password_complexity_low), @@ -135,14 +122,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(isDeviceOwner(dpm) || isProfileOwner(dpm)) { Text(stringResource(R.string.is_password_sufficient, dpm.isActivePasswordSufficient)) } - if(dpm.isAdminActive(receiver)){ + 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 && isProfileOwner(dpm) && dpm.isManagedProfile(receiver)) { val unifiedPwd = dpm.isUsingUnifiedPassword(receiver) Text(stringResource(R.string.is_using_unified_password, unifiedPwd)) } @@ -151,48 +138,51 @@ private fun PasswordInfo(){ @SuppressLint("NewApi") @Composable -private fun ResetPasswordToken(){ +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 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())){ + 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)) Text(text = stringResource(R.string.reset_password_token), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) Button( onClick = { - if(dpm.clearResetPasswordToken(receiver)){ Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() - }else{ Toast.makeText(context, R.string.fail, Toast.LENGTH_SHORT).show() } + Toast.makeText( + context, + if(dpm.clearResetPasswordToken(receiver)) R.string.success else R.string.fail, + Toast.LENGTH_SHORT + ).show() }, modifier = Modifier.fillMaxWidth(), - enabled = isDeviceOwner(dpm)||isProfileOwner(dpm) + enabled = isDeviceOwner(dpm) || isProfileOwner(dpm) ) { Text(stringResource(R.string.clear)) } Button( onClick = { try { - if(dpm.setResetPasswordToken(receiver, tokenByteArray)){ - Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() - }else{ - Toast.makeText(context, R.string.fail, Toast.LENGTH_SHORT).show() - } - }catch(e:SecurityException){ + Toast.makeText( + context, + if(dpm.setResetPasswordToken(receiver, tokenByteArray)) R.string.success else R.string.fail, + Toast.LENGTH_SHORT + ).show() + }catch(e:SecurityException) { Toast.makeText(context, R.string.security_exception, Toast.LENGTH_SHORT).show() } }, - enabled = isDeviceOwner(dpm)||isProfileOwner(dpm), + enabled = isDeviceOwner(dpm) || isProfileOwner(dpm), modifier = Modifier.fillMaxWidth() ) { Text(stringResource(R.string.set)) } Button( onClick = { - if(!dpm.isResetPasswordTokenActive(receiver)){ - try{ activateToken(context) } - catch(e:NullPointerException){ Toast.makeText(context, R.string.please_set_a_token, Toast.LENGTH_SHORT).show() } - }else{ Toast.makeText(context, R.string.token_already_activated, Toast.LENGTH_SHORT).show() } + if(!dpm.isResetPasswordTokenActive(receiver)) { + try { activateToken(context) } + catch(e:NullPointerException) { Toast.makeText(context, R.string.please_set_a_token, Toast.LENGTH_SHORT).show() } + } else { Toast.makeText(context, R.string.token_already_activated, Toast.LENGTH_SHORT).show() } }, enabled = isDeviceOwner(dpm)||isProfileOwner(dpm), modifier = Modifier.fillMaxWidth() @@ -200,70 +190,75 @@ private fun ResetPasswordToken(){ Text(stringResource(R.string.activate)) } Spacer(Modifier.padding(vertical = 5.dp)) - Information{Text(stringResource(R.string.activate_token_not_required_when_no_password))} + Information{ Text(stringResource(R.string.activate_token_not_required_when_no_password)) } } } @Composable -private fun ResetPassword(){ +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 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)) } - var confirmed by remember{ mutableStateOf(false) } - var resetPwdFlag by remember{ mutableIntStateOf(0) } - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + 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)) } + var confirmed by remember { mutableStateOf(false) } + var resetPwdFlag by remember { mutableIntStateOf(0) } + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.reset_password),style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) OutlinedTextField( value = newPwd, - onValueChange = {newPwd=it}, - enabled = !confirmed&&(isDeviceOwner(dpm)||isProfileOwner(dpm)||dpm.isAdminActive(receiver)), - label = { Text(stringResource(R.string.password))}, + onValueChange = { newPwd=it }, + enabled = !confirmed && (isDeviceOwner(dpm) || isProfileOwner(dpm) || dpm.isAdminActive(receiver)), + label = { Text(stringResource(R.string.password)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password, imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth() ) Spacer(Modifier.padding(vertical = 3.dp)) Text(text = stringResource(R.string.reset_pwd_desc)) Spacer(Modifier.padding(vertical = 5.dp)) - if(VERSION.SDK_INT>=23){ + if(VERSION.SDK_INT >= 23) { RadioButtonItem( stringResource(R.string.do_not_ask_credentials_on_boot), - {resetPwdFlag==RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT}, {resetPwdFlag=RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT} + { resetPwdFlag == RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT }, + { resetPwdFlag = RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT } ) } - RadioButtonItem(stringResource(R.string.reset_password_require_entry),{resetPwdFlag==RESET_PASSWORD_REQUIRE_ENTRY}, {resetPwdFlag=RESET_PASSWORD_REQUIRE_ENTRY}) - RadioButtonItem(stringResource(R.string.none),{resetPwdFlag==0},{resetPwdFlag=0}) + RadioButtonItem( + stringResource(R.string.reset_password_require_entry), + { resetPwdFlag==RESET_PASSWORD_REQUIRE_ENTRY }, + { resetPwdFlag=RESET_PASSWORD_REQUIRE_ENTRY } + ) + RadioButtonItem(stringResource(R.string.none), { resetPwdFlag==0 }, { resetPwdFlag=0 }) Spacer(Modifier.padding(vertical = 5.dp)) Button( onClick = { - if(newPwd.length>=4||newPwd.isEmpty()){ confirmed=!confirmed - }else{ Toast.makeText(context, R.string.require_4_digit_password, Toast.LENGTH_SHORT).show() } + if(newPwd.length>=4 || newPwd.isEmpty()) { confirmed=!confirmed } + else { Toast.makeText(context, R.string.require_4_digit_password, Toast.LENGTH_SHORT).show() } }, enabled = isDeviceOwner(dpm) || isProfileOwner(dpm) || dpm.isAdminActive(receiver), modifier = Modifier.fillMaxWidth(), colors = ButtonDefaults.buttonColors( - containerColor = if(confirmed){ colorScheme.primary }else{ colorScheme.error }, - contentColor = if(confirmed){ colorScheme.onPrimary }else{ colorScheme.onError } + containerColor = if(confirmed) colorScheme.primary else colorScheme.error, + contentColor = if(confirmed) colorScheme.onPrimary else colorScheme.onError ) ) { - Text(text = stringResource(if(confirmed){R.string.cancel}else{R.string.confirm})) + Text(text = stringResource(if(confirmed) R.string.cancel else R.string.confirm)) } Spacer(Modifier.padding(vertical = 3.dp)) - if(VERSION.SDK_INT>=26){ + if(VERSION.SDK_INT >= 26) { Button( onClick = { val resetSuccess = dpm.resetPasswordWithToken(receiver,newPwd,tokenByteArray,resetPwdFlag) - if(resetSuccess){ Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show();newPwd=""} + if(resetSuccess) { Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show(); newPwd=""} else{ Toast.makeText(context, R.string.fail, Toast.LENGTH_SHORT).show() } confirmed=false }, colors = ButtonDefaults.buttonColors(containerColor = colorScheme.error, contentColor = colorScheme.onError), - enabled = confirmed&&(isDeviceOwner(dpm)||isProfileOwner(dpm)), + enabled = confirmed && (isDeviceOwner(dpm) || isProfileOwner(dpm)), modifier = Modifier.fillMaxWidth() ) { Text(stringResource(R.string.reset_password_with_token)) @@ -272,7 +267,7 @@ private fun ResetPassword(){ Button( onClick = { val resetSuccess = dpm.resetPassword(newPwd,resetPwdFlag) - if(resetSuccess){ Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show(); newPwd=""} + if(resetSuccess) { Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show(); newPwd="" } else{ Toast.makeText(context, R.string.fail, Toast.LENGTH_SHORT).show() } confirmed=false }, @@ -288,7 +283,7 @@ private fun ResetPassword(){ @SuppressLint("NewApi") @Composable -private fun PasswordComplexity(){ +private fun PasswordComplexity() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val passwordComplexity = mapOf( @@ -297,18 +292,34 @@ private fun PasswordComplexity(){ PASSWORD_COMPLEXITY_MEDIUM to stringResource(R.string.password_complexity_medium), PASSWORD_COMPLEXITY_HIGH to stringResource(R.string.password_complexity_high) ).toList() - var selectedItem by remember{ mutableIntStateOf(passwordComplexity[0].first) } - if(isDeviceOwner(dpm) || isProfileOwner(dpm)){ + var selectedItem by remember { mutableIntStateOf(passwordComplexity[0].first) } + if(isDeviceOwner(dpm) || isProfileOwner(dpm)) { selectedItem=dpm.requiredPasswordComplexity } - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.required_password_complexity), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) - RadioButtonItem(passwordComplexity[0].second,{selectedItem==passwordComplexity[0].first},{selectedItem=passwordComplexity[0].first}) - RadioButtonItem(passwordComplexity[1].second,{selectedItem==passwordComplexity[1].first},{selectedItem=passwordComplexity[1].first}) - RadioButtonItem(passwordComplexity[2].second,{selectedItem==passwordComplexity[2].first},{selectedItem=passwordComplexity[2].first}) - RadioButtonItem(passwordComplexity[3].second,{selectedItem==passwordComplexity[3].first},{selectedItem=passwordComplexity[3].first}) + RadioButtonItem( + passwordComplexity[0].second, + { selectedItem == passwordComplexity[0].first }, + { selectedItem = passwordComplexity[0].first } + ) + RadioButtonItem( + passwordComplexity[1].second, + { selectedItem == passwordComplexity[1].first }, + { selectedItem = passwordComplexity[1].first } + ) + RadioButtonItem( + passwordComplexity[2].second, + { selectedItem == passwordComplexity[2].first }, + { selectedItem = passwordComplexity[2].first } + ) + RadioButtonItem( + passwordComplexity[3].second, + { selectedItem == passwordComplexity[3].first }, + { selectedItem = passwordComplexity[3].first } + ) Spacer(Modifier.padding(vertical = 5.dp)) Button( @@ -316,16 +327,16 @@ private fun PasswordComplexity(){ dpm.requiredPasswordComplexity = selectedItem Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() }, - enabled = isDeviceOwner(dpm)|| isProfileOwner(dpm), + enabled = isDeviceOwner(dpm) || isProfileOwner(dpm), modifier = Modifier.fillMaxWidth() ) { Text(text = stringResource(R.string.apply)) } Spacer(Modifier.padding(vertical = 5.dp)) Button( - onClick = {context.startActivity(Intent(ACTION_SET_NEW_PASSWORD))}, + onClick = { context.startActivity(Intent(ACTION_SET_NEW_PASSWORD)) }, modifier = Modifier.fillMaxWidth() - ){ + ) { Text(stringResource(R.string.require_set_new_password)) } Spacer(Modifier.padding(vertical = 30.dp)) @@ -333,14 +344,14 @@ private fun PasswordComplexity(){ } @Composable -private fun ScreenTimeout(){ +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 focusMgr = LocalFocusManager.current - var inputContent by remember{ mutableStateOf(if(isDeviceOwner(dpm)){dpm.getMaximumTimeToLock(receiver).toString()}else{""}) } - var ableToApply by remember{ mutableStateOf(inputContent!="") } - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + var inputContent by remember { mutableStateOf(if(isDeviceOwner(dpm)) dpm.getMaximumTimeToLock(receiver).toString() else "") } + var ableToApply by remember { mutableStateOf(inputContent!="") } + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.max_time_to_lock), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) @@ -348,35 +359,35 @@ private fun ScreenTimeout(){ Spacer(Modifier.padding(vertical = 5.dp)) OutlinedTextField( value = inputContent, - label = { Text(stringResource(R.string.time_unit_ms))}, + label = { Text(stringResource(R.string.time_unit_ms)) }, onValueChange = { inputContent = it - ableToApply = inputContent!="" + ableToApply = inputContent != "" }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), enabled = isDeviceOwner(dpm), modifier = Modifier.focusable().fillMaxWidth() ) Spacer(Modifier.padding(vertical = 5.dp)) Button( - onClick = {focusMgr.clearFocus() ; dpm.setMaximumTimeToLock(receiver,inputContent.toLong())}, + onClick = { focusMgr.clearFocus(); dpm.setMaximumTimeToLock(receiver,inputContent.toLong()) }, modifier = Modifier.fillMaxWidth() - ){ + ) { Text(stringResource(R.string.apply)) } } } @Composable -private fun MaxFailedPasswordForWipe(){ +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 focusMgr = LocalFocusManager.current - var inputContent by remember{ mutableStateOf(if(isDeviceOwner(dpm)){dpm.getMaximumFailedPasswordsForWipe(receiver).toString()}else{""}) } - var ableToApply by remember{ mutableStateOf(inputContent!=""&&inputContent!="0") } - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + var inputContent by remember { mutableStateOf(if(isDeviceOwner(dpm)) dpm.getMaximumFailedPasswordsForWipe(receiver).toString() else "") } + var ableToApply by remember { mutableStateOf(inputContent != "" && inputContent != "0") } + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.max_pwd_fail), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) @@ -384,35 +395,35 @@ private fun MaxFailedPasswordForWipe(){ Spacer(Modifier.padding(vertical = 5.dp)) OutlinedTextField( value = inputContent, - label = { Text(stringResource(R.string.max_pwd_fail_textfield))}, + label = { Text(stringResource(R.string.max_pwd_fail_textfield)) }, onValueChange = { inputContent = it - ableToApply = inputContent!=""&&inputContent!="0" + ableToApply = inputContent != "" && inputContent != "0" }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), enabled = isDeviceOwner(dpm), modifier = Modifier.focusable().fillMaxWidth() ) Spacer(Modifier.padding(vertical = 5.dp)) Button( - onClick = {focusMgr.clearFocus() ; dpm.setMaximumFailedPasswordsForWipe(receiver,inputContent.toInt())}, + onClick = { focusMgr.clearFocus(); dpm.setMaximumFailedPasswordsForWipe(receiver,inputContent.toInt()) }, modifier = Modifier.fillMaxWidth() - ){ + ) { Text(stringResource(R.string.apply)) } } } @Composable -private fun PasswordExpiration(){ +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 focusMgr = LocalFocusManager.current - var inputContent by remember{ mutableStateOf(if(isDeviceOwner(dpm)){dpm.getPasswordExpirationTimeout(receiver).toString()}else{""}) } - var ableToApply by remember{ mutableStateOf(inputContent!="") } - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + var inputContent by remember { mutableStateOf(if(isDeviceOwner(dpm)) dpm.getPasswordExpirationTimeout(receiver).toString() else "") } + var ableToApply by remember { mutableStateOf(inputContent != "") } + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.pwd_timeout), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) @@ -420,35 +431,35 @@ private fun PasswordExpiration(){ Spacer(Modifier.padding(vertical = 5.dp)) OutlinedTextField( value = inputContent, - label = { Text(stringResource(R.string.time_unit_ms))}, + label = { Text(stringResource(R.string.time_unit_ms)) }, onValueChange = { inputContent = it - ableToApply = inputContent!="" + ableToApply = inputContent != "" }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), enabled = isDeviceOwner(dpm), modifier = Modifier.focusable().fillMaxWidth() ) Spacer(Modifier.padding(vertical = 5.dp)) Button( - onClick = {focusMgr.clearFocus() ; dpm.setPasswordExpirationTimeout(receiver,inputContent.toLong())}, + onClick = { focusMgr.clearFocus() ; dpm.setPasswordExpirationTimeout(receiver,inputContent.toLong()) }, modifier = Modifier.fillMaxWidth() - ){ + ) { Text(stringResource(R.string.apply)) } } } @Composable -private fun PasswordHistoryLength(){ +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 focusMgr = LocalFocusManager.current - var inputContent by remember{ mutableStateOf(if(isDeviceOwner(dpm)){dpm.getPasswordHistoryLength(receiver).toString()}else{""}) } - var ableToApply by remember{ mutableStateOf(inputContent!="") } - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + var inputContent by remember { mutableStateOf(if(isDeviceOwner(dpm)) dpm.getPasswordHistoryLength(receiver).toString() else "") } + var ableToApply by remember { mutableStateOf(inputContent!="") } + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.pwd_history), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) @@ -456,116 +467,116 @@ private fun PasswordHistoryLength(){ Spacer(Modifier.padding(vertical = 5.dp)) OutlinedTextField( value = inputContent, - label = { Text(stringResource(R.string.length))}, + label = { Text(stringResource(R.string.length)) }, onValueChange = { inputContent = it - ableToApply = inputContent!="" + ableToApply = inputContent != "" }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), enabled = isDeviceOwner(dpm), modifier = Modifier.focusable().fillMaxWidth() ) Spacer(Modifier.padding(vertical = 5.dp)) Button( - onClick = {focusMgr.clearFocus() ; dpm.setPasswordHistoryLength(receiver,inputContent.toInt())}, + onClick = { focusMgr.clearFocus() ; dpm.setPasswordHistoryLength(receiver,inputContent.toInt()) }, modifier = Modifier.fillMaxWidth() - ){ + ) { Text(stringResource(R.string.apply)) } } } @Composable -private fun KeyguardDisabledFeatures(){ +private fun KeyguardDisabledFeatures() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val receiver = ComponentName(context,Receiver::class.java) - var state by remember{mutableIntStateOf(-1)} - var shortcuts by remember{mutableStateOf(false)} - var biometrics by remember{mutableStateOf(false)} - var iris by remember{mutableStateOf(false)} - var face by remember{mutableStateOf(false)} - var remote by remember{mutableStateOf(false)} - var fingerprint by remember{mutableStateOf(false)} - var agents by remember{mutableStateOf(false)} - var unredacted by remember{mutableStateOf(false)} - var notification by remember{mutableStateOf(false)} - var camera by remember{mutableStateOf(false)} - var widgets by remember{mutableStateOf(false)} + var state by remember { mutableIntStateOf(-1) } + var shortcuts by remember { mutableStateOf(false) } + var biometrics by remember { mutableStateOf(false) } + var iris by remember { mutableStateOf(false) } + var face by remember { mutableStateOf(false) } + var remote by remember { mutableStateOf(false) } + var fingerprint by remember { mutableStateOf(false) } + var agents by remember { mutableStateOf(false) } + var unredacted by remember { mutableStateOf(false) } + var notification by remember { mutableStateOf(false) } + var camera by remember { mutableStateOf(false) } + var widgets by remember { mutableStateOf(false) } val calculateCustomFeature = { var calculate = dpm.getKeyguardDisabledFeatures(receiver) - if(calculate==0){state=0} + if(calculate==0) {state=0} else{ - if(calculate-KEYGUARD_DISABLE_SHORTCUTS_ALL>=0 && VERSION.SDK_INT>=34){shortcuts=true;calculate-= KEYGUARD_DISABLE_SHORTCUTS_ALL } - if(calculate-KEYGUARD_DISABLE_BIOMETRICS>=0&&VERSION.SDK_INT>=28){biometrics=true;calculate -= KEYGUARD_DISABLE_BIOMETRICS } - if(calculate-KEYGUARD_DISABLE_IRIS>=0&&VERSION.SDK_INT>=28){iris=true;calculate -= KEYGUARD_DISABLE_IRIS } - if(calculate-KEYGUARD_DISABLE_FACE>=0&&VERSION.SDK_INT>=28){face=true;calculate -= KEYGUARD_DISABLE_FACE } - if(calculate-KEYGUARD_DISABLE_REMOTE_INPUT>=0&&VERSION.SDK_INT>=24){remote=true;calculate -= KEYGUARD_DISABLE_REMOTE_INPUT } - if(calculate-KEYGUARD_DISABLE_FINGERPRINT>=0){fingerprint=true;calculate -= KEYGUARD_DISABLE_FINGERPRINT } - if(calculate-KEYGUARD_DISABLE_TRUST_AGENTS>=0){agents=true;calculate -= KEYGUARD_DISABLE_TRUST_AGENTS } - if(calculate-KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS>=0){unredacted=true;calculate -= KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS } - if(calculate-KEYGUARD_DISABLE_SECURE_NOTIFICATIONS>=0){notification=true;calculate -= KEYGUARD_DISABLE_SECURE_NOTIFICATIONS } - if(calculate-KEYGUARD_DISABLE_SECURE_CAMERA>=0){camera=true;calculate -= KEYGUARD_DISABLE_SECURE_CAMERA } - if(calculate-KEYGUARD_DISABLE_WIDGETS_ALL>=0){widgets=true;calculate -= KEYGUARD_DISABLE_WIDGETS_ALL } + if(calculate-KEYGUARD_DISABLE_SHORTCUTS_ALL >= 0 && VERSION.SDK_INT >= 34) { shortcuts=true; calculate-= KEYGUARD_DISABLE_SHORTCUTS_ALL } + if(calculate-KEYGUARD_DISABLE_BIOMETRICS >= 0 && VERSION.SDK_INT >= 28) { biometrics=true; calculate -= KEYGUARD_DISABLE_BIOMETRICS } + if(calculate-KEYGUARD_DISABLE_IRIS >= 0 && VERSION.SDK_INT >= 28) { iris=true; calculate -= KEYGUARD_DISABLE_IRIS } + if(calculate-KEYGUARD_DISABLE_FACE >= 0 && VERSION.SDK_INT >= 28) { face=true; calculate -= KEYGUARD_DISABLE_FACE } + if(calculate-KEYGUARD_DISABLE_REMOTE_INPUT >= 0 && VERSION.SDK_INT >= 24) { remote=true; calculate -= KEYGUARD_DISABLE_REMOTE_INPUT } + if(calculate-KEYGUARD_DISABLE_FINGERPRINT >= 0) { fingerprint=true; calculate -= KEYGUARD_DISABLE_FINGERPRINT } + if(calculate-KEYGUARD_DISABLE_TRUST_AGENTS >= 0) { agents=true; calculate -= KEYGUARD_DISABLE_TRUST_AGENTS } + if(calculate-KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS >= 0) { unredacted=true; calculate -= KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS } + if(calculate-KEYGUARD_DISABLE_SECURE_NOTIFICATIONS >= 0) { notification=true; calculate -= KEYGUARD_DISABLE_SECURE_NOTIFICATIONS } + if(calculate-KEYGUARD_DISABLE_SECURE_CAMERA >= 0) { camera=true; calculate -= KEYGUARD_DISABLE_SECURE_CAMERA } + if(calculate-KEYGUARD_DISABLE_WIDGETS_ALL >= 0) { widgets=true; calculate -= KEYGUARD_DISABLE_WIDGETS_ALL } } } - if(state==-1){ - state = when(dpm.getKeyguardDisabledFeatures(receiver)){ - KEYGUARD_DISABLE_FEATURES_NONE->0 - KEYGUARD_DISABLE_FEATURES_ALL->1 - else->2 + if(state==-1) { + state = when(dpm.getKeyguardDisabledFeatures(receiver)) { + KEYGUARD_DISABLE_FEATURES_NONE -> 0 + KEYGUARD_DISABLE_FEATURES_ALL -> 1 + else -> 2 } calculateCustomFeature() } - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.keyguard_disabled_features), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) - RadioButtonItem(stringResource(R.string.enable_all),{state==0},{state=0}) - RadioButtonItem(stringResource(R.string.disable_all),{state==1},{state=1}) - RadioButtonItem(stringResource(R.string.custom),{state==2},{state=2}) + RadioButtonItem(stringResource(R.string.enable_all), { state==0 }, { state=0 }) + RadioButtonItem(stringResource(R.string.disable_all), { state==1 }, { state=1 }) + RadioButtonItem(stringResource(R.string.custom), { state==2 }, { state=2 }) AnimatedVisibility(state==2) { Column { - CheckBoxItem(stringResource(R.string.keyguard_disabled_features_widgets),{widgets},{widgets=!widgets}) - CheckBoxItem(stringResource(R.string.keyguard_disabled_features_camera),{camera},{camera=!camera}) - CheckBoxItem(stringResource(R.string.keyguard_disabled_features_notification),{notification},{notification=!notification}) - CheckBoxItem(stringResource(R.string.keyguard_disabled_features_unredacted_notification),{unredacted},{unredacted=!unredacted}) - CheckBoxItem(stringResource(R.string.keyguard_disabled_features_trust_agents),{agents},{agents=!agents}) - CheckBoxItem(stringResource(R.string.keyguard_disabled_features_fingerprint),{fingerprint},{fingerprint=!fingerprint}) - if(VERSION.SDK_INT>=24){ CheckBoxItem(stringResource(R.string.keyguard_disabled_features_remote_input),{remote}, {remote=!remote}) } - if(VERSION.SDK_INT>=28){ - CheckBoxItem(stringResource(R.string.keyguard_disabled_features_face),{face},{face=!face}) - CheckBoxItem(stringResource(R.string.keyguard_disabled_features_iris),{iris},{iris=!iris}) - CheckBoxItem(stringResource(R.string.keyguard_disabled_features_biometrics),{biometrics},{biometrics=!biometrics}) + CheckBoxItem(stringResource(R.string.keyguard_disabled_features_widgets), { widgets }, { widgets=!widgets }) + CheckBoxItem(stringResource(R.string.keyguard_disabled_features_camera), { camera }, { camera=!camera }) + CheckBoxItem(stringResource(R.string.keyguard_disabled_features_notification), { notification }, { notification=!notification }) + CheckBoxItem(stringResource(R.string.keyguard_disabled_features_unredacted_notification), { unredacted }, { unredacted=!unredacted }) + CheckBoxItem(stringResource(R.string.keyguard_disabled_features_trust_agents), { agents }, { agents=!agents }) + CheckBoxItem(stringResource(R.string.keyguard_disabled_features_fingerprint), { fingerprint }, { fingerprint=!fingerprint }) + if(VERSION.SDK_INT >= 24) { CheckBoxItem(stringResource(R.string.keyguard_disabled_features_remote_input), { remote} , { remote=!remote }) } + if(VERSION.SDK_INT >= 28) { + CheckBoxItem(stringResource(R.string.keyguard_disabled_features_face), { face }, { face=!face }) + CheckBoxItem(stringResource(R.string.keyguard_disabled_features_iris), { iris }, { iris=!iris }) + CheckBoxItem(stringResource(R.string.keyguard_disabled_features_biometrics), { biometrics }, { biometrics=!biometrics }) } - if(VERSION.SDK_INT>=34){ CheckBoxItem(stringResource(R.string.keyguard_disabled_features_shortcuts),{shortcuts},{shortcuts=!shortcuts}) } + if(VERSION.SDK_INT >= 34) { CheckBoxItem(stringResource(R.string.keyguard_disabled_features_shortcuts), { shortcuts }, { shortcuts=!shortcuts }) } } } Spacer(Modifier.padding(vertical = 5.dp)) Button( onClick = { var result = 0 - if(state==0){ result = 0 } - else if(state==1){ result = KEYGUARD_DISABLE_FEATURES_ALL } + if(state==0) { result = 0 } + else if(state==1) { result = KEYGUARD_DISABLE_FEATURES_ALL } else{ - if(shortcuts&&VERSION.SDK_INT>=34){result+=KEYGUARD_DISABLE_SHORTCUTS_ALL} - if(biometrics&&VERSION.SDK_INT>=28){result+=KEYGUARD_DISABLE_BIOMETRICS} - if(iris&&VERSION.SDK_INT>=28){result+=KEYGUARD_DISABLE_IRIS} - if(face&&VERSION.SDK_INT>=28){result+=KEYGUARD_DISABLE_FACE} - if(remote&&VERSION.SDK_INT>=24){result+=KEYGUARD_DISABLE_REMOTE_INPUT} - if(fingerprint){result+=KEYGUARD_DISABLE_FINGERPRINT} - if(agents){result+=KEYGUARD_DISABLE_TRUST_AGENTS} - if(unredacted){result+=KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS} - if(notification){result+=KEYGUARD_DISABLE_SECURE_NOTIFICATIONS} - if(camera){result+=KEYGUARD_DISABLE_SECURE_CAMERA} - if(widgets){result+=KEYGUARD_DISABLE_WIDGETS_ALL} + if(shortcuts && VERSION.SDK_INT >= 34) { result+=KEYGUARD_DISABLE_SHORTCUTS_ALL } + if(biometrics && VERSION.SDK_INT >= 28) { result+=KEYGUARD_DISABLE_BIOMETRICS } + if(iris && VERSION.SDK_INT >= 28) { result+=KEYGUARD_DISABLE_IRIS } + if(face && VERSION.SDK_INT >= 28) { result+=KEYGUARD_DISABLE_FACE } + if(remote && VERSION.SDK_INT >= 24) { result+=KEYGUARD_DISABLE_REMOTE_INPUT } + if(fingerprint) { result+=KEYGUARD_DISABLE_FINGERPRINT } + if(agents) { result+=KEYGUARD_DISABLE_TRUST_AGENTS } + if(unredacted) { result+=KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS } + if(notification) { result+=KEYGUARD_DISABLE_SECURE_NOTIFICATIONS } + if(camera) { result+=KEYGUARD_DISABLE_SECURE_CAMERA } + if(widgets) { result+=KEYGUARD_DISABLE_WIDGETS_ALL } } dpm.setKeyguardDisabledFeatures(receiver,result) Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() calculateCustomFeature() }, - enabled = isDeviceOwner(dpm)||isProfileOwner(dpm), + enabled = isDeviceOwner(dpm) || isProfileOwner(dpm), modifier = Modifier.fillMaxWidth() ) { Text(text = stringResource(R.string.apply)) @@ -575,7 +586,7 @@ private fun KeyguardDisabledFeatures(){ } @Composable -private fun PasswordQuality(){ +private fun PasswordQuality() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val receiver = ComponentName(context,Receiver::class.java) @@ -587,25 +598,25 @@ private fun PasswordQuality(){ PASSWORD_QUALITY_ALPHANUMERIC to stringResource(R.string.password_quality_alphanumeric), PASSWORD_QUALITY_BIOMETRIC_WEAK to stringResource(R.string.password_quality_biometrics_weak), PASSWORD_QUALITY_NUMERIC_COMPLEX to stringResource(R.string.password_quality_numeric_complex), - PASSWORD_QUALITY_COMPLEX to stringResource(R.string.custom)+"(${stringResource(R.string.unsupported)})", + PASSWORD_QUALITY_COMPLEX to stringResource(R.string.custom) + "(${stringResource(R.string.unsupported) })", ).toList() - var selectedItem by remember{ mutableIntStateOf(passwordQuality[0].first) } - if(isDeviceOwner(dpm) || isProfileOwner(dpm)){ selectedItem=dpm.getPasswordQuality(receiver) } - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + var selectedItem by remember { mutableIntStateOf(passwordQuality[0].first) } + if(isDeviceOwner(dpm) || isProfileOwner(dpm)) { selectedItem=dpm.getPasswordQuality(receiver) } + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.required_password_quality), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) Text(text = stringResource(R.string.password_complexity_instead_password_quality)) - if(VERSION.SDK_INT>=31){ Text(text = stringResource(R.string.password_quality_deprecated_desc), color = colorScheme.error) } + if(VERSION.SDK_INT >= 31) { Text(text = stringResource(R.string.password_quality_deprecated_desc), color = colorScheme.error) } Spacer(Modifier.padding(vertical = 5.dp)) - RadioButtonItem(passwordQuality[0].second,{selectedItem==passwordQuality[0].first},{selectedItem=passwordQuality[0].first}) - RadioButtonItem(passwordQuality[1].second,{selectedItem==passwordQuality[1].first},{selectedItem=passwordQuality[1].first}) - RadioButtonItem(passwordQuality[2].second,{selectedItem==passwordQuality[2].first},{selectedItem=passwordQuality[2].first}) - RadioButtonItem(passwordQuality[3].second,{selectedItem==passwordQuality[3].first},{selectedItem=passwordQuality[3].first}) - RadioButtonItem(passwordQuality[4].second,{selectedItem==passwordQuality[4].first},{selectedItem=passwordQuality[4].first}) - RadioButtonItem(passwordQuality[5].second,{selectedItem==passwordQuality[5].first},{selectedItem=passwordQuality[5].first}) - RadioButtonItem(passwordQuality[6].second,{selectedItem==passwordQuality[6].first},{selectedItem=passwordQuality[6].first}) - RadioButtonItem(passwordQuality[7].second,{selectedItem==passwordQuality[7].first},{selectedItem=passwordQuality[7].first}) + RadioButtonItem(passwordQuality[0].second, { selectedItem == passwordQuality[0].first }, { selectedItem = passwordQuality[0].first }) + RadioButtonItem(passwordQuality[1].second, { selectedItem == passwordQuality[1].first }, { selectedItem = passwordQuality[1].first }) + RadioButtonItem(passwordQuality[2].second, { selectedItem == passwordQuality[2].first }, { selectedItem = passwordQuality[2].first }) + RadioButtonItem(passwordQuality[3].second, { selectedItem == passwordQuality[3].first }, { selectedItem = passwordQuality[3].first }) + RadioButtonItem(passwordQuality[4].second, { selectedItem == passwordQuality[4].first }, { selectedItem = passwordQuality[4].first }) + RadioButtonItem(passwordQuality[5].second, { selectedItem == passwordQuality[5].first }, { selectedItem = passwordQuality[5].first }) + RadioButtonItem(passwordQuality[6].second, { selectedItem == passwordQuality[6].first }, { selectedItem = passwordQuality[6].first }) + RadioButtonItem(passwordQuality[7].second, { selectedItem == passwordQuality[7].first }, { selectedItem = passwordQuality[7].first }) Spacer(Modifier.padding(vertical = 5.dp)) Button( onClick = { @@ -621,7 +632,7 @@ private fun PasswordQuality(){ } } -private fun activateToken(context: Context){ +private fun activateToken(context: Context) { val desc = context.getString(R.string.activate_reset_password_token_here) val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager val confirmIntent = keyguardManager.createConfirmDeviceCredentialIntent(context.getString(R.string.app_name), desc) 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 ba859d4..7ea26a6 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/Permissions.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/Permissions.kt @@ -40,33 +40,14 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.launch @Composable -fun DpmPermissions(navCtrl:NavHostController){ +fun DpmPermissions(navCtrl:NavHostController) { val localNavCtrl = rememberNavController() val backStackEntry by localNavCtrl.currentBackStackEntryAsState() val scrollState = rememberScrollState() - /*val titleMap = mapOf( - "Home" to R.string.permission, - "Shizuku" to R.string.shizuku, - "DeviceAdmin" to R.string.device_admin, - "ProfileOwner" to R.string.profile_owner, - "DeviceOwner" to R.string.device_owner, - "DeviceInfo" to R.string.device_info, - "SpecificID" to R.string.enrollment_specific_id, - "OrgName" to R.string.org_name, - "NoManagementAccount" to R.string.account_types_management_disabled, - "LockScreenInfo" to R.string.owner_lockscr_info, - "SupportMsg" to R.string.support_msg, - "TransformOwnership" to R.string.transform_ownership - )*/ Scaffold( topBar = { - /*TopAppBar( - title = {Text(text = stringResource(titleMap[backStackEntry?.destination?.route]?:R.string.permission))}, - navigationIcon = {NavIcon{if(backStackEntry?.destination?.route=="Home"){navCtrl.navigateUp()}else{localNavCtrl.navigateUp()}}}, - colors = TopAppBarDefaults.topAppBarColors(containerColor = colorScheme.surfaceVariant) - )*/ - TopBar(backStackEntry,navCtrl,localNavCtrl){ - if(backStackEntry?.destination?.route=="Home"&&scrollState.maxValue>80){ + TopBar(backStackEntry,navCtrl,localNavCtrl) { + if(backStackEntry?.destination?.route=="Home"&&scrollState.maxValue>80) { Text( text = stringResource(R.string.permission), modifier = Modifier.alpha((maxOf(scrollState.value-30,0)).toFloat()/80) @@ -74,7 +55,7 @@ fun DpmPermissions(navCtrl:NavHostController){ } } } - ){ + ) { NavHost( navController = localNavCtrl, startDestination = "Home", enterTransition = Animations.navHostEnterTransition, @@ -82,65 +63,69 @@ fun DpmPermissions(navCtrl:NavHostController){ popEnterTransition = Animations.navHostPopEnterTransition, popExitTransition = Animations.navHostPopExitTransition, modifier = Modifier.padding(top = it.calculateTopPadding()) - ){ - composable(route = "Home"){Home(localNavCtrl,scrollState)} - composable(route = "Shizuku"){ShizukuActivate()} - composable(route = "DeviceAdmin"){DeviceAdmin()} - composable(route = "ProfileOwner"){ProfileOwner()} - composable(route = "DeviceOwner"){DeviceOwner()} - composable(route = "DeviceInfo"){DeviceInfo()} - composable(route = "SpecificID"){SpecificID()} - composable(route = "OrgName"){OrgName()} - composable(route = "NoManagementAccount"){NoManageAccount()} - composable(route = "LockScreenInfo"){LockScreenInfo()} - composable(route = "SupportMsg"){SupportMsg()} - composable(route = "TransformOwnership"){TransformOwnership()} + ) { + composable(route = "Home") { Home(localNavCtrl,scrollState) } + composable(route = "Shizuku") { ShizukuActivate() } + composable(route = "DeviceAdmin") { DeviceAdmin() } + composable(route = "ProfileOwner") { ProfileOwner() } + composable(route = "DeviceOwner") { DeviceOwner() } + composable(route = "DeviceInfo") { DeviceInfo() } + composable(route = "SpecificID") { SpecificID() } + composable(route = "OrgName") { OrgName() } + composable(route = "NoManagementAccount") { NoManageAccount() } + composable(route = "LockScreenInfo") { LockScreenInfo() } + composable(route = "SupportMsg") { SupportMsg() } + composable(route = "TransformOwnership") { TransformOwnership() } } } } @Composable -private fun Home(localNavCtrl:NavHostController,listScrollState:ScrollState){ +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) Column(modifier = Modifier.fillMaxSize().verticalScroll(listScrollState)) { - Text(text = stringResource(R.string.permission), style = typography.headlineLarge, modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 15.dp)) - SubPageItem( - R.string.device_admin, stringResource(if(dpm.isAdminActive(receiver)){R.string.activated}else{R.string.deactivated}), - operation = {localNavCtrl.navigate("DeviceAdmin")} + Text( + text = stringResource(R.string.permission), + style = typography.headlineLarge, + modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 15.dp) ) - if(!isDeviceOwner(dpm)){ + SubPageItem( + R.string.device_admin, stringResource(if(dpm.isAdminActive(receiver)) R.string.activated else R.string.deactivated), + operation = { localNavCtrl.navigate("DeviceAdmin") } + ) + if(!isDeviceOwner(dpm)) { SubPageItem( - R.string.profile_owner, stringResource(if(isProfileOwner(dpm)){R.string.activated}else{R.string.deactivated}), - operation = {localNavCtrl.navigate("ProfileOwner")} + R.string.profile_owner, stringResource(if(isProfileOwner(dpm)) R.string.activated else R.string.deactivated), + operation = { localNavCtrl.navigate("ProfileOwner") } ) } - if(!isProfileOwner(dpm)){ + if(!isProfileOwner(dpm)) { SubPageItem( - R.string.device_owner, stringResource(if(isDeviceOwner(dpm)){R.string.activated}else{R.string.deactivated}), - operation = {localNavCtrl.navigate("DeviceOwner")} + R.string.device_owner, stringResource(if(isDeviceOwner(dpm)) 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>=31&&(isProfileOwner(dpm)|| isDeviceOwner(dpm))){ - SubPageItem(R.string.enrollment_specific_id,"",R.drawable.id_card_fill0){localNavCtrl.navigate("SpecificID")} + 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 >= 31 && (isProfileOwner(dpm) || isDeviceOwner(dpm))) { + SubPageItem(R.string.enrollment_specific_id, "", R.drawable.id_card_fill0) { localNavCtrl.navigate("SpecificID") } } - if((VERSION.SDK_INT>=26&&isDeviceOwner(dpm))||(VERSION.SDK_INT>=24&&isProfileOwner(dpm))){ - SubPageItem(R.string.org_name,"",R.drawable.corporate_fare_fill0){localNavCtrl.navigate("OrgName")} + if((VERSION.SDK_INT >= 26 && isDeviceOwner(dpm)) || (VERSION.SDK_INT>=24 && isProfileOwner(dpm))) { + SubPageItem(R.string.org_name, "", R.drawable.corporate_fare_fill0) { localNavCtrl.navigate("OrgName") } } - if(isDeviceOwner(dpm) || isProfileOwner(dpm)){ - SubPageItem(R.string.account_types_management_disabled,"",R.drawable.account_circle_fill0){localNavCtrl.navigate("NoManagementAccount")} + if(isDeviceOwner(dpm) || isProfileOwner(dpm)) { + SubPageItem(R.string.account_types_management_disabled, "", R.drawable.account_circle_fill0) { localNavCtrl.navigate("NoManagementAccount") } } - if(VERSION.SDK_INT>=24&&isDeviceOwner(dpm)){ - SubPageItem(R.string.device_owner_lock_screen_info,"",R.drawable.screen_lock_portrait_fill0){localNavCtrl.navigate("LockScreenInfo")} + if(VERSION.SDK_INT >= 24&&isDeviceOwner(dpm)) { + SubPageItem(R.string.device_owner_lock_screen_info, "", R.drawable.screen_lock_portrait_fill0) { localNavCtrl.navigate("LockScreenInfo") } } - if(VERSION.SDK_INT>=24&&(isDeviceOwner(dpm)||isProfileOwner(dpm))){ - SubPageItem(R.string.support_msg,"",R.drawable.chat_fill0){localNavCtrl.navigate("SupportMsg")} + if(VERSION.SDK_INT >= 24 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { + SubPageItem(R.string.support_msg, "", R.drawable.chat_fill0) { localNavCtrl.navigate("SupportMsg") } } - if(VERSION.SDK_INT>=28&&(isDeviceOwner(dpm)||isProfileOwner(dpm))){ - SubPageItem(R.string.transform_ownership,"",R.drawable.admin_panel_settings_fill0){localNavCtrl.navigate("TransformOwnership")} + if(VERSION.SDK_INT >= 28 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { + SubPageItem(R.string.transform_ownership, "", R.drawable.admin_panel_settings_fill0) { localNavCtrl.navigate("TransformOwnership") } } Spacer(Modifier.padding(vertical = 30.dp)) } @@ -148,18 +133,18 @@ private fun Home(localNavCtrl:NavHostController,listScrollState:ScrollState){ @SuppressLint("NewApi") @Composable -private fun LockScreenInfo(){ +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 focusMgr = LocalFocusManager.current - var infoText by remember{mutableStateOf(dpm.deviceOwnerLockScreenInfo?.toString() ?: "")} - Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)){ + var infoText by remember { mutableStateOf(dpm.deviceOwnerLockScreenInfo?.toString() ?: "") } + Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) { Text(text = stringResource(R.string.device_owner_lock_screen_info), style = typography.headlineLarge) OutlinedTextField( value = infoText, - label = {Text(stringResource(R.string.device_owner_lock_screen_info))}, - onValueChange = { infoText=it }, + label = { Text(stringResource(R.string.device_owner_lock_screen_info)) }, + onValueChange = { infoText = it }, modifier = Modifier.focusable().fillMaxWidth().padding(vertical = 4.dp) ) Button( @@ -186,24 +171,24 @@ private fun LockScreenInfo(){ } @Composable -private fun DeviceAdmin(){ +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 co = rememberCoroutineScope() - var showDeactivateButton by remember{mutableStateOf(dpm.isAdminActive(receiver))} - Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)){ + var showDeactivateButton by remember { mutableStateOf(dpm.isAdminActive(receiver)) } + Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.device_admin), style = typography.headlineLarge) - Text(text = stringResource(if(dpm.isAdminActive(receiver)) { R.string.activated } else { R.string.deactivated }), style = typography.titleLarge) + Text(text = stringResource(if(dpm.isAdminActive(receiver)) R.string.activated else R.string.deactivated), style = typography.titleLarge) Spacer(Modifier.padding(vertical = 5.dp)) AnimatedVisibility(showDeactivateButton) { Button( onClick = { dpm.removeActiveAdmin(receiver) - co.launch{ delay(400); showDeactivateButton=dpm.isAdminActive(receiver) } + co.launch{ delay(400); showDeactivateButton = dpm.isAdminActive(receiver) } }, - enabled = !isProfileOwner(dpm)&&!isDeviceOwner(dpm), + enabled = !isProfileOwner(dpm) && !isDeviceOwner(dpm), colors = ButtonDefaults.buttonColors(containerColor = colorScheme.error, contentColor = colorScheme.onError) ) { Text(stringResource(R.string.deactivate)) @@ -211,7 +196,7 @@ private fun DeviceAdmin(){ } AnimatedVisibility(!showDeactivateButton) { Column { - Button(onClick = {activateDeviceAdmin(context, receiver)}, modifier = Modifier.fillMaxWidth()) { + Button(onClick = {activateDeviceAdmin(context, receiver) }, modifier = Modifier.fillMaxWidth()) { Text(stringResource(R.string.activate_jump)) } Spacer(Modifier.padding(vertical = 5.dp)) @@ -225,17 +210,17 @@ private fun DeviceAdmin(){ } @Composable -private fun ProfileOwner(){ +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))} - Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)){ + var showDeactivateButton by remember { mutableStateOf(isProfileOwner(dpm)) } + 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(isProfileOwner(dpm)) R.string.activated else R.string.deactivated), style = typography.titleLarge) Spacer(Modifier.padding(vertical = 5.dp)) - if(VERSION.SDK_INT>=24){ + if(VERSION.SDK_INT>=24) { AnimatedVisibility(showDeactivateButton) { val co = rememberCoroutineScope() Button( @@ -262,15 +247,15 @@ private fun ProfileOwner(){ } @Composable -private fun DeviceOwner(){ +private fun DeviceOwner() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val co = rememberCoroutineScope() - var showDeactivateButton by remember{mutableStateOf(isDeviceOwner(dpm))} - Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)){ + var showDeactivateButton by remember { mutableStateOf(isDeviceOwner(dpm)) } + 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(isDeviceOwner(dpm)) R.string.activated else R.string.deactivated), style = typography.titleLarge) Spacer(Modifier.padding(vertical = 5.dp)) AnimatedVisibility(showDeactivateButton) { Button( @@ -295,23 +280,23 @@ private fun DeviceOwner(){ } @Composable -fun DeviceInfo(){ +fun DeviceInfo() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)){ + 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)||(isProfileOwner(dpm)&&dpm.isOrganizationOwnedDeviceWithManagedProfile))){ + if(VERSION.SDK_INT>=34 && (isDeviceOwner(dpm) || (isProfileOwner(dpm) && dpm.isOrganizationOwnedDeviceWithManagedProfile))) { val financed = dpm.isDeviceFinanced Text(stringResource(R.string.is_device_financed, financed)) } Spacer(Modifier.padding(vertical = 2.dp)) - if(VERSION.SDK_INT>=33){ + if(VERSION.SDK_INT >= 33) { val dpmRole = dpm.devicePolicyManagementRoleHolderPackage - Text(stringResource(R.string.dpmrh, if(dpmRole==null) { stringResource(R.string.none) } else { "" })) - if(dpmRole!=null){ - SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState())){ + Text(stringResource(R.string.dpmrh, if(dpmRole == null) stringResource(R.string.none) else "")) + if(dpmRole!=null) { + SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState())) { Text(text = dpmRole) } } @@ -322,21 +307,21 @@ fun DeviceInfo(){ DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE to stringResource(R.string.es_active), DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED to stringResource(R.string.es_unsupported) ) - if(VERSION.SDK_INT>=23){ encryptionStatus[DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY] = stringResource(R.string.es_active_default_key) } - if(VERSION.SDK_INT>=24){ encryptionStatus[DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER] = stringResource(R.string.es_active_per_user) } + if(VERSION.SDK_INT >= 23) { encryptionStatus[DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY] = stringResource(R.string.es_active_default_key) } + if(VERSION.SDK_INT >= 24) { encryptionStatus[DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER] = stringResource(R.string.es_active_per_user) } Text(stringResource(R.string.encrypt_status_is)+encryptionStatus[dpm.storageEncryptionStatus]) Spacer(Modifier.padding(vertical = 2.dp)) val adminList = dpm.activeAdmins - if(adminList!=null){ + if(adminList!=null) { var adminListText = "" Text(text = stringResource(R.string.activated_device_admin, adminList.size)) var count = adminList.size - for(each in adminList){ + for(each in adminList) { count -= 1 adminListText += "$each" - if(count>0){adminListText += "\n"} + if(count>0) {adminListText += "\n"} } - SelectionContainer(modifier = Modifier.fillMaxWidth().padding(vertical = 2.dp).horizontalScroll(rememberScrollState())){ + SelectionContainer(modifier = Modifier.fillMaxWidth().padding(vertical = 2.dp).horizontalScroll(rememberScrollState())) { Text(text = adminListText) } } @@ -345,16 +330,16 @@ fun DeviceInfo(){ @SuppressLint("NewApi") @Composable -private fun SpecificID(){ +private fun SpecificID() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)){ + Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) { val specificId = dpm.enrollmentSpecificId Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.enrollment_specific_id), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) - if(specificId!=""){ - SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState())){ Text(specificId) } + if(specificId != "") { + SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState())) { Text(specificId) } CopyTextButton(R.string.copy, specificId) }else{ Text(stringResource(R.string.require_set_org_id)) @@ -364,21 +349,21 @@ private fun SpecificID(){ @SuppressLint("NewApi") @Composable -private fun OrgName(){ +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 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){""})} + Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) { + var orgName by remember { mutableStateOf(try{dpm.getOrganizationName(receiver).toString() }catch(e:SecurityException) {""}) } Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.org_name), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) OutlinedTextField( - value = orgName, onValueChange = {orgName=it}, modifier = Modifier.focusable().fillMaxWidth().padding(vertical = 3.dp), - label = {Text(stringResource(R.string.org_name))}, + value = orgName, onValueChange = { orgName = it }, modifier = Modifier.focusable().fillMaxWidth().padding(vertical = 3.dp), + label = { Text(stringResource(R.string.org_name)) }, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}) + keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus() }) ) Spacer(Modifier.padding(vertical = 5.dp)) Button( @@ -388,7 +373,7 @@ private fun OrgName(){ Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() }, modifier = Modifier.fillMaxWidth() - ){ + ) { Text(stringResource(R.string.apply)) } } @@ -396,28 +381,28 @@ private fun OrgName(){ @SuppressLint("NewApi") @Composable -private fun SupportMsg(){ +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 focusMgr = LocalFocusManager.current - var shortMsg by remember{mutableStateOf(dpm.getShortSupportMessage(receiver)?.toString() ?: "")} - var longMsg by remember{mutableStateOf(dpm.getLongSupportMessage(receiver)?.toString() ?: "")} - Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)){ + var shortMsg by remember { mutableStateOf(dpm.getShortSupportMessage(receiver)?.toString() ?: "") } + var longMsg by remember { mutableStateOf(dpm.getLongSupportMessage(receiver)?.toString() ?: "") } + Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.support_msg), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) OutlinedTextField( value = shortMsg, - label = {Text(stringResource(R.string.short_support_msg))}, - onValueChange = { shortMsg=it }, + label = { Text(stringResource(R.string.short_support_msg)) }, + onValueChange = { shortMsg = it }, modifier = Modifier.focusable().fillMaxWidth() ) Spacer(Modifier.padding(vertical = 2.dp)) OutlinedTextField( value = longMsg, - label = {Text(stringResource(R.string.long_support_msg))}, - onValueChange = { longMsg=it }, + label = { Text(stringResource(R.string.long_support_msg)) }, + onValueChange = { longMsg = it }, modifier = Modifier.focusable().fillMaxWidth() ) Spacer(Modifier.padding(vertical = 5.dp)) @@ -449,18 +434,18 @@ private fun SupportMsg(){ Text(text = stringResource(R.string.reset)) } Spacer(Modifier.padding(vertical = 5.dp)) - Information{Text(text = stringResource(R.string.support_msg_desc))} + Information{ Text(text = stringResource(R.string.support_msg_desc)) } Spacer(Modifier.padding(vertical = 30.dp)) } } @Composable -private fun NoManageAccount(){ +private fun NoManageAccount() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val receiver = ComponentName(context,Receiver::class.java) val focusMgr = LocalFocusManager.current - Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)){ + Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.account_types_management_disabled), style = typography.headlineLarge) Text(stringResource(R.string.unknown_effect)) @@ -470,38 +455,38 @@ private fun NoManageAccount(){ accountList = "" if (noManageAccount != null) { var count = noManageAccount.size - for(each in noManageAccount){ count -= 1; accountList += each; if(count>0){accountList += "\n"} } + for(each in noManageAccount) { count -= 1; accountList += each; if(count>0) { accountList += "\n" } } } } - var inited by remember{mutableStateOf(false)} - if(!inited){ refreshList(); inited=true } + var inited by remember { mutableStateOf(false) } + if(!inited) { refreshList(); inited=true } Spacer(Modifier.padding(vertical = 5.dp)) - Text(text = if(accountList==""){stringResource(R.string.none)}else{accountList}) + Text(text = if(accountList=="") stringResource(R.string.none) else accountList) var inputText by remember{ mutableStateOf("") } OutlinedTextField( value = inputText, - onValueChange = {inputText=it}, - label = {Text(stringResource(R.string.account_types))}, + onValueChange = { inputText = it }, + label = { Text(stringResource(R.string.account_types)) }, modifier = Modifier.focusable().fillMaxWidth().padding(vertical = 4.dp), keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}) + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }) ) Button( onClick={ - dpm.setAccountManagementDisabled(receiver,inputText,true) + dpm.setAccountManagementDisabled(receiver, inputText, true) refreshList() }, modifier = Modifier.fillMaxWidth() - ){ + ) { Text(stringResource(R.string.add)) } Button( onClick={ - dpm.setAccountManagementDisabled(receiver,inputText,false) + dpm.setAccountManagementDisabled(receiver, inputText, false) refreshList() }, modifier = Modifier.fillMaxWidth() - ){ + ) { Text(stringResource(R.string.remove)) } } @@ -509,32 +494,32 @@ private fun NoManageAccount(){ @SuppressLint("NewApi") @Composable -private fun TransformOwnership(){ +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 focusMgr = LocalFocusManager.current val focusRequester = FocusRequester() - Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)){ - var pkg by remember{mutableStateOf("")} - var cls by remember{mutableStateOf("")} + Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) { + var pkg by remember { mutableStateOf("") } + var cls by remember { mutableStateOf("") } Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.transform_ownership), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) Text(text = stringResource(R.string.transform_ownership_desc)) Spacer(Modifier.padding(vertical = 5.dp)) OutlinedTextField( - value = pkg, onValueChange = {pkg = it}, label = {Text(stringResource(R.string.target_package_name))}, + value = pkg, onValueChange = { pkg = it }, label = { Text(stringResource(R.string.target_package_name)) }, modifier = Modifier.fillMaxWidth(), keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), - keyboardActions = KeyboardActions(onNext = {focusRequester.requestFocus()}) + keyboardActions = KeyboardActions(onNext = { focusRequester.requestFocus() }) ) Spacer(Modifier.padding(vertical = 2.dp)) OutlinedTextField( - value = cls, onValueChange = {cls = it}, label = {Text(stringResource(R.string.target_class_name))}, + value = cls, onValueChange = {cls = it }, label = { Text(stringResource(R.string.target_class_name)) }, modifier = Modifier.focusRequester(focusRequester).fillMaxWidth(), keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}) + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }) ) Spacer(Modifier.padding(vertical = 5.dp)) Button( @@ -542,7 +527,7 @@ private fun TransformOwnership(){ try { dpm.transferOwnership(receiver,ComponentName(pkg, cls),null) Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() - }catch(e:IllegalArgumentException){ + }catch(e:IllegalArgumentException) { Toast.makeText(context, R.string.fail, Toast.LENGTH_SHORT).show() } }, @@ -554,13 +539,13 @@ private fun TransformOwnership(){ } } -private fun activateDeviceAdmin(inputContext:Context,inputComponent:ComponentName){ +private fun activateDeviceAdmin(inputContext:Context,inputComponent:ComponentName) { try { val intent = Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN) intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, inputComponent) intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, inputContext.getString(R.string.activate_device_admin_here)) addDeviceAdmin.launch(intent) - }catch(e:ActivityNotFoundException){ + }catch(e:ActivityNotFoundException) { Toast.makeText(inputContext, R.string.unsupported, Toast.LENGTH_SHORT).show() } } 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 a8c1678..02b9847 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/ShizukuActivate.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/ShizukuActivate.kt @@ -39,7 +39,7 @@ import rikka.shizuku.Shizuku private var waitGrantPermission = false @Composable -fun ShizukuActivate(){ +fun ShizukuActivate() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val receiver = ComponentName(context, Receiver::class.java) @@ -47,15 +47,15 @@ fun ShizukuActivate(){ 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 showOrgProfileOwnerButton by remember{mutableStateOf(true)} - LaunchedEffect(Unit){ - if(service==null){userServiceControl(context, true)} - while(true){ - if(service==null){ + 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 showOrgProfileOwnerButton by remember { mutableStateOf(true) } + LaunchedEffect(Unit) { + if(service == null) { userServiceControl(context, true) } + while(true) { + if(service == null) { enabled = false bindShizuku = checkShizukuStatus()==1 }else{ @@ -71,14 +71,14 @@ fun ShizukuActivate(){ .padding(horizontal = 8.dp) .verticalScroll(rememberScrollState()), horizontalAlignment = Alignment.CenterHorizontally - ){ + ) { AnimatedVisibility(bindShizuku) { Button( onClick = { userServiceControl(context, true) outputText = "" } - ){ + ) { Text(stringResource(R.string.bind_shizuku)) } } @@ -107,7 +107,7 @@ fun ShizukuActivate(){ } Spacer(Modifier.padding(vertical = 5.dp)) - AnimatedVisibility(showDeviceAdminButton&&showProfileOwnerButton&&showDeviceOwnerButton) { + AnimatedVisibility(showDeviceAdminButton && showProfileOwnerButton && showDeviceOwnerButton) { Button( onClick = { coScope.launch{ @@ -139,7 +139,7 @@ fun ShizukuActivate(){ } } - AnimatedVisibility(showDeviceOwnerButton&&showProfileOwnerButton) { + AnimatedVisibility(showDeviceOwnerButton && showProfileOwnerButton) { Button( onClick = { coScope.launch{ @@ -156,8 +156,8 @@ fun ShizukuActivate(){ } if( - VERSION.SDK_INT>=30&&isProfileOwner(dpm)&&dpm.isManagedProfile(receiver)&&!dpm.isOrganizationOwnedDeviceWithManagedProfile - ){ + VERSION.SDK_INT >= 30 && isProfileOwner(dpm) && dpm.isManagedProfile(receiver) && !dpm.isOrganizationOwnedDeviceWithManagedProfile + ) { AnimatedVisibility(showOrgProfileOwnerButton) { Button( onClick = { @@ -180,7 +180,7 @@ fun ShizukuActivate(){ SelectionContainer(modifier = Modifier .align(Alignment.Start) - .horizontalScroll(outputTextScrollState)){ + .horizontalScroll(outputTextScrollState)) { Text(text = outputText, softWrap = false, modifier = Modifier.padding(4.dp)) } @@ -196,12 +196,12 @@ fun scrollAnim( ): SpringSpec = SpringSpec(dampingRatio, stiffness, visibilityThreshold) private fun checkPermission(context: Context):String{ - if(checkShizukuStatus()==-1){return context.getString(R.string.shizuku_not_started)} - val getUid = if(service==null){return context.getString(R.string.shizuku_not_bind)}else{service!!.uid} - return when(getUid){ + if(checkShizukuStatus()==-1) { return context.getString(R.string.shizuku_not_started) } + val getUid = if(service==null) { return context.getString(R.string.shizuku_not_bind) } else { service!!.uid } + return when(getUid) { "2000"->context.getString(R.string.shizuku_activated_shell) "0"->context.getString(R.string.shizuku_activated_root) - else->context.getString(R.string.unknown_status)+"\nUID: $getUid" + else->context.getString(R.string.unknown_status) + "\nUID: $getUid" } } @@ -210,16 +210,16 @@ fun checkShizukuStatus():Int{ if(Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED) { waitGrantPermission = false; 1 } else if(Shizuku.shouldShowRequestPermissionRationale()) { 0 } else{ - if(!waitGrantPermission){Shizuku.requestPermission(0)} + if(!waitGrantPermission) {Shizuku.requestPermission(0) } waitGrantPermission = true 0 } - }catch(e:Exception){ -1 } + } catch(e:Exception) { -1 } return status } -fun userServiceControl(context:Context, status:Boolean){ - if(checkShizukuStatus()!=1){ return } +fun userServiceControl(context:Context, status:Boolean) { + if(checkShizukuStatus()!=1) { return } val userServiceConnection = object : ServiceConnection { override fun onServiceConnected(componentName: ComponentName, binder: IBinder) { if (binder.pingBinder()) { @@ -233,7 +233,7 @@ fun userServiceControl(context:Context, status:Boolean){ Toast.makeText(context, R.string.shizuku_service_disconnected, Toast.LENGTH_SHORT).show() } } - val userServiceArgs = Shizuku.UserServiceArgs( + val userServiceArgs = Shizuku.UserServiceArgs( ComponentName( context.packageName,ShizukuService::class.java.name ) @@ -242,9 +242,9 @@ fun userServiceControl(context:Context, status:Boolean){ .processNameSuffix("service") .debuggable(true) .version(26) - if(status){ - Shizuku.bindUserService(userServiceArgs,userServiceConnection) + if(status) { + Shizuku.bindUserService(userServiceArgs, userServiceConnection) }else{ - Shizuku.unbindUserService(userServiceArgs,userServiceConnection,false) + Shizuku.unbindUserService(userServiceArgs, userServiceConnection, false) } } diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/ShizukuService.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/ShizukuService.kt index 3b17ea2..82ff371 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/ShizukuService.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/ShizukuService.kt @@ -10,16 +10,16 @@ var service:IUserService? = null @Keep class ShizukuService: IUserService.Stub() { - override fun destroy(){ } + override fun destroy() { } override fun execute(command: String?): String { var result = "" - val process:Process + val process: Process try { process = Runtime.getRuntime().exec(command) val exitCode = process.waitFor() if(exitCode!=0){ result+="Error: $exitCode" } - }catch(e:Exception){ + } catch(e:Exception) { e.printStackTrace() return e.toString() } @@ -33,7 +33,7 @@ class ShizukuService: IUserService.Stub() { } catch(e: NullPointerException) { e.printStackTrace() } - if(result==""){ return "No result" } + if(result=="") { return "No result" } return result } 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 3c3b56e..afe0798 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/SystemManager.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/SystemManager.kt @@ -51,34 +51,14 @@ import com.bintianqi.owndroid.ui.* import java.util.Date @Composable -fun SystemManage(navCtrl:NavHostController){ +fun SystemManage(navCtrl:NavHostController) { val localNavCtrl = rememberNavController() val backStackEntry by localNavCtrl.currentBackStackEntryAsState() val scrollState = rememberScrollState() - /*val titleMap = mapOf( - "Switches" to R.string.options, - "Keyguard" to R.string.keyguard, - "BugReport" to R.string.request_bug_report, - "Reboot" to R.string.reboot, - "EditTime" to R.string.edit_time, - "PermissionPolicy" to R.string.permission_policy, - "MTEPolicy" to R.string.mte_policy, - "NearbyStreamingPolicy" to R.string.nearby_streaming_policy, - "LockTaskFeatures" to R.string.lock_task_feature, - "CaCert" to R.string.ca_cert, - "SecurityLogs" to R.string.security_logs, - "SystemUpdatePolicy" to R.string.system_update_policy, - "WipeData" to R.string.wipe_data - )*/ Scaffold( topBar = { - /*TopAppBar( - title = {Text(text = stringResource(titleMap[backStackEntry?.destination?.route]?:R.string.device_ctrl))}, - navigationIcon = {NavIcon{if(backStackEntry?.destination?.route=="Home"){navCtrl.navigateUp()}else{localNavCtrl.navigateUp()}}}, - colors = TopAppBarDefaults.topAppBarColors(containerColor = colorScheme.surfaceVariant) - )*/ - TopBar(backStackEntry,navCtrl,localNavCtrl){ - if(backStackEntry?.destination?.route=="Home"&&scrollState.maxValue>80){ + TopBar(backStackEntry,navCtrl,localNavCtrl) { + if(backStackEntry?.destination?.route=="Home"&&scrollState.maxValue>80) { Text( text = stringResource(R.string.system_manage), modifier = Modifier.alpha((maxOf(scrollState.value-30,0)).toFloat()/80) @@ -86,7 +66,7 @@ fun SystemManage(navCtrl:NavHostController){ } } } - ){ + ) { NavHost( navController = localNavCtrl, startDestination = "Home", enterTransition = Animations.navHostEnterTransition, @@ -94,130 +74,134 @@ fun SystemManage(navCtrl:NavHostController){ popEnterTransition = Animations.navHostPopEnterTransition, popExitTransition = Animations.navHostPopExitTransition, modifier = Modifier.padding(top = it.calculateTopPadding()) - ){ - composable(route = "Home"){Home(localNavCtrl,scrollState)} - composable(route = "Switches"){Switches()} - composable(route = "Keyguard"){Keyguard()} - composable(route = "BugReport"){BugReport()} - composable(route = "Reboot"){Reboot()} - composable(route = "EditTime"){EditTime()} - composable(route = "PermissionPolicy"){PermissionPolicy()} - composable(route = "MTEPolicy"){MTEPolicy()} - composable(route = "NearbyStreamingPolicy"){NearbyStreamingPolicy()} - composable(route = "LockTaskFeatures"){LockTaskFeatures()} - composable(route = "CaCert"){CaCert()} - composable(route = "SecurityLogs"){SecurityLogs()} - composable(route = "SystemUpdatePolicy"){SysUpdatePolicy()} - composable(route = "WipeData"){WipeData()} + ) { + composable(route = "Home") { Home(localNavCtrl,scrollState) } + composable(route = "Switches") { Switches() } + composable(route = "Keyguard") { Keyguard() } + composable(route = "BugReport") { BugReport() } + composable(route = "Reboot") { Reboot() } + composable(route = "EditTime") { EditTime() } + composable(route = "PermissionPolicy") { PermissionPolicy() } + composable(route = "MTEPolicy") { MTEPolicy() } + composable(route = "NearbyStreamingPolicy") { NearbyStreamingPolicy() } + composable(route = "LockTaskFeatures") { LockTaskFeatures() } + composable(route = "CaCert") { CaCert() } + composable(route = "SecurityLogs") { SecurityLogs() } + composable(route = "SystemUpdatePolicy") { SysUpdatePolicy() } + composable(route = "WipeData") { WipeData() } } } } @Composable -private fun Home(navCtrl: NavHostController,scrollState: ScrollState){ +private fun Home(navCtrl: NavHostController, scrollState: ScrollState) { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)){ - Text(text = stringResource(R.string.system_manage), style = typography.headlineLarge, modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 15.dp)) - if(isDeviceOwner(dpm)||isProfileOwner(dpm)){ - SubPageItem(R.string.options,"",R.drawable.tune_fill0){navCtrl.navigate("Switches")} + Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)) { + Text( + text = stringResource(R.string.system_manage), + style = typography.headlineLarge, + modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 15.dp) + ) + if(isDeviceOwner(dpm) || isProfileOwner(dpm)) { + 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){ - SubPageItem(R.string.request_bug_report,"",R.drawable.bug_report_fill0){navCtrl.navigate("BugReport")} - SubPageItem(R.string.reboot,"",R.drawable.restart_alt_fill0){navCtrl.navigate("Reboot")} + SubPageItem(R.string.keyguard, "", R.drawable.screen_lock_portrait_fill0) { navCtrl.navigate("Keyguard") } + if(VERSION.SDK_INT >= 24) { + SubPageItem(R.string.request_bug_report, "", R.drawable.bug_report_fill0) { navCtrl.navigate("BugReport") } + SubPageItem(R.string.reboot, "", R.drawable.restart_alt_fill0) { navCtrl.navigate("Reboot") } } - if(VERSION.SDK_INT>=28){ - SubPageItem(R.string.edit_time,"",R.drawable.schedule_fill0){navCtrl.navigate("EditTime")} + if(VERSION.SDK_INT >= 28) { + SubPageItem(R.string.edit_time, "", R.drawable.schedule_fill0) { navCtrl.navigate("EditTime") } } - if(VERSION.SDK_INT>=23&&(isDeviceOwner(dpm)||isProfileOwner(dpm))){ - SubPageItem(R.string.permission_policy,"",R.drawable.key_fill0){navCtrl.navigate("PermissionPolicy")} + if(VERSION.SDK_INT >= 23 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { + SubPageItem(R.string.permission_policy, "", R.drawable.key_fill0) { navCtrl.navigate("PermissionPolicy") } } - if(VERSION.SDK_INT>=34&&isDeviceOwner(dpm)){ - SubPageItem(R.string.mte_policy,"",R.drawable.memory_fill0){navCtrl.navigate("MTEPolicy")} + if(VERSION.SDK_INT >= 34 && isDeviceOwner(dpm)) { + SubPageItem(R.string.mte_policy, "", R.drawable.memory_fill0) { navCtrl.navigate("MTEPolicy") } } - if(VERSION.SDK_INT>=31&&(isDeviceOwner(dpm)||isProfileOwner(dpm))){ - SubPageItem(R.string.nearby_streaming_policy,"",R.drawable.share_fill0){navCtrl.navigate("NearbyStreamingPolicy")} + if(VERSION.SDK_INT >= 31 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { + SubPageItem(R.string.nearby_streaming_policy, "", R.drawable.share_fill0) { navCtrl.navigate("NearbyStreamingPolicy") } } - if(VERSION.SDK_INT>=28&&isDeviceOwner(dpm)){ - SubPageItem(R.string.lock_task_feature,"",R.drawable.lock_fill0){navCtrl.navigate("LockTaskFeatures")} + if(VERSION.SDK_INT >= 28 && isDeviceOwner(dpm)) { + SubPageItem(R.string.lock_task_feature, "", R.drawable.lock_fill0) { navCtrl.navigate("LockTaskFeatures") } } - if(isDeviceOwner(dpm)||isProfileOwner(dpm)){ - SubPageItem(R.string.ca_cert,"",R.drawable.license_fill0){navCtrl.navigate("CaCert")} + if(isDeviceOwner(dpm) || isProfileOwner(dpm)) { + SubPageItem(R.string.ca_cert, "", R.drawable.license_fill0) { navCtrl.navigate("CaCert") } } - if(VERSION.SDK_INT>=26&&(isDeviceOwner(dpm)||(VERSION.SDK_INT>=30&&isProfileOwner(dpm)&&dpm.isOrganizationOwnedDeviceWithManagedProfile))){ - SubPageItem(R.string.security_logs,"",R.drawable.description_fill0){navCtrl.navigate("SecurityLogs")} + if(VERSION.SDK_INT >= 26 && (isDeviceOwner(dpm) || (VERSION.SDK_INT >= 30 && isProfileOwner(dpm) && dpm.isOrganizationOwnedDeviceWithManagedProfile))) { + SubPageItem(R.string.security_logs, "", R.drawable.description_fill0) { navCtrl.navigate("SecurityLogs") } } - if(VERSION.SDK_INT>=23&&isDeviceOwner(dpm)){ - SubPageItem(R.string.system_update_policy,"",R.drawable.system_update_fill0){navCtrl.navigate("SystemUpdatePolicy")} + if(VERSION.SDK_INT >= 23 && isDeviceOwner(dpm)) { + SubPageItem(R.string.system_update_policy, "", R.drawable.system_update_fill0) { navCtrl.navigate("SystemUpdatePolicy") } } - SubPageItem(R.string.wipe_data,"",R.drawable.warning_fill0){navCtrl.navigate("WipeData")} + SubPageItem(R.string.wipe_data, "", R.drawable.warning_fill0) { navCtrl.navigate("WipeData") } Spacer(Modifier.padding(vertical = 30.dp)) - LaunchedEffect(Unit){ fileUriFlow.value = Uri.parse("") } + LaunchedEffect(Unit) { fileUriFlow.value = Uri.parse("") } } } @Composable -private fun Switches(){ +private fun Switches() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val receiver = ComponentName(context, Receiver::class.java) - Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) - if(isDeviceOwner(dpm)||isProfileOwner(dpm)){ + if(isDeviceOwner(dpm) || isProfileOwner(dpm)) { SwitchItem(R.string.disable_cam,"", R.drawable.photo_camera_fill0, - {dpm.getCameraDisabled(null)},{dpm.setCameraDisabled(receiver,it)} + { dpm.getCameraDisabled(null) }, { dpm.setCameraDisabled(receiver,it) } ) } - if(isDeviceOwner(dpm)||isProfileOwner(dpm)){ - SwitchItem(R.string.disable_screenshot, stringResource(R.string.also_disable_aosp_screen_record),R.drawable.screenshot_fill0, - {dpm.getScreenCaptureDisabled(null)},{dpm.setScreenCaptureDisabled(receiver,it) } + if(isDeviceOwner(dpm) || isProfileOwner(dpm)) { + SwitchItem(R.string.disable_screenshot, 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))){ - SwitchItem(R.string.disable_status_bar,"",R.drawable.notifications_fill0, - {dpm.isStatusBarDisabled},{dpm.setStatusBarDisabled(receiver,it) } + if(VERSION.SDK_INT >= 34 && (isDeviceOwner(dpm) || (isProfileOwner(dpm) && dpm.isAffiliatedUser))) { + SwitchItem(R.string.disable_status_bar, "", R.drawable.notifications_fill0, + { dpm.isStatusBarDisabled}, { dpm.setStatusBarDisabled(receiver,it) } ) } - if(isDeviceOwner(dpm)||(VERSION.SDK_INT>=30&&isProfileOwner(dpm)&&dpm.isOrganizationOwnedDeviceWithManagedProfile)){ - if(VERSION.SDK_INT>=30){ - SwitchItem(R.string.auto_time,"",R.drawable.schedule_fill0, - {dpm.getAutoTimeEnabled(receiver)},{dpm.setAutoTimeEnabled(receiver,it) } + if(isDeviceOwner(dpm) || (VERSION.SDK_INT >= 30 && isProfileOwner(dpm) && dpm.isOrganizationOwnedDeviceWithManagedProfile)) { + if(VERSION.SDK_INT >= 30) { + SwitchItem(R.string.auto_time, "", R.drawable.schedule_fill0, + { dpm.getAutoTimeEnabled(receiver) }, { dpm.setAutoTimeEnabled(receiver,it) } ) - SwitchItem(R.string.auto_timezone,"",R.drawable.globe_fill0, - {dpm.getAutoTimeZoneEnabled(receiver)},{dpm.setAutoTimeZoneEnabled(receiver,it) } + SwitchItem(R.string.auto_timezone, "", R.drawable.globe_fill0, + { dpm.getAutoTimeZoneEnabled(receiver) }, { dpm.setAutoTimeZoneEnabled(receiver,it) } ) }else{ - SwitchItem(R.string.auto_time,"",R.drawable.schedule_fill0,{dpm.autoTimeRequired},{dpm.setAutoTimeRequired(receiver,it)}) + SwitchItem(R.string.auto_time, "", R.drawable.schedule_fill0, { dpm.autoTimeRequired}, { dpm.setAutoTimeRequired(receiver,it) }) } } - if(isDeviceOwner(dpm)|| isProfileOwner(dpm)){ - SwitchItem(R.string.master_mute,"",R.drawable.volume_up_fill0, - {dpm.isMasterVolumeMuted(receiver)},{dpm.setMasterVolumeMuted(receiver,it) } + if(isDeviceOwner(dpm) || isProfileOwner(dpm)) { + 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))){ - SwitchItem(R.string.backup_service,"",R.drawable.backup_fill0, - {dpm.isBackupServiceEnabled(receiver)},{dpm.setBackupServiceEnabled(receiver,it) } + if(VERSION.SDK_INT >= 26 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { + 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))){ - SwitchItem(R.string.disable_bt_contact_share,"",R.drawable.account_circle_fill0, - {dpm.getBluetoothContactSharingDisabled(receiver)},{dpm.setBluetoothContactSharingDisabled(receiver,it)} + if(VERSION.SDK_INT >= 23 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { + 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 && isDeviceOwner(dpm)) { SwitchItem(R.string.common_criteria_mode, stringResource(R.string.common_criteria_mode_desc),R.drawable.security_fill0, - {dpm.isCommonCriteriaModeEnabled(receiver)},{dpm.setCommonCriteriaModeEnabled(receiver,it)} + { dpm.isCommonCriteriaModeEnabled(receiver) }, { dpm.setCommonCriteriaModeEnabled(receiver,it) } ) } - if(VERSION.SDK_INT>=31&&(isDeviceOwner(dpm)||(VERSION.SDK_INT>=30&&isProfileOwner(dpm)&&dpm.isOrganizationOwnedDeviceWithManagedProfile))){ + if(VERSION.SDK_INT >= 31 && (isDeviceOwner(dpm) || (VERSION.SDK_INT >= 30 && isProfileOwner(dpm) && dpm.isOrganizationOwnedDeviceWithManagedProfile))) { SwitchItem( - R.string.usb_signal,"",R.drawable.usb_fill0, {dpm.isUsbDataSignalingEnabled}, + R.string.usb_signal, "", R.drawable.usb_fill0, { dpm.isUsbDataSignalingEnabled }, { - if(dpm.canUsbDataSignalingBeDisabled()){ + if(dpm.canUsbDataSignalingBeDisabled()) { dpm.isUsbDataSignalingEnabled = it - }else{ + } else { Toast.makeText(context, R.string.unsupported, Toast.LENGTH_SHORT).show() } } @@ -228,62 +212,68 @@ private fun Switches(){ } @Composable -private fun Keyguard(){ +private fun Keyguard() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val receiver = ComponentName(context,Receiver::class.java) - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + 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) Spacer(Modifier.padding(vertical = 5.dp)) - if(VERSION.SDK_INT>=23){ + if(VERSION.SDK_INT >= 23) { Button( onClick = { - Toast.makeText(context, if(dpm.setKeyguardDisabled(receiver,true)){R.string.success}else{R.string.fail}, Toast.LENGTH_SHORT).show() + Toast.makeText(context, if(dpm.setKeyguardDisabled(receiver,true)) R.string.success else R.string.fail, Toast.LENGTH_SHORT).show() }, - enabled = isDeviceOwner(dpm)|| (VERSION.SDK_INT>=28&&isProfileOwner(dpm)&&dpm.isAffiliatedUser), + enabled = isDeviceOwner(dpm) || (VERSION.SDK_INT >= 28 && isProfileOwner(dpm) && dpm.isAffiliatedUser), modifier = Modifier.fillMaxWidth() ) { Text(stringResource(R.string.disable)) } Button( onClick = { - Toast.makeText(context, if(dpm.setKeyguardDisabled(receiver,false)){R.string.success}else{R.string.fail}, Toast.LENGTH_SHORT).show() + Toast.makeText(context, if(dpm.setKeyguardDisabled(receiver,false)) R.string.success else R.string.fail, Toast.LENGTH_SHORT).show() }, - enabled = isDeviceOwner(dpm)|| (VERSION.SDK_INT>=28&&isProfileOwner(dpm)&&dpm.isAffiliatedUser), + enabled = isDeviceOwner(dpm) || (VERSION.SDK_INT >= 28 && isProfileOwner(dpm) && dpm.isAffiliatedUser), modifier = Modifier.fillMaxWidth() ) { Text(stringResource(R.string.enable)) } Spacer(Modifier.padding(vertical = 3.dp)) - Information{Text(text = stringResource(R.string.require_no_password_to_disable))} + Information{ Text(text = stringResource(R.string.require_no_password_to_disable)) } Spacer(Modifier.padding(vertical = 8.dp)) } - var flag by remember{mutableIntStateOf(0)} + var flag by remember { mutableIntStateOf(0) } Button( - onClick = {dpm.lockNow()}, + onClick = { dpm.lockNow() }, enabled = dpm.isAdminActive(receiver), modifier = Modifier.fillMaxWidth() ) { Text(stringResource(R.string.lock_now)) } - if(VERSION.SDK_INT>=26){ CheckBoxItem(stringResource(R.string.require_enter_password_again),{flag==FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY},{flag = if(flag==0){1}else{0} }) } + if(VERSION.SDK_INT >= 26) { + CheckBoxItem( + stringResource(R.string.require_enter_password_again), + { flag==FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY }, + { flag = if(flag==0) {1}else{0} } + ) + } Spacer(Modifier.padding(vertical = 30.dp)) } } @SuppressLint("NewApi") @Composable -private fun BugReport(){ +private fun BugReport() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val receiver = ComponentName(context,Receiver::class.java) - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp)){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp)) { Spacer(Modifier.padding(vertical = 10.dp)) Button( onClick = { val result = dpm.requestBugreport(receiver) - Toast.makeText(context, if(result){R.string.success}else{R.string.fail}, Toast.LENGTH_SHORT).show() + Toast.makeText(context, if(result) R.string.success else R.string.fail, Toast.LENGTH_SHORT).show() }, modifier = Modifier.fillMaxWidth(), enabled = isDeviceOwner(dpm) @@ -295,14 +285,14 @@ private fun BugReport(){ @SuppressLint("NewApi") @Composable -private fun Reboot(){ +private fun Reboot() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val receiver = ComponentName(context,Receiver::class.java) - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp)){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp)) { Spacer(Modifier.padding(vertical = 10.dp)) Button( - onClick = {dpm.reboot(receiver)}, + onClick = { dpm.reboot(receiver) }, enabled = isDeviceOwner(dpm), modifier = Modifier.fillMaxWidth() ) { @@ -313,37 +303,37 @@ private fun Reboot(){ @SuppressLint("NewApi") @Composable -private fun EditTime(){ +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 focusMgr = LocalFocusManager.current - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.edit_time), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) - var inputTime by remember{mutableStateOf("")} + var inputTime by remember { mutableStateOf("") } Text(text = stringResource(R.string.from_epoch_to_target_time)) Spacer(Modifier.padding(vertical = 5.dp)) OutlinedTextField( value = inputTime, - label = { Text(stringResource(R.string.time_unit_ms))}, - onValueChange = {inputTime = it}, + label = { Text(stringResource(R.string.time_unit_ms)) }, + onValueChange = { inputTime = it}, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), - enabled = isDeviceOwner(dpm)||(VERSION.SDK_INT>=30&&isProfileOwner(dpm)&&dpm.isOrganizationOwnedDeviceWithManagedProfile), + keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus() }), + enabled = isDeviceOwner(dpm) || (VERSION.SDK_INT >= 30 && isProfileOwner(dpm) && dpm.isOrganizationOwnedDeviceWithManagedProfile), modifier = Modifier.focusable().fillMaxWidth() ) Spacer(Modifier.padding(vertical = 5.dp)) Button( - onClick = {dpm.setTime(receiver,inputTime.toLong())}, + onClick = { dpm.setTime(receiver,inputTime.toLong()) }, modifier = Modifier.fillMaxWidth(), - enabled = inputTime!=""&&(isDeviceOwner(dpm)||(VERSION.SDK_INT>=30&&isProfileOwner(dpm)&&dpm.isOrganizationOwnedDeviceWithManagedProfile)) + enabled = inputTime!="" && (isDeviceOwner(dpm) || (VERSION.SDK_INT >= 30 && isProfileOwner(dpm) && dpm.isOrganizationOwnedDeviceWithManagedProfile)) ) { - Text("应用") + Text(stringResource(R.string.apply)) } Button( - onClick = {inputTime = System.currentTimeMillis().toString()}, + onClick = { inputTime = System.currentTimeMillis().toString() }, modifier = Modifier.fillMaxWidth() ) { Text(stringResource(R.string.get_current_time)) @@ -353,18 +343,18 @@ private fun EditTime(){ @SuppressLint("NewApi") @Composable -private fun PermissionPolicy(){ +private fun PermissionPolicy() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val receiver = ComponentName(context,Receiver::class.java) - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ - var selectedPolicy by remember{mutableIntStateOf(dpm.getPermissionPolicy(receiver))} + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { + var selectedPolicy by remember { mutableIntStateOf(dpm.getPermissionPolicy(receiver)) } Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.permission_policy), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) - RadioButtonItem(stringResource(R.string.default_stringres), {selectedPolicy==PERMISSION_POLICY_PROMPT}, {selectedPolicy= PERMISSION_POLICY_PROMPT}) - RadioButtonItem(stringResource(R.string.auto_grant), {selectedPolicy==PERMISSION_POLICY_AUTO_GRANT}, {selectedPolicy= PERMISSION_POLICY_AUTO_GRANT}) - RadioButtonItem(stringResource(R.string.auto_deny), {selectedPolicy==PERMISSION_POLICY_AUTO_DENY}, {selectedPolicy= PERMISSION_POLICY_AUTO_DENY}) + RadioButtonItem(stringResource(R.string.default_stringres), { selectedPolicy==PERMISSION_POLICY_PROMPT}, { selectedPolicy= PERMISSION_POLICY_PROMPT}) + RadioButtonItem(stringResource(R.string.auto_grant), { selectedPolicy==PERMISSION_POLICY_AUTO_GRANT}, { selectedPolicy= PERMISSION_POLICY_AUTO_GRANT}) + RadioButtonItem(stringResource(R.string.auto_deny), { selectedPolicy==PERMISSION_POLICY_AUTO_DENY}, { selectedPolicy= PERMISSION_POLICY_AUTO_DENY}) Spacer(Modifier.padding(vertical = 5.dp)) Button( onClick = { @@ -380,23 +370,35 @@ private fun PermissionPolicy(){ @SuppressLint("NewApi") @Composable -private fun MTEPolicy(){ +private fun MTEPolicy() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + 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) Spacer(Modifier.padding(vertical = 5.dp)) - var selectedMtePolicy by remember{mutableIntStateOf(dpm.mtePolicy)} - RadioButtonItem(stringResource(R.string.decide_by_user), {selectedMtePolicy==MTE_NOT_CONTROLLED_BY_POLICY}, {selectedMtePolicy= MTE_NOT_CONTROLLED_BY_POLICY}) - RadioButtonItem(stringResource(R.string.enabled), {selectedMtePolicy==MTE_ENABLED}, {selectedMtePolicy=MTE_ENABLED}) - RadioButtonItem(stringResource(R.string.disabled), {selectedMtePolicy==MTE_DISABLED}, {selectedMtePolicy=MTE_DISABLED}) + var selectedMtePolicy by remember { mutableIntStateOf(dpm.mtePolicy) } + RadioButtonItem( + stringResource(R.string.decide_by_user), + { selectedMtePolicy == MTE_NOT_CONTROLLED_BY_POLICY }, + { selectedMtePolicy = MTE_NOT_CONTROLLED_BY_POLICY } + ) + RadioButtonItem( + stringResource(R.string.enabled), + { selectedMtePolicy == MTE_ENABLED }, + { selectedMtePolicy = MTE_ENABLED } + ) + RadioButtonItem( + stringResource(R.string.disabled), + { selectedMtePolicy == MTE_DISABLED }, + { selectedMtePolicy = MTE_DISABLED } + ) Button( onClick = { try { dpm.mtePolicy = selectedMtePolicy Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() - }catch(e:java.lang.UnsupportedOperationException){ + }catch(e:java.lang.UnsupportedOperationException) { Toast.makeText(context, R.string.unsupported, Toast.LENGTH_SHORT).show() } selectedMtePolicy = dpm.mtePolicy @@ -406,25 +408,41 @@ private fun MTEPolicy(){ Text(stringResource(R.string.apply)) } Spacer(Modifier.padding(vertical = 5.dp)) - Information{Text(stringResource(R.string.mte_policy_desc))} + Information { Text(stringResource(R.string.mte_policy_desc)) } Spacer(Modifier.padding(vertical = 30.dp)) } } @SuppressLint("NewApi") @Composable -private fun NearbyStreamingPolicy(){ +private fun NearbyStreamingPolicy() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ - var appPolicy by remember{mutableIntStateOf(dpm.nearbyAppStreamingPolicy)} + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { + var appPolicy by remember { mutableIntStateOf(dpm.nearbyAppStreamingPolicy) } Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.nearby_app_streaming), style = typography.titleLarge) Spacer(Modifier.padding(vertical = 3.dp)) - RadioButtonItem(stringResource(R.string.decide_by_user),{appPolicy == NEARBY_STREAMING_NOT_CONTROLLED_BY_POLICY},{appPolicy = NEARBY_STREAMING_NOT_CONTROLLED_BY_POLICY}) - RadioButtonItem(stringResource(R.string.enabled),{appPolicy == NEARBY_STREAMING_ENABLED},{appPolicy = NEARBY_STREAMING_ENABLED}) - RadioButtonItem(stringResource(R.string.disabled),{appPolicy == NEARBY_STREAMING_DISABLED},{appPolicy = NEARBY_STREAMING_DISABLED}) - RadioButtonItem(stringResource(R.string.enable_if_secure_enough),{appPolicy == NEARBY_STREAMING_SAME_MANAGED_ACCOUNT_ONLY},{appPolicy = NEARBY_STREAMING_SAME_MANAGED_ACCOUNT_ONLY}) + RadioButtonItem( + stringResource(R.string.decide_by_user), + { appPolicy == NEARBY_STREAMING_NOT_CONTROLLED_BY_POLICY }, + { appPolicy = NEARBY_STREAMING_NOT_CONTROLLED_BY_POLICY } + ) + RadioButtonItem( + stringResource(R.string.enabled), + { appPolicy == NEARBY_STREAMING_ENABLED }, + { appPolicy = NEARBY_STREAMING_ENABLED } + ) + RadioButtonItem( + stringResource(R.string.disabled), + { appPolicy == NEARBY_STREAMING_DISABLED }, + { appPolicy = NEARBY_STREAMING_DISABLED } + ) + RadioButtonItem( + stringResource(R.string.enable_if_secure_enough), + { appPolicy == NEARBY_STREAMING_SAME_MANAGED_ACCOUNT_ONLY }, + { appPolicy = NEARBY_STREAMING_SAME_MANAGED_ACCOUNT_ONLY } + ) Spacer(Modifier.padding(vertical = 3.dp)) Button( onClick = { @@ -433,16 +451,32 @@ private fun NearbyStreamingPolicy(){ }, modifier = Modifier.fillMaxWidth() ) { - Text("应用") + Text(stringResource(R.string.apply)) } - var notificationPolicy by remember{mutableIntStateOf(dpm.nearbyNotificationStreamingPolicy)} + var notificationPolicy by remember { mutableIntStateOf(dpm.nearbyNotificationStreamingPolicy) } Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.nearby_notification_streaming), style = typography.titleLarge) Spacer(Modifier.padding(vertical = 3.dp)) - RadioButtonItem(stringResource(R.string.decide_by_user),{notificationPolicy == NEARBY_STREAMING_NOT_CONTROLLED_BY_POLICY},{notificationPolicy = NEARBY_STREAMING_NOT_CONTROLLED_BY_POLICY}) - RadioButtonItem(stringResource(R.string.enabled),{notificationPolicy == NEARBY_STREAMING_ENABLED},{notificationPolicy = NEARBY_STREAMING_ENABLED}) - RadioButtonItem(stringResource(R.string.disabled),{notificationPolicy == NEARBY_STREAMING_DISABLED},{notificationPolicy = NEARBY_STREAMING_DISABLED}) - RadioButtonItem(stringResource(R.string.enable_if_secure_enough),{notificationPolicy == NEARBY_STREAMING_SAME_MANAGED_ACCOUNT_ONLY},{notificationPolicy = NEARBY_STREAMING_SAME_MANAGED_ACCOUNT_ONLY}) + RadioButtonItem( + stringResource(R.string.decide_by_user), + { notificationPolicy == NEARBY_STREAMING_NOT_CONTROLLED_BY_POLICY }, + { notificationPolicy = NEARBY_STREAMING_NOT_CONTROLLED_BY_POLICY } + ) + RadioButtonItem( + stringResource(R.string.enabled), + { notificationPolicy == NEARBY_STREAMING_ENABLED }, + { notificationPolicy = NEARBY_STREAMING_ENABLED } + ) + RadioButtonItem( + stringResource(R.string.disabled), + { notificationPolicy == NEARBY_STREAMING_DISABLED }, + { notificationPolicy = NEARBY_STREAMING_DISABLED } + ) + RadioButtonItem( + stringResource(R.string.enable_if_secure_enough), + { notificationPolicy == NEARBY_STREAMING_SAME_MANAGED_ACCOUNT_ONLY }, + { notificationPolicy = NEARBY_STREAMING_SAME_MANAGED_ACCOUNT_ONLY } + ) Spacer(Modifier.padding(vertical = 3.dp)) Button( onClick = { @@ -459,12 +493,12 @@ private fun NearbyStreamingPolicy(){ @SuppressLint("NewApi") @Composable -private fun LockTaskFeatures(){ +private fun LockTaskFeatures() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val receiver = ComponentName(context,Receiver::class.java) val focusMgr = LocalFocusManager.current - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { val lockTaskPolicyList = mutableListOf( LOCK_TASK_FEATURE_NONE, LOCK_TASK_FEATURE_SYSTEM_INFO, @@ -474,26 +508,26 @@ private fun LockTaskFeatures(){ LOCK_TASK_FEATURE_GLOBAL_ACTIONS, LOCK_TASK_FEATURE_KEYGUARD ) - var sysInfo by remember{mutableStateOf(false)} - var notifications by remember{mutableStateOf(false)} - var home by remember{mutableStateOf(false)} - var overview by remember{mutableStateOf(false)} - var globalAction by remember{mutableStateOf(false)} - var keyGuard by remember{mutableStateOf(false)} - var blockAct by remember{mutableStateOf(false)} - if(VERSION.SDK_INT>=30){lockTaskPolicyList.add(LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK)} - var inited by remember{mutableStateOf(false)} - var custom by remember{mutableStateOf(false)} + var sysInfo by remember { mutableStateOf(false) } + var notifications by remember { mutableStateOf(false) } + var home by remember { mutableStateOf(false) } + var overview by remember { mutableStateOf(false) } + var globalAction by remember { mutableStateOf(false) } + var keyGuard by remember { mutableStateOf(false) } + var blockAct by remember { mutableStateOf(false) } + if(VERSION.SDK_INT >= 30) { lockTaskPolicyList.add(LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK) } + var inited by remember { mutableStateOf(false) } + var custom by remember { mutableStateOf(false) } val refreshFeature = { var calculate = dpm.getLockTaskFeatures(receiver) - if(calculate!=0){ - if(VERSION.SDK_INT>=30&&calculate-lockTaskPolicyList[7]>=0){blockAct=true;calculate-=lockTaskPolicyList[7]} - if(calculate-lockTaskPolicyList[6]>=0){keyGuard=true;calculate-=lockTaskPolicyList[6]} - if(calculate-lockTaskPolicyList[5]>=0){globalAction=true;calculate-=lockTaskPolicyList[5]} - if(calculate-lockTaskPolicyList[4]>=0){overview=true;calculate-=lockTaskPolicyList[4]} - if(calculate-lockTaskPolicyList[3]>=0){home=true;calculate-=lockTaskPolicyList[3]} - if(calculate-lockTaskPolicyList[2]>=0){notifications=true;calculate-=lockTaskPolicyList[2]} - if(calculate-lockTaskPolicyList[1]>=0){sysInfo=true;calculate-=lockTaskPolicyList[1]} + if(calculate!=0) { + if(VERSION.SDK_INT >= 30 && calculate-lockTaskPolicyList[7] >= 0) { blockAct= true; calculate -= lockTaskPolicyList[7] } + if(calculate-lockTaskPolicyList[6] >= 0) { keyGuard = true; calculate -= lockTaskPolicyList[6] } + if(calculate-lockTaskPolicyList[5] >= 0) { globalAction= true; calculate -= lockTaskPolicyList[5] } + if(calculate-lockTaskPolicyList[4] >= 0) { overview= true; calculate -= lockTaskPolicyList[4] } + if(calculate-lockTaskPolicyList[3] >= 0) { home= true; calculate -= lockTaskPolicyList[3] } + if(calculate-lockTaskPolicyList[2] >= 0) { notifications= true; calculate -= lockTaskPolicyList[2] } + if(calculate-lockTaskPolicyList[1] >= 0) { sysInfo= true; calculate -= lockTaskPolicyList[1] } }else{ custom = false } @@ -501,32 +535,32 @@ private fun LockTaskFeatures(){ Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.lock_task_feature), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) - if(!inited){ refreshFeature();custom=dpm.getLockTaskFeatures(receiver)!=0;inited=true } - RadioButtonItem(stringResource(R.string.disable_all),{!custom},{custom=false}) - RadioButtonItem(stringResource(R.string.custom),{custom},{custom=true}) + if(!inited) { refreshFeature(); custom=dpm.getLockTaskFeatures(receiver)!=0; inited= true } + RadioButtonItem(stringResource(R.string.disable_all), { !custom }, { custom=false }) + RadioButtonItem(stringResource(R.string.custom), { custom }, { custom= true }) AnimatedVisibility(custom) { Column { - CheckBoxItem(stringResource(R.string.ltf_sys_info),{sysInfo},{sysInfo=!sysInfo}) - CheckBoxItem(stringResource(R.string.ltf_notifications),{notifications},{notifications=!notifications}) - CheckBoxItem(stringResource(R.string.ltf_home),{home},{home=!home}) - CheckBoxItem(stringResource(R.string.ltf_overview),{overview},{overview=!overview}) - CheckBoxItem(stringResource(R.string.ltf_global_actions),{globalAction},{globalAction=!globalAction}) - CheckBoxItem(stringResource(R.string.ltf_keyguard),{keyGuard},{keyGuard=!keyGuard}) - if(VERSION.SDK_INT>=30){ CheckBoxItem(stringResource(R.string.ltf_block_activity_start_in_task),{blockAct},{blockAct=!blockAct}) } + CheckBoxItem(stringResource(R.string.ltf_sys_info), { sysInfo }, { sysInfo = !sysInfo }) + CheckBoxItem(stringResource(R.string.ltf_notifications), { notifications }, { notifications = !notifications }) + CheckBoxItem(stringResource(R.string.ltf_home), { home }, { home = !home }) + CheckBoxItem(stringResource(R.string.ltf_overview), { overview }, { overview = !overview }) + CheckBoxItem(stringResource(R.string.ltf_global_actions), { globalAction}, {globalAction = !globalAction}) + CheckBoxItem(stringResource(R.string.ltf_keyguard), { keyGuard }, { keyGuard = !keyGuard }) + if(VERSION.SDK_INT >= 30) { CheckBoxItem(stringResource(R.string.ltf_block_activity_start_in_task), { blockAct }, { blockAct=!blockAct }) } } } Button( modifier = Modifier.fillMaxWidth(), onClick = { var result = lockTaskPolicyList[0] - if(custom){ - if(blockAct&&VERSION.SDK_INT>=30){result+=lockTaskPolicyList[7]} - if(keyGuard){result+=lockTaskPolicyList[6]} - if(globalAction){result+=lockTaskPolicyList[5]} - if(overview){result+=lockTaskPolicyList[4]} - if(home){result+=lockTaskPolicyList[3]} - if(notifications){result+=lockTaskPolicyList[2]} - if(sysInfo){result+=lockTaskPolicyList[1]} + if(custom) { + if(blockAct&&VERSION.SDK_INT >= 30) { result += lockTaskPolicyList[7] } + if(keyGuard) { result += lockTaskPolicyList[6] } + if(globalAction) { result += lockTaskPolicyList[5] } + if(overview) { result += lockTaskPolicyList[4] } + if(home) { result += lockTaskPolicyList[3] } + if(notifications) { result += lockTaskPolicyList[2] } + if(sysInfo) { result += lockTaskPolicyList[1] } } dpm.setLockTaskFeatures(receiver,result) refreshFeature() @@ -537,27 +571,27 @@ private fun LockTaskFeatures(){ } Spacer(Modifier.padding(vertical = 5.dp)) val whitelist = dpm.getLockTaskPackages(receiver).toMutableList() - var listText by remember{mutableStateOf("")} - var inputPkg by remember{mutableStateOf("")} + var listText by remember { mutableStateOf("") } + var inputPkg by remember { mutableStateOf("") } val refreshWhitelist = { - inputPkg="" - listText="" + inputPkg = "" + listText = "" listText = whitelist.toText() } - LaunchedEffect(Unit){refreshWhitelist()} + LaunchedEffect(Unit) { refreshWhitelist() } Text(text = stringResource(R.string.whitelist_app), style = typography.titleLarge) - SelectionContainer(modifier = Modifier.animateContentSize()){ - Text(text = if(listText==""){ stringResource(R.string.none) }else{listText}) + SelectionContainer(modifier = Modifier.animateContentSize()) { + Text(text = if(listText == "") stringResource(R.string.none) else listText) } OutlinedTextField( value = inputPkg, - onValueChange = {inputPkg=it}, - label = {Text(stringResource(R.string.package_name))}, + onValueChange = { inputPkg = it }, + label = { Text(stringResource(R.string.package_name)) }, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth().padding(vertical = 3.dp) ) - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { Button( onClick = { focusMgr.clearFocus() @@ -573,11 +607,11 @@ private fun LockTaskFeatures(){ Button( onClick = { focusMgr.clearFocus() - if(inputPkg in whitelist){ + if(inputPkg in whitelist) { whitelist.remove(inputPkg) dpm.setLockTaskPackages(receiver,whitelist.toTypedArray()) Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() - }else{ + } else { Toast.makeText(context, R.string.not_exist, Toast.LENGTH_SHORT).show() } refreshWhitelist() @@ -592,19 +626,19 @@ private fun LockTaskFeatures(){ } @Composable -private fun CaCert(){ +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 uri by fileUriFlow.collectAsState() - var exist by remember{mutableStateOf(false)} + var exist by remember { mutableStateOf(false) } val uriPath = uri.path ?: "" - var caCertByteArray by remember{ mutableStateOf(byteArrayOf()) } + var caCertByteArray by remember { mutableStateOf(byteArrayOf()) } LaunchedEffect(uri) { if(uri != Uri.parse("")) { - uriToStream(context, uri){ + uriToStream(context, uri) { val array = it.readBytes() - caCertByteArray = if(array.size<10000){ + caCertByteArray = if(array.size < 10000) { array }else{ byteArrayOf() @@ -613,15 +647,15 @@ private fun CaCert(){ exist = dpm.hasCaCertInstalled(receiver, caCertByteArray) } } - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.ca_cert), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) - AnimatedVisibility(uriPath!="") { + AnimatedVisibility(uriPath != "") { Text(text = uriPath) } Text( - text = if(uriPath==""){stringResource(R.string.please_select_ca_cert)}else{stringResource(R.string.cacert_installed, exist)}, + text = if(uriPath == "") { stringResource(R.string.please_select_ca_cert) } else { stringResource(R.string.cacert_installed, exist) }, modifier = Modifier.animateContentSize() ) Spacer(Modifier.padding(vertical = 5.dp)) @@ -636,12 +670,12 @@ private fun CaCert(){ ) { Text(stringResource(R.string.select_ca_cert)) } - AnimatedVisibility(uriPath!="") { - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ + AnimatedVisibility(uriPath != "") { + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { Button( onClick = { val result = dpm.installCaCert(receiver, caCertByteArray) - Toast.makeText(context, if(result){R.string.success}else{R.string.fail}, Toast.LENGTH_SHORT).show() + Toast.makeText(context, if(result) R.string.success else R.string.fail, Toast.LENGTH_SHORT).show() exist = dpm.hasCaCertInstalled(receiver, caCertByteArray) }, modifier = Modifier.fillMaxWidth(0.49F) @@ -650,11 +684,11 @@ private fun CaCert(){ } Button( onClick = { - if(exist){ + if(exist) { dpm.uninstallCaCert(receiver, caCertByteArray) exist = dpm.hasCaCertInstalled(receiver, caCertByteArray) - Toast.makeText(context, if(exist){R.string.fail}else{R.string.success}, Toast.LENGTH_SHORT).show() - }else{ Toast.makeText(context, R.string.not_exist, Toast.LENGTH_SHORT).show() } + Toast.makeText(context, if(exist) R.string.fail else R.string.success, Toast.LENGTH_SHORT).show() + } else { Toast.makeText(context, R.string.not_exist, Toast.LENGTH_SHORT).show() } }, modifier = Modifier.fillMaxWidth(0.96F) ) { @@ -668,7 +702,7 @@ private fun CaCert(){ Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() }, modifier = Modifier.fillMaxWidth() - ){ + ) { Text(stringResource(R.string.uninstall_all_user_ca_cert)) } } @@ -676,24 +710,24 @@ private fun CaCert(){ @SuppressLint("NewApi") @Composable -private fun SecurityLogs(){ +private fun SecurityLogs() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + val receiver = ComponentName(context, Receiver::class.java) + 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) Spacer(Modifier.padding(vertical = 5.dp)) Text(text = stringResource(R.string.developing)) - SwitchItem(R.string.enable,"",null,{dpm.isSecurityLoggingEnabled(receiver)},{dpm.setSecurityLoggingEnabled(receiver,it)}) + SwitchItem(R.string.enable, "", null, { dpm.isSecurityLoggingEnabled(receiver) }, { dpm.setSecurityLoggingEnabled(receiver,it) }) Button( onClick = { val log = dpm.retrieveSecurityLogs(receiver) - if(log!=null){ - for(i in log){ Log.d("SecureLog",i.toString()) } + if(log!=null) { + for(i in log) { Log.d("SecureLog",i.toString()) } Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() }else{ - Log.d("SecureLog",context.getString(R.string.none)) + Log.d("SecureLog", context.getString(R.string.none)) Toast.makeText(context, R.string.no_logs, Toast.LENGTH_SHORT).show() } }, @@ -704,11 +738,11 @@ private fun SecurityLogs(){ Button( onClick = { val log = dpm.retrievePreRebootSecurityLogs(receiver) - if(log!=null){ - for(i in log){ Log.d("SecureLog",i.toString()) } + if(log!=null) { + for(i in log) { Log.d("SecureLog",i.toString()) } Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() }else{ - Log.d("SecureLog",context.getString(R.string.none)) + Log.d("SecureLog", context.getString(R.string.none)) Toast.makeText(context, R.string.no_logs, Toast.LENGTH_SHORT).show() } }, @@ -720,33 +754,42 @@ private fun SecurityLogs(){ } @Composable -private fun WipeData(){ +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 focusMgr = LocalFocusManager.current - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ - var flag by remember{ mutableIntStateOf(0) } - var confirmed by remember{ mutableStateOf(false) } - var externalStorage by remember{mutableStateOf(false)} - var protectionData by remember{mutableStateOf(false)} - var euicc by remember{mutableStateOf(false)} - var silent by remember{mutableStateOf(false)} - var reason by remember{mutableStateOf("")} + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { + var flag by remember { mutableIntStateOf(0) } + var confirmed by remember { mutableStateOf(false) } + var externalStorage by remember { mutableStateOf(false) } + var protectionData by remember { mutableStateOf(false) } + var euicc by remember { mutableStateOf(false) } + var silent by remember { mutableStateOf(false) } + var reason by remember { mutableStateOf("") } Spacer(Modifier.padding(vertical = 10.dp)) - Text(text = stringResource(R.string.wipe_data),style = typography.headlineLarge,modifier = Modifier.padding(6.dp),color = colorScheme.error) + Text( + text = stringResource(R.string.wipe_data), + style = typography.headlineLarge, + modifier = Modifier.padding(6.dp),color = colorScheme.error + ) Spacer(Modifier.padding(vertical = 5.dp)) - CheckBoxItem(stringResource(R.string.wipe_external_storage),{externalStorage},{externalStorage=!externalStorage;confirmed=false}) - if(VERSION.SDK_INT>=22&&isDeviceOwner(dpm)){ - CheckBoxItem(stringResource(R.string.wipe_reset_protection_data),{protectionData},{protectionData=!protectionData;confirmed=false}) + CheckBoxItem( + stringResource(R.string.wipe_external_storage), + { externalStorage }, { externalStorage = !externalStorage; confirmed = false } + ) + if(VERSION.SDK_INT >= 22 && isDeviceOwner(dpm)) { + CheckBoxItem(stringResource(R.string.wipe_reset_protection_data), + { protectionData }, { protectionData = !protectionData; confirmed = false} + ) } - if(VERSION.SDK_INT>=28){ CheckBoxItem(stringResource(R.string.wipe_euicc),{euicc},{euicc=!euicc;confirmed=false}) } - if(VERSION.SDK_INT>=29){ CheckBoxItem(stringResource(R.string.wipe_silently),{silent},{silent=!silent;confirmed=false}) } - AnimatedVisibility(!silent&&VERSION.SDK_INT>=28) { + if(VERSION.SDK_INT >= 28) { CheckBoxItem(stringResource(R.string.wipe_euicc), { euicc }, { euicc = !euicc; confirmed = false }) } + if(VERSION.SDK_INT >= 29) { CheckBoxItem(stringResource(R.string.wipe_silently), { silent }, { silent = !silent; confirmed = false }) } + AnimatedVisibility(!silent && VERSION.SDK_INT >= 28) { OutlinedTextField( - value = reason, onValueChange = {reason=it}, - label = {Text(stringResource(R.string.reason))}, + value = reason, onValueChange = { reason = it }, + label = { Text(stringResource(R.string.reason)) }, enabled = !confirmed, modifier = Modifier.fillMaxWidth().padding(vertical = 3.dp) ) @@ -756,39 +799,39 @@ private fun WipeData(){ onClick = { focusMgr.clearFocus() flag = 0 - if(externalStorage){flag += WIPE_EXTERNAL_STORAGE} - if(protectionData&&VERSION.SDK_INT>=22){flag += WIPE_RESET_PROTECTION_DATA} - if(euicc&&VERSION.SDK_INT>=28){flag += WIPE_EUICC} - if(reason==""){silent = true} - if(silent&&VERSION.SDK_INT>=29){flag += WIPE_SILENTLY} - confirmed=!confirmed + if(externalStorage) { flag += WIPE_EXTERNAL_STORAGE } + if(protectionData && VERSION.SDK_INT >= 22) { flag += WIPE_RESET_PROTECTION_DATA } + if(euicc && VERSION.SDK_INT >= 28) { flag += WIPE_EUICC } + if(reason == "") { silent = true } + if(silent && VERSION.SDK_INT >= 29) { flag += WIPE_SILENTLY } + confirmed = !confirmed }, colors = ButtonDefaults.buttonColors( - containerColor = if(confirmed){ colorScheme.primary }else{ colorScheme.error }, - contentColor = if(confirmed){ colorScheme.onPrimary }else{ colorScheme.onError } + containerColor = if(confirmed) colorScheme.primary else colorScheme.error , + contentColor = if(confirmed) colorScheme.onPrimary else colorScheme.onError ), enabled = dpm.isAdminActive(receiver), modifier = Modifier.fillMaxWidth() ) { - Text(text = stringResource(if(confirmed){ R.string.cancel }else{ R.string.confirm })) + Text(text = stringResource(if(confirmed) R.string.cancel else R.string.confirm)) } Button( onClick = { - if(VERSION.SDK_INT>=28&&reason!=""){ - dpm.wipeData(flag,reason) + if(VERSION.SDK_INT >= 28 && reason != "") { + dpm.wipeData(flag, reason) }else{ dpm.wipeData(flag) } }, colors = ButtonDefaults.buttonColors(containerColor = colorScheme.error, contentColor = colorScheme.onError), - enabled = confirmed&&(VERSION.SDK_INT<34||(VERSION.SDK_INT>=34&&!userManager.isSystemUser)), + enabled = confirmed && (VERSION.SDK_INT < 34 || (VERSION.SDK_INT >= 34 && !userManager.isSystemUser)), modifier = Modifier.fillMaxWidth() ) { Text("WipeData") } - if (VERSION.SDK_INT >= 34&&(isDeviceOwner(dpm)||(isProfileOwner(dpm)&&dpm.isOrganizationOwnedDeviceWithManagedProfile))) { + if (VERSION.SDK_INT >= 34 && (isDeviceOwner(dpm) || (isProfileOwner(dpm) && dpm.isOrganizationOwnedDeviceWithManagedProfile))) { Button( - onClick = {dpm.wipeDevice(flag)}, + onClick = { dpm.wipeDevice(flag) }, colors = ButtonDefaults.buttonColors(containerColor = colorScheme.error, contentColor = colorScheme.onError), enabled = confirmed, modifier = Modifier.fillMaxWidth() @@ -797,68 +840,74 @@ private fun WipeData(){ } } Spacer(Modifier.padding(vertical = 5.dp)) - if(VERSION.SDK_INT>=24&&isProfileOwner(dpm)&&dpm.isManagedProfile(receiver)){ - Information{Text(text = stringResource(R.string.will_delete_work_profile))} + if(VERSION.SDK_INT >= 24 && isProfileOwner(dpm) && dpm.isManagedProfile(receiver)) { + Information{ Text(text = stringResource(R.string.will_delete_work_profile)) } } - if(VERSION.SDK_INT>=34&&Binder.getCallingUid()/100000==0){ - Information{Text(text = stringResource(R.string.api34_or_above_wipedata_cannot_in_system_user))} + if(VERSION.SDK_INT >= 34 && Binder.getCallingUid()/100000 == 0) { + Information{ Text(text = stringResource(R.string.api34_or_above_wipedata_cannot_in_system_user)) } } Spacer(Modifier.padding(vertical = 30.dp)) } } @Composable -private fun SysUpdatePolicy(){ +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 focusMgr = LocalFocusManager.current - val sharedPref = context.getSharedPreferences("data", Context.MODE_PRIVATE) - val isWear = sharedPref.getBoolean("isWear",false) - val bodyTextStyle = if(isWear){ typography.bodyMedium}else{typography.bodyLarge} - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) - if(VERSION.SDK_INT>=23){ + if(VERSION.SDK_INT >= 23) { Column { - var selectedPolicy by remember{ mutableStateOf(dpm.systemUpdatePolicy?.policyType) } + var selectedPolicy by remember { mutableStateOf(dpm.systemUpdatePolicy?.policyType) } Text(text = stringResource(R.string.system_update_policy), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) - RadioButtonItem(stringResource(R.string.system_update_policy_automatic),{selectedPolicy==TYPE_INSTALL_AUTOMATIC},{selectedPolicy= TYPE_INSTALL_AUTOMATIC}) - RadioButtonItem(stringResource(R.string.system_update_policy_install_windowed),{selectedPolicy==TYPE_INSTALL_WINDOWED},{selectedPolicy= TYPE_INSTALL_WINDOWED}) - RadioButtonItem(stringResource(R.string.system_update_policy_postpone),{selectedPolicy==TYPE_POSTPONE},{selectedPolicy= TYPE_POSTPONE}) - RadioButtonItem(stringResource(R.string.none),{selectedPolicy == null},{selectedPolicy=null}) - var windowedPolicyStart by remember{ mutableStateOf("") } - var windowedPolicyEnd by remember{ mutableStateOf("") } - if(selectedPolicy==2){ + RadioButtonItem( + stringResource(R.string.system_update_policy_automatic), + { selectedPolicy == TYPE_INSTALL_AUTOMATIC }, { selectedPolicy = TYPE_INSTALL_AUTOMATIC } + ) + RadioButtonItem( + stringResource(R.string.system_update_policy_install_windowed), + { selectedPolicy == TYPE_INSTALL_WINDOWED }, { selectedPolicy = TYPE_INSTALL_WINDOWED } + ) + RadioButtonItem( + stringResource(R.string.system_update_policy_postpone), + { selectedPolicy == TYPE_POSTPONE}, { selectedPolicy = TYPE_POSTPONE } + ) + RadioButtonItem(stringResource(R.string.none), { selectedPolicy == null }, { selectedPolicy = null }) + var windowedPolicyStart by remember { mutableStateOf("") } + var windowedPolicyEnd by remember { mutableStateOf("") } + if(selectedPolicy == 2) { Spacer(Modifier.padding(vertical = 3.dp)) OutlinedTextField( value = windowedPolicyStart, - label = { Text(stringResource(R.string.start_time))}, - onValueChange = {windowedPolicyStart=it}, + label = { Text(stringResource(R.string.start_time)) }, + onValueChange = { windowedPolicyStart = it }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth(0.5F) ) Spacer(Modifier.padding(horizontal = 3.dp)) OutlinedTextField( value = windowedPolicyEnd, - onValueChange = {windowedPolicyEnd=it}, - label = {Text(stringResource(R.string.end_time))}, + onValueChange = {windowedPolicyEnd = it }, + label = { Text(stringResource(R.string.end_time)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth() ) Spacer(Modifier.padding(vertical = 3.dp)) - Text(text = stringResource(R.string.minutes_in_one_day), style = bodyTextStyle) + Text(text = stringResource(R.string.minutes_in_one_day)) } Button( onClick = { val policy = - when(selectedPolicy){ + when(selectedPolicy) { TYPE_INSTALL_AUTOMATIC-> SystemUpdatePolicy.createAutomaticInstallPolicy() - TYPE_INSTALL_WINDOWED-> SystemUpdatePolicy.createWindowedInstallPolicy(windowedPolicyStart.toInt(),windowedPolicyEnd.toInt()) + TYPE_INSTALL_WINDOWED-> SystemUpdatePolicy.createWindowedInstallPolicy(windowedPolicyStart.toInt(), windowedPolicyEnd.toInt()) TYPE_POSTPONE-> SystemUpdatePolicy.createPostponeInstallPolicy() - else->null + else -> null } dpm.setSystemUpdatePolicy(receiver,policy) Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() @@ -870,61 +919,23 @@ private fun SysUpdatePolicy(){ } } } - if(VERSION.SDK_INT>=26){ + if(VERSION.SDK_INT >= 26) { Spacer(Modifier.padding(vertical = 10.dp)) val sysUpdateInfo = dpm.getPendingSystemUpdate(receiver) Column { - if(sysUpdateInfo!=null){ - Text(text = stringResource(R.string.update_received_time, Date(sysUpdateInfo.receivedTime)), style = bodyTextStyle) - val securityStateDesc = when(sysUpdateInfo.securityPatchState){ - SystemUpdateInfo.SECURITY_PATCH_STATE_UNKNOWN-> stringResource(R.string.unknown) - SystemUpdateInfo.SECURITY_PATCH_STATE_TRUE->"true" + if(sysUpdateInfo != null) { + Text(text = stringResource(R.string.update_received_time, Date(sysUpdateInfo.receivedTime))) + val securityStateDesc = when(sysUpdateInfo.securityPatchState) { + SystemUpdateInfo.SECURITY_PATCH_STATE_UNKNOWN -> stringResource(R.string.unknown) + SystemUpdateInfo.SECURITY_PATCH_STATE_TRUE -> "true" else->"false" } - Text(text = stringResource(R.string.is_security_patch, securityStateDesc), style = bodyTextStyle) + Text(text = stringResource(R.string.is_security_patch, securityStateDesc)) }else{ - Text(text = stringResource(R.string.no_system_update), style = bodyTextStyle) + Text(text = stringResource(R.string.no_system_update)) } } } Spacer(Modifier.padding(vertical = 30.dp)) - /*if(VERSION.SDK_INT>=29){ - Column(modifier = sections()){ - var resultUri by remember{mutableStateOf(otaUri)} - Text(text = "安装系统更新", style = typography.titleLarge) - Button( - onClick = { - val getUri = Intent(Intent.ACTION_GET_CONTENT) - getUri.setType("application/zip") - getUri.addCategory(Intent.CATEGORY_OPENABLE) - getOtaPackage.launch(getUri) - }, - modifier = Modifier.fillMaxWidth(), - enabled = isDeviceOwner(dpm)||isProfileOwner(dpm) - ) { - Text("选择OTA包") - } - Button( - onClick = {resultUri = otaUri}, - modifier = Modifier.fillMaxWidth(), - enabled = isDeviceOwner(dpm)||isProfileOwner(dpm) - ) { - Text("查看OTA包详情") - } - Text("URI: $resultUri") - if(installOta){ - Button( - onClick = { - val sysUpdateExecutor = Executors.newCachedThreadPool() - val sysUpdateCallback:InstallSystemUpdateCallback = InstallSystemUpdateCallback - dpm.installSystemUpdate(receiver,resultUri,sysUpdateExecutor,sysUpdateCallback) - }, - enabled = isDeviceOwner(dpm)||isProfileOwner(dpm) - ){ - Text("安装") - } - } - } - }*/ } } 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 2455e75..c02d406 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/UserManager.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/UserManager.kt @@ -16,11 +16,14 @@ import android.provider.MediaStore import android.widget.Toast import androidx.activity.ComponentActivity import androidx.compose.animation.AnimatedVisibility -import androidx.compose.foundation.* +import androidx.compose.foundation.ScrollState +import androidx.compose.foundation.focusable import androidx.compose.foundation.layout.* +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.selection.SelectionContainer +import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Button import androidx.compose.material3.MaterialTheme.typography import androidx.compose.material3.OutlinedTextField @@ -44,40 +47,25 @@ import androidx.navigation.compose.rememberNavController import com.bintianqi.owndroid.* import com.bintianqi.owndroid.R import com.bintianqi.owndroid.ui.* -import kotlinx.coroutines.delay var affiliationID = mutableSetOf() @Composable -fun UserManage(navCtrl:NavHostController) { +fun UserManage(navCtrl: NavHostController) { val localNavCtrl = rememberNavController() val backStackEntry by localNavCtrl.currentBackStackEntryAsState() val scrollState = rememberScrollState() - /*val titleMap = mapOf( - "UserInfo" to R.string.user_info, - "UserOperation" to R.string.user_operation, - "CreateUser" to R.string.create_user, - "EditUsername" to R.string.edit_username, - "ChangeUserIcon" to R.string.change_user_icon, - "UserSessionMessage" to R.string.user_session_msg, - "AffiliationID" to R.string.affiliation_id, - )*/ Scaffold( topBar = { - /*TopAppBar( - title = {Text(text = stringResource(titleMap[backStackEntry?.destination?.route]?:R.string.user_manage))}, - navigationIcon = {NavIcon{if(backStackEntry?.destination?.route=="Home"){navCtrl.navigateUp()}else{localNavCtrl.navigateUp()}}}, - colors = TopAppBarDefaults.topAppBarColors(containerColor = colorScheme.surfaceVariant) - )*/ - TopBar(backStackEntry,navCtrl,localNavCtrl){ - if(backStackEntry?.destination?.route=="Home"&&scrollState.maxValue>80){ + TopBar(backStackEntry, navCtrl, localNavCtrl) { + if(backStackEntry?.destination?.route == "Home" && scrollState.maxValue > 80) { Text( text = stringResource(R.string.user_manager), - modifier = Modifier.alpha((maxOf(scrollState.value-30,0)).toFloat()/80) + modifier = Modifier.alpha((maxOf(scrollState.value-30, 0)).toFloat() / 80) ) } } } - ){ + ) { NavHost( navController = localNavCtrl, startDestination = "Home", enterTransition = Animations.navHostEnterTransition, @@ -85,39 +73,43 @@ fun UserManage(navCtrl:NavHostController) { popEnterTransition = Animations.navHostPopEnterTransition, popExitTransition = Animations.navHostPopExitTransition, modifier = Modifier.padding(top = it.calculateTopPadding()) - ){ - composable(route = "Home"){Home(localNavCtrl,scrollState)} - composable(route = "UserInfo"){CurrentUserInfo()} - composable(route = "UserOperation"){UserOperation()} - composable(route = "CreateUser"){CreateUser()} - composable(route = "EditUsername"){Username()} - composable(route = "ChangeUserIcon"){UserIcon()} - composable(route = "UserSessionMessage"){UserSessionMessage()} - composable(route = "AffiliationID"){AffiliationID()} + ) { + composable(route = "Home") { Home(localNavCtrl, scrollState) } + composable(route = "UserInfo") { CurrentUserInfo() } + composable(route = "UserOperation") { UserOperation() } + composable(route = "CreateUser") { CreateUser() } + composable(route = "EditUsername") { Username() } + composable(route = "ChangeUserIcon") { UserIcon() } + composable(route = "UserSessionMessage") { UserSessionMessage() } + composable(route = "AffiliationID") { AffiliationID() } } } } @Composable -private fun Home(navCtrl: NavHostController,scrollState: ScrollState){ +private fun Home(navCtrl: NavHostController,scrollState: ScrollState) { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)){ - Text(text = stringResource(R.string.user_manager), style = typography.headlineLarge, modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 15.dp)) - SubPageItem(R.string.user_info,"",R.drawable.person_fill0){navCtrl.navigate("UserInfo")} - SubPageItem(R.string.user_operation,"",R.drawable.sync_alt_fill0){navCtrl.navigate("UserOperation")} - if(VERSION.SDK_INT>=24&&isDeviceOwner(dpm)){ - SubPageItem(R.string.create_user,"",R.drawable.person_add_fill0){navCtrl.navigate("CreateUser")} + Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)) { + Text( + text = stringResource(R.string.user_manager), + style = typography.headlineLarge, + modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 15.dp) + ) + SubPageItem(R.string.user_info, "", R.drawable.person_fill0) { navCtrl.navigate("UserInfo") } + SubPageItem(R.string.user_operation, "", R.drawable.sync_alt_fill0) { navCtrl.navigate("UserOperation") } + if(VERSION.SDK_INT >= 24 && isDeviceOwner(dpm)) { + SubPageItem(R.string.create_user, "", R.drawable.person_add_fill0) { navCtrl.navigate("CreateUser") } } - SubPageItem(R.string.edit_username,"",R.drawable.edit_fill0){navCtrl.navigate("EditUsername")} - if(VERSION.SDK_INT>=23&&(isDeviceOwner(dpm)||isProfileOwner(dpm))){ - SubPageItem(R.string.change_user_icon,"",R.drawable.account_circle_fill0){navCtrl.navigate("ChangeUserIcon")} + SubPageItem(R.string.edit_username, "", R.drawable.edit_fill0) { navCtrl.navigate("EditUsername") } + if(VERSION.SDK_INT >= 23 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { + SubPageItem(R.string.change_user_icon, "", R.drawable.account_circle_fill0) { navCtrl.navigate("ChangeUserIcon") } } - if(VERSION.SDK_INT>=28&&isDeviceOwner(dpm)){ - SubPageItem(R.string.user_session_msg,"",R.drawable.notifications_fill0){navCtrl.navigate("UserSessionMessage")} + if(VERSION.SDK_INT >= 28 && isDeviceOwner(dpm)) { + SubPageItem(R.string.user_session_msg, "", R.drawable.notifications_fill0) { navCtrl.navigate("UserSessionMessage") } } - if(VERSION.SDK_INT>=26&&(isDeviceOwner(dpm)||isProfileOwner(dpm))){ - SubPageItem(R.string.affiliation_id,"",R.drawable.id_card_fill0){navCtrl.navigate("AffiliationID")} + if(VERSION.SDK_INT >= 26 && (isDeviceOwner(dpm) || isProfileOwner(dpm))) { + SubPageItem(R.string.affiliation_id, "", R.drawable.id_card_fill0) { navCtrl.navigate("AffiliationID") } } Spacer(Modifier.padding(vertical = 30.dp)) LaunchedEffect(Unit) { fileUriFlow.value = Uri.parse("") } @@ -125,56 +117,56 @@ private fun Home(navCtrl: NavHostController,scrollState: ScrollState){ } @Composable -private fun CurrentUserInfo(){ +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 userManager = context.getSystemService(Context.USER_SERVICE) as UserManager - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.user_info), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) Text(stringResource(R.string.is_user_unlocked, UserManagerCompat.isUserUnlocked(context))) - if(VERSION.SDK_INT>=24){ Text(stringResource(R.string.is_support_multi_user, UserManager.supportsMultipleUsers())) } - if(VERSION.SDK_INT>=23){ Text(text = stringResource(R.string.is_system_user, userManager.isSystemUser)) } - if(VERSION.SDK_INT>=34){ Text(text = stringResource(R.string.is_admin_user, userManager.isAdminUser)) } - if(VERSION.SDK_INT>=31){ Text(text = stringResource(R.string.is_headless_system_user, UserManager.isHeadlessSystemUserMode())) } + if(VERSION.SDK_INT >= 24) { Text(stringResource(R.string.is_support_multi_user, UserManager.supportsMultipleUsers())) } + if(VERSION.SDK_INT >= 23) { Text(text = stringResource(R.string.is_system_user, userManager.isSystemUser)) } + if(VERSION.SDK_INT >= 34) { Text(text = stringResource(R.string.is_admin_user, userManager.isAdminUser)) } + if(VERSION.SDK_INT >= 31) { Text(text = stringResource(R.string.is_headless_system_user, UserManager.isHeadlessSystemUserMode())) } Spacer(Modifier.padding(vertical = 5.dp)) if (VERSION.SDK_INT >= 28) { val logoutable = dpm.isLogoutEnabled Text(text = stringResource(R.string.user_can_logout, logoutable)) - if(isDeviceOwner(dpm)|| isProfileOwner(dpm)){ + if(isDeviceOwner(dpm) || isProfileOwner(dpm)) { val ephemeralUser = dpm.isEphemeralUser(receiver) Text(text = stringResource(R.string.is_ephemeral_user, ephemeralUser)) } Text(text = stringResource(R.string.is_affiliated_user, dpm.isAffiliatedUser)) } Spacer(Modifier.padding(vertical = 5.dp)) - Text(text = stringResource(R.string.user_id_is, Binder.getCallingUid()/100000)) + Text(text = stringResource(R.string.user_id_is, Binder.getCallingUid() / 100000)) Text(text = stringResource(R.string.user_serial_number_is, userManager.getSerialNumberForUser(Process.myUserHandle()))) } } @Composable -private fun UserOperation(){ +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 focusMgr = LocalFocusManager.current - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.user_operation), style = typography.headlineLarge) - var idInput by remember{ mutableStateOf("") } - var userHandleById:UserHandle by remember{ mutableStateOf(Process.myUserHandle()) } - var useUid by remember{ mutableStateOf(false) } + var idInput by remember { mutableStateOf("") } + var userHandleById: UserHandle by remember { mutableStateOf(Process.myUserHandle()) } + var useUid by remember { mutableStateOf(false) } Spacer(Modifier.padding(vertical = 5.dp)) OutlinedTextField( value = idInput, onValueChange = { - idInput=it - if(useUid){ - if(idInput!=""&&VERSION.SDK_INT>=24){ + idInput = it + if(useUid) { + if(idInput != "" && VERSION.SDK_INT >= 24) { userHandleById = UserHandle.getUserHandleForUid(idInput.toInt()) } }else{ @@ -182,23 +174,23 @@ private fun UserOperation(){ userHandleById = userHandleBySerial ?: Process.myUserHandle() } }, - label = {Text(if(useUid){"UID"}else{ stringResource(R.string.serial_number) })}, + label = { Text(if(useUid) "UID" else stringResource(R.string.serial_number)) }, enabled = isDeviceOwner(dpm), modifier = Modifier.focusable().fillMaxWidth(), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}) + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }) ) Spacer(Modifier.padding(vertical = 3.dp)) - if(VERSION.SDK_INT>=24){ - CheckBoxItem(text = stringResource(R.string.use_uid), checked = {useUid}, operation = {idInput=""; useUid = !useUid}) + if(VERSION.SDK_INT >= 24) { + CheckBoxItem(text = stringResource(R.string.use_uid), checked = { useUid }, operation = { idInput=""; useUid = !useUid}) } Spacer(Modifier.padding(vertical = 5.dp)) - if(VERSION.SDK_INT>28){ - if(isProfileOwner(dpm)&&dpm.isAffiliatedUser){ + if(VERSION.SDK_INT > 28) { + if(isProfileOwner(dpm)&&dpm.isAffiliatedUser) { Button( onClick = { val result = dpm.logoutUser(receiver) - Toast.makeText(context, userOperationResultCode(result,context), Toast.LENGTH_SHORT).show() + Toast.makeText(context, userOperationResultCode(result, context), Toast.LENGTH_SHORT).show() }, enabled = isProfileOwner(dpm), modifier = Modifier.fillMaxWidth() @@ -207,37 +199,37 @@ private fun UserOperation(){ } } } - if(VERSION.SDK_INT>=28){ + if(VERSION.SDK_INT >= 28) { Button( onClick = { focusMgr.clearFocus() - val result = dpm.startUserInBackground(receiver,userHandleById) - Toast.makeText(context, userOperationResultCode(result,context), Toast.LENGTH_SHORT).show() + val result = dpm.startUserInBackground(receiver, userHandleById) + Toast.makeText(context, userOperationResultCode(result, context), Toast.LENGTH_SHORT).show() }, enabled = isDeviceOwner(dpm), modifier = Modifier.fillMaxWidth() - ){ + ) { Text(stringResource(R.string.start_in_background)) } } Button( onClick = { focusMgr.clearFocus() - Toast.makeText(context, if(dpm.switchUser(receiver,userHandleById)) { R.string.success }else{ R.string.fail }, Toast.LENGTH_SHORT).show() + Toast.makeText(context, if(dpm.switchUser(receiver,userHandleById)) R.string.success else R.string.fail, Toast.LENGTH_SHORT).show() }, enabled = isDeviceOwner(dpm), modifier = Modifier.fillMaxWidth() ) { Text(stringResource(R.string.user_operation_switch)) } - if(VERSION.SDK_INT>=28){ + if(VERSION.SDK_INT >= 28) { Button( onClick = { focusMgr.clearFocus() try{ val result = dpm.stopUser(receiver,userHandleById) Toast.makeText(context, userOperationResultCode(result,context), Toast.LENGTH_SHORT).show() - }catch(e:IllegalArgumentException){ + }catch(e:IllegalArgumentException) { Toast.makeText(context, R.string.fail, Toast.LENGTH_SHORT).show() } }, @@ -250,9 +242,9 @@ private fun UserOperation(){ Button( onClick = { focusMgr.clearFocus() - if(dpm.removeUser(receiver,userHandleById)){ + if(dpm.removeUser(receiver,userHandleById)) { Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() - idInput="" + idInput = "" }else{ Toast.makeText(context, R.string.fail, Toast.LENGTH_SHORT).show() } @@ -268,40 +260,52 @@ private fun UserOperation(){ @SuppressLint("NewApi") @Composable -private fun CreateUser(){ +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 focusMgr = LocalFocusManager.current - var userName by remember{ mutableStateOf("") } - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + var userName by remember { mutableStateOf("") } + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.create_user), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) OutlinedTextField( value = userName, - onValueChange = {userName=it}, - label = {Text(stringResource(R.string.username))}, + onValueChange = { userName= it }, + label = { Text(stringResource(R.string.username)) }, modifier = Modifier.focusable().fillMaxWidth(), keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}) + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }) ) Spacer(Modifier.padding(vertical = 5.dp)) - var selectedFlag by remember{ mutableIntStateOf(0) } - RadioButtonItem(stringResource(R.string.none),{selectedFlag==0},{selectedFlag=0}) - RadioButtonItem(stringResource(R.string.create_user_skip_wizard),{selectedFlag==DevicePolicyManager.SKIP_SETUP_WIZARD},{selectedFlag=DevicePolicyManager.SKIP_SETUP_WIZARD}) - if(VERSION.SDK_INT>=28){ - RadioButtonItem(stringResource(R.string.create_user_ephemeral_user),{selectedFlag==DevicePolicyManager.MAKE_USER_EPHEMERAL},{selectedFlag=DevicePolicyManager.MAKE_USER_EPHEMERAL}) - RadioButtonItem(stringResource(R.string.create_user_enable_all_system_app),{selectedFlag==DevicePolicyManager.LEAVE_ALL_SYSTEM_APPS_ENABLED},{selectedFlag=DevicePolicyManager.LEAVE_ALL_SYSTEM_APPS_ENABLED}) + var selectedFlag by remember { mutableIntStateOf(0) } + RadioButtonItem(stringResource(R.string.none), { selectedFlag == 0 }, { selectedFlag = 0 }) + RadioButtonItem( + stringResource(R.string.create_user_skip_wizard), + { selectedFlag == DevicePolicyManager.SKIP_SETUP_WIZARD }, + { selectedFlag = DevicePolicyManager.SKIP_SETUP_WIZARD } + ) + if(VERSION.SDK_INT >= 28) { + RadioButtonItem( + stringResource(R.string.create_user_ephemeral_user), + { selectedFlag == DevicePolicyManager.MAKE_USER_EPHEMERAL }, + { selectedFlag = DevicePolicyManager.MAKE_USER_EPHEMERAL } + ) + RadioButtonItem( + stringResource(R.string.create_user_enable_all_system_app), + { selectedFlag == DevicePolicyManager.LEAVE_ALL_SYSTEM_APPS_ENABLED }, + { selectedFlag = DevicePolicyManager.LEAVE_ALL_SYSTEM_APPS_ENABLED } + ) } - var newUserHandle: UserHandle? by remember{ mutableStateOf(null) } + var newUserHandle: UserHandle? by remember { mutableStateOf(null) } Spacer(Modifier.padding(vertical = 5.dp)) Button( onClick = { - newUserHandle=dpm.createAndManageUser(receiver,userName,receiver,null,selectedFlag) + newUserHandle = dpm.createAndManageUser(receiver, userName, receiver, null, selectedFlag) focusMgr.clearFocus() - Toast.makeText(context, if(newUserHandle!=null){R.string.success}else{R.string.fail}, Toast.LENGTH_SHORT).show() + Toast.makeText(context, if(newUserHandle!=null) R.string.success else R.string.fail, Toast.LENGTH_SHORT).show() }, enabled = isDeviceOwner(dpm), modifier = Modifier.fillMaxWidth() @@ -309,32 +313,30 @@ private fun CreateUser(){ Text(stringResource(R.string.create)) } Spacer(Modifier.padding(vertical = 5.dp)) - if(newUserHandle!=null){ Text(text = stringResource(R.string.serial_number_of_new_user_is, userManager.getSerialNumberForUser(newUserHandle))) } + if(newUserHandle != null) { Text(text = stringResource(R.string.serial_number_of_new_user_is, userManager.getSerialNumberForUser(newUserHandle))) } Spacer(Modifier.padding(vertical = 30.dp)) } } @SuppressLint("NewApi") @Composable -private fun AffiliationID(){ +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 focusMgr = LocalFocusManager.current - var input by remember{mutableStateOf("")} - var list by remember{mutableStateOf("")} - LaunchedEffect(Unit){ + var input by remember { mutableStateOf("") } + var list by remember { mutableStateOf("") } + LaunchedEffect(Unit) { affiliationID = dpm.getAffiliationIds(receiver) list = affiliationID.toText() } - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.affiliation_id), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) - if(list!=""){ - SelectionContainer { - Text(text = list) - } + if(list != "") { + SelectionContainer { Text(text = list) } }else{ Text(text = stringResource(R.string.none)) } @@ -342,23 +344,23 @@ private fun AffiliationID(){ OutlinedTextField( value = input, onValueChange = {input = it}, - label = {Text("ID")}, + label = { Text("ID") }, modifier = Modifier.focusable().fillMaxWidth().padding(vertical = 2.dp), keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}) + keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus() }) ) Spacer(Modifier.padding(vertical = 5.dp)) - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { Button( onClick = { affiliationID.add(input); list = affiliationID.toText() }, modifier = Modifier.fillMaxWidth(0.49F) - ){ + ) { Text(stringResource(R.string.add)) } Button( onClick = { affiliationID.remove(input); list = affiliationID.toText() }, modifier = Modifier.fillMaxWidth(0.96F) - ){ + ) { Text(stringResource(R.string.remove)) } } @@ -366,7 +368,7 @@ private fun AffiliationID(){ onClick = { if("" in affiliationID) { Toast.makeText(context, R.string.include_empty_string, Toast.LENGTH_SHORT).show() - }else if(affiliationID.isEmpty()){ + }else if(affiliationID.isEmpty()) { Toast.makeText(context, R.string.cannot_be_empty, Toast.LENGTH_SHORT).show() }else{ dpm.setAffiliationIds(receiver, affiliationID) @@ -384,41 +386,39 @@ private fun AffiliationID(){ } @Composable -private fun Username(){ +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 focusMgr = LocalFocusManager.current - var inputUsername by remember{mutableStateOf("")} - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + var inputUsername by remember { mutableStateOf("") } + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.edit_username), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) OutlinedTextField( value = inputUsername, - onValueChange = {inputUsername=it}, - label = {Text(stringResource(R.string.username))}, + onValueChange = { inputUsername= it }, + label = { Text(stringResource(R.string.username)) }, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth(), - enabled = isDeviceOwner(dpm)||isProfileOwner(dpm) + enabled = isDeviceOwner(dpm) || isProfileOwner(dpm) ) Spacer(Modifier.padding(vertical = 5.dp)) Button( onClick = { - dpm.setProfileName(receiver,inputUsername) + dpm.setProfileName(receiver, inputUsername) Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() }, - enabled = isDeviceOwner(dpm)||isProfileOwner(dpm), + enabled = isDeviceOwner(dpm) || isProfileOwner(dpm), modifier = Modifier.fillMaxWidth() ) { Text(stringResource(R.string.apply)) } Button( - onClick = { - dpm.setProfileName(receiver,null) - }, - enabled = isDeviceOwner(dpm)||isProfileOwner(dpm), + onClick = { dpm.setProfileName(receiver,null) }, + enabled = isDeviceOwner(dpm) || isProfileOwner(dpm), modifier = Modifier.fillMaxWidth() ) { Text(stringResource(R.string.reset)) @@ -428,37 +428,37 @@ private fun Username(){ @SuppressLint("NewApi") @Composable -private fun UserSessionMessage(){ +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 focusMgr = LocalFocusManager.current val getStart = dpm.getStartUserSessionMessage(receiver)?:"" val getEnd = dpm.getEndUserSessionMessage(receiver)?:"" - var start by remember{mutableStateOf(getStart.toString())} - var end by remember{mutableStateOf(getEnd.toString())} - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + var start by remember { mutableStateOf(getStart.toString()) } + var end by remember { mutableStateOf(getEnd.toString()) } + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.user_session_msg), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) OutlinedTextField( value = start, - onValueChange = {start=it}, - label = {Text(stringResource(R.string.start_user_session_msg))}, + onValueChange = { start= it }, + label = { Text(stringResource(R.string.start_user_session_msg)) }, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth(), - enabled = isDeviceOwner(dpm)||isProfileOwner(dpm) + enabled = isDeviceOwner(dpm) || isProfileOwner(dpm) ) Spacer(Modifier.padding(vertical = 2.dp)) OutlinedTextField( value = end, - onValueChange = {end=it}, - label = {Text(stringResource(R.string.end_user_session_msg))}, + onValueChange = { end= it }, + label = { Text(stringResource(R.string.end_user_session_msg)) }, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), modifier = Modifier.focusable().fillMaxWidth(), - enabled = isDeviceOwner(dpm)||isProfileOwner(dpm) + enabled = isDeviceOwner(dpm) || isProfileOwner(dpm) ) Spacer(Modifier.padding(vertical = 5.dp)) Button( @@ -467,7 +467,7 @@ private fun UserSessionMessage(){ dpm.setEndUserSessionMessage(receiver,end) Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() }, - enabled = isDeviceOwner(dpm)||isProfileOwner(dpm), + enabled = isDeviceOwner(dpm) || isProfileOwner(dpm), modifier = Modifier.fillMaxWidth() ) { Text(stringResource(R.string.apply)) @@ -478,7 +478,7 @@ private fun UserSessionMessage(){ dpm.setEndUserSessionMessage(receiver,null) Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() }, - enabled = isDeviceOwner(dpm)||isProfileOwner(dpm), + enabled = isDeviceOwner(dpm) || isProfileOwner(dpm), modifier = Modifier.fillMaxWidth() ) { Text(stringResource(R.string.reset)) @@ -489,24 +489,24 @@ private fun UserSessionMessage(){ @SuppressLint("NewApi") @Composable -private fun UserIcon(){ +private fun UserIcon() { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val receiver = ComponentName(context,Receiver::class.java) - var getContent by remember{mutableStateOf(false)} + var getContent by remember { mutableStateOf(false) } val canApply = fileUriFlow.collectAsState().value != Uri.parse("") - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){ + Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.change_user_icon), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) Text(text = stringResource(R.string.pick_a_square_image)) Spacer(Modifier.padding(vertical = 5.dp)) - CheckBoxItem(stringResource(R.string.file_picker_instead_gallery),{getContent},{getContent=!getContent}) + CheckBoxItem(stringResource(R.string.file_picker_instead_gallery), {getContent}, {getContent=!getContent}) Spacer(Modifier.padding(vertical = 5.dp)) Button( onClick = { - val intent = Intent(if(getContent){Intent.ACTION_GET_CONTENT}else{Intent.ACTION_PICK}) - if(getContent){intent.addCategory(Intent.CATEGORY_OPENABLE)} + val intent = Intent(if(getContent) Intent.ACTION_GET_CONTENT else Intent.ACTION_PICK) + if(getContent) intent.addCategory(Intent.CATEGORY_OPENABLE) intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*") getFile.launch(intent) }, @@ -517,9 +517,9 @@ private fun UserIcon(){ AnimatedVisibility(canApply) { Button( onClick = { - uriToStream(context, fileUriFlow.value){stream -> + uriToStream(context, fileUriFlow.value) {stream -> val bitmap = BitmapFactory.decodeStream(stream) - dpm.setUserIcon(receiver,bitmap) + dpm.setUserIcon(receiver, bitmap) Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() } }, @@ -532,11 +532,11 @@ private fun UserIcon(){ } private fun userOperationResultCode(result:Int, context: Context): String { - return when(result){ + return when(result) { UserManager.USER_OPERATION_SUCCESS->context.getString(R.string.success) UserManager.USER_OPERATION_ERROR_UNKNOWN-> context.getString(R.string.unknown_result) UserManager.USER_OPERATION_ERROR_MANAGED_PROFILE-> context.getString(R.string.fail_managed_profile) UserManager.USER_OPERATION_ERROR_CURRENT_USER-> context.getString(R.string.fail_current_user) - else->"未知" + else->context.getString(R.string.unknown) } } 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 0bdc8aa..fd25984 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/UserRestriction.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/UserRestriction.kt @@ -47,7 +47,7 @@ private data class Restriction( ) @Composable -fun UserRestriction(navCtrl: NavHostController){ +fun UserRestriction(navCtrl: NavHostController) { val localNavCtrl = rememberNavController() val backStackEntry by localNavCtrl.currentBackStackEntryAsState() val scrollState = rememberScrollState() @@ -70,12 +70,12 @@ fun UserRestriction(navCtrl: NavHostController){ if(backStackEntry?.destination?.route=="Home"&&scrollState.maxValue>80){ Text( text = stringResource(R.string.user_restrict), - modifier = Modifier.alpha((maxOf(scrollState.value-30,0)).toFloat()/80) + modifier = Modifier.alpha((maxOf(scrollState.value-30, 0)).toFloat() / 80) ) } } } - ){ + ) { NavHost( navController = localNavCtrl, startDestination = "Home", enterTransition = Animations.navHostEnterTransition, @@ -83,99 +83,103 @@ fun UserRestriction(navCtrl: NavHostController){ popEnterTransition = Animations.navHostPopEnterTransition, popExitTransition = Animations.navHostPopExitTransition, modifier = Modifier.padding(top = it.calculateTopPadding()) - ){ - composable(route = "Internet"){Internet()} - composable(route = "Home"){Home(localNavCtrl,scrollState)} - composable(route = "Connectivity"){Connectivity()} - composable(route = "Applications"){Application()} - composable(route = "Users"){User()} - composable(route = "Media"){Media()} - composable(route = "Other"){Other()} + ) { + composable(route = "Internet") { Internet() } + composable(route = "Home") { Home(localNavCtrl,scrollState) } + composable(route = "Connectivity") { Connectivity() } + composable(route = "Applications") { Application() } + composable(route = "Users") { User() } + composable(route = "Media") { Media() } + composable(route = "Other") { Other() } } } } @Composable -private fun Home(navCtrl:NavHostController,scrollState: ScrollState){ +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) - Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)){ - Text(text = stringResource(R.string.user_restrict), style = typography.headlineLarge, modifier = Modifier.padding(top = 8.dp, bottom = 7.dp, start = 15.dp)) + Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)) { + Text( + text = stringResource(R.string.user_restrict), + style = typography.headlineLarge, + 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(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)))) { Text(text = stringResource(R.string.some_features_invalid_in_work_profile), modifier = Modifier.padding(start = 15.dp)) } Spacer(Modifier.padding(vertical = 2.dp)) - SubPageItem(R.string.network_internet,"",R.drawable.wifi_fill0){navCtrl.navigate("Internet")} - SubPageItem(R.string.more_connectivity,"",R.drawable.devices_other_fill0){navCtrl.navigate("Connectivity")} - SubPageItem(R.string.applications,"",R.drawable.apps_fill0){navCtrl.navigate("Applications")} - SubPageItem(R.string.users,"",R.drawable.account_circle_fill0){navCtrl.navigate("Users")} - SubPageItem(R.string.media,"",R.drawable.volume_up_fill0){navCtrl.navigate("Media")} - SubPageItem(R.string.other,"",R.drawable.more_horiz_fill0){navCtrl.navigate("Other")} + SubPageItem(R.string.network_internet, "", R.drawable.wifi_fill0) { navCtrl.navigate("Internet") } + SubPageItem(R.string.more_connectivity, "", R.drawable.devices_other_fill0) { navCtrl.navigate("Connectivity") } + SubPageItem(R.string.applications, "", R.drawable.apps_fill0) { navCtrl.navigate("Applications") } + SubPageItem(R.string.users, "", R.drawable.account_circle_fill0) { navCtrl.navigate("Users") } + SubPageItem(R.string.media, "", R.drawable.volume_up_fill0) { navCtrl.navigate("Media") } + SubPageItem(R.string.other, "", R.drawable.more_horiz_fill0) { navCtrl.navigate("Other") } Spacer(Modifier.padding(vertical = 30.dp)) } } @SuppressLint("NewApi") @Composable -private fun Internet(){ - Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())){ - for(internetItem in RestrictionData.internet()){ - UserRestrictionItem(internetItem.restriction,internetItem.name,internetItem.desc,internetItem.ico) +private fun Internet() { + Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) { + for(internetItem in RestrictionData.internet()) { + UserRestrictionItem(internetItem.restriction, internetItem.name, internetItem.desc, internetItem.ico) } Spacer(Modifier.padding(vertical = 30.dp)) } } @Composable -private fun Connectivity(){ - Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())){ - for(connectivityItem in RestrictionData.connectivity()){ - UserRestrictionItem(connectivityItem.restriction,connectivityItem.name,connectivityItem.desc,connectivityItem.ico) +private fun Connectivity() { + Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) { + for(connectivityItem in RestrictionData.connectivity()) { + UserRestrictionItem(connectivityItem.restriction, connectivityItem.name, connectivityItem.desc, connectivityItem.ico) } Spacer(Modifier.padding(vertical = 30.dp)) } } @Composable -fun Application(){ +fun Application() { val context = LocalContext.current - Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())){ - for(applicationItem in RestrictionData.application(context)){ - UserRestrictionItem(applicationItem.restriction,applicationItem.name,applicationItem.desc,applicationItem.ico) + Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) { + for(applicationItem in RestrictionData.application(context)) { + UserRestrictionItem(applicationItem.restriction, applicationItem.name, applicationItem.desc, applicationItem.ico) } Spacer(Modifier.padding(vertical = 30.dp)) } } @Composable -private fun User(){ - Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())){ - for(userItem in RestrictionData.user()){ - UserRestrictionItem(userItem.restriction,userItem.name,userItem.desc,userItem.ico) +private fun User() { + Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) { + for(userItem in RestrictionData.user()) { + UserRestrictionItem(userItem.restriction, userItem.name, userItem.desc, userItem.ico) } Spacer(Modifier.padding(vertical = 30.dp)) } } @Composable -private fun Media(){ - Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())){ - for(mediaItem in RestrictionData.media()){ - UserRestrictionItem(mediaItem.restriction,mediaItem.name,mediaItem.desc,mediaItem.ico) +private fun Media() { + Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) { + for(mediaItem in RestrictionData.media()) { + UserRestrictionItem(mediaItem.restriction, mediaItem.name, mediaItem.desc, mediaItem.ico) } Spacer(Modifier.padding(vertical = 30.dp)) } } @Composable -private fun Other(){ +private fun Other() { val context = LocalContext.current - Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())){ - for(otherItem in RestrictionData.other(context)){ - UserRestrictionItem(otherItem.restriction,otherItem.name,otherItem.desc,otherItem.ico) + Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) { + for(otherItem in RestrictionData.other(context)) { + UserRestrictionItem(otherItem.restriction, otherItem.name, otherItem.desc, otherItem.ico) } Spacer(Modifier.padding(vertical = 30.dp)) } @@ -187,22 +191,22 @@ private fun UserRestrictionItem( restriction:String, itemName:Int, restrictionDescription:String, leadIcon:Int -){ +) { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager - val receiver = ComponentName(context,Receiver::class.java) + val receiver = ComponentName(context, Receiver::class.java) SwitchItem( itemName,restrictionDescription,leadIcon, - { if(isDeviceOwner(dpm)||isProfileOwner(dpm)){ dpm.getUserRestrictions(receiver).getBoolean(restriction) }else{ false } }, + { if(isDeviceOwner(dpm)||isProfileOwner(dpm)) { dpm.getUserRestrictions(receiver).getBoolean(restriction) }else{ false } }, { try{ - if(it){ + if(it) { dpm.addUserRestriction(receiver,restriction) }else{ dpm.clearUserRestriction(receiver,restriction) } - }catch(e:SecurityException){ - if(isProfileOwner(dpm)){ + }catch(e:SecurityException) { + if(isProfileOwner(dpm)) { Toast.makeText(context, R.string.require_device_owner, Toast.LENGTH_SHORT).show() } } @@ -212,105 +216,105 @@ private fun UserRestrictionItem( } private object RestrictionData{ - fun internet():List{ + fun internet(): List{ val list:MutableList = mutableListOf() - list += Restriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, R.string.config_mobile_network,"",R.drawable.signal_cellular_alt_fill0) - list += Restriction(UserManager.DISALLOW_CONFIG_WIFI,R.string.config_wifi,"",R.drawable.wifi_fill0) - if(VERSION.SDK_INT>=24){list += Restriction(UserManager.DISALLOW_DATA_ROAMING,R.string.data_roaming,"",R.drawable.network_cell_fill0)} - if(VERSION.SDK_INT>=34){ - list += Restriction(UserManager.DISALLOW_CELLULAR_2G,R.string.cellular_2g,"",R.drawable.network_cell_fill0) - list += Restriction(UserManager.DISALLOW_ULTRA_WIDEBAND_RADIO,R.string.ultra_wideband_radio,"",R.drawable.wifi_tethering_fill0) + list += Restriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, R.string.config_mobile_network, "", R.drawable.signal_cellular_alt_fill0) + list += Restriction(UserManager.DISALLOW_CONFIG_WIFI, R.string.config_wifi, "", R.drawable.wifi_fill0) + if(VERSION.SDK_INT>=24) { list += Restriction(UserManager.DISALLOW_DATA_ROAMING, R.string.data_roaming, "", R.drawable.network_cell_fill0) } + if(VERSION.SDK_INT>=34) { + list += Restriction(UserManager.DISALLOW_CELLULAR_2G, R.string.cellular_2g, "", R.drawable.network_cell_fill0) + list += Restriction(UserManager.DISALLOW_ULTRA_WIDEBAND_RADIO, R.string.ultra_wideband_radio, "", R.drawable.wifi_tethering_fill0) } - if(VERSION.SDK_INT>=33){ - list += Restriction(UserManager.DISALLOW_ADD_WIFI_CONFIG,R.string.add_wifi_conf,"",R.drawable.wifi_fill0) - list += Restriction(UserManager.DISALLOW_CHANGE_WIFI_STATE,R.string.change_wifi_state,"",R.drawable.wifi_fill0) - list += Restriction(UserManager.DISALLOW_WIFI_DIRECT,R.string.wifi_direct,"",R.drawable.wifi_tethering_fill0) - list += Restriction(UserManager.DISALLOW_WIFI_TETHERING,R.string.wifi_tethering,"",R.drawable.wifi_tethering_fill0) - list += Restriction(UserManager.DISALLOW_SHARING_ADMIN_CONFIGURED_WIFI,R.string.share_admin_wifi,"",R.drawable.share_fill0) + if(VERSION.SDK_INT>=33) { + list += Restriction(UserManager.DISALLOW_ADD_WIFI_CONFIG, R.string.add_wifi_conf, "", R.drawable.wifi_fill0) + list += Restriction(UserManager.DISALLOW_CHANGE_WIFI_STATE, R.string.change_wifi_state, "", R.drawable.wifi_fill0) + list += Restriction(UserManager.DISALLOW_WIFI_DIRECT, R.string.wifi_direct, "", R.drawable.wifi_tethering_fill0) + list += Restriction(UserManager.DISALLOW_WIFI_TETHERING, R.string.wifi_tethering, "", R.drawable.wifi_tethering_fill0) + list += Restriction(UserManager.DISALLOW_SHARING_ADMIN_CONFIGURED_WIFI, R.string.share_admin_wifi, "", R.drawable.share_fill0) } - if(VERSION.SDK_INT>=23){ list += Restriction(UserManager.DISALLOW_NETWORK_RESET,R.string.network_reset,"",R.drawable.reset_wrench_fill0) } - list += Restriction(UserManager.DISALLOW_CONFIG_TETHERING,R.string.config_tethering,"",R.drawable.wifi_tethering_fill0) - list += Restriction(UserManager.DISALLOW_CONFIG_VPN,R.string.config_vpn,"",R.drawable.vpn_key_fill0) - if(VERSION.SDK_INT>=29){list += Restriction(UserManager.DISALLOW_CONFIG_PRIVATE_DNS,R.string.config_private_dns,"",R.drawable.dns_fill0)} - if(VERSION.SDK_INT>=28){list += Restriction(UserManager.DISALLOW_AIRPLANE_MODE,R.string.airplane_mode,"",R.drawable.airplanemode_active_fill0)} - list += Restriction(UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,R.string.config_cell_broadcasts,"",R.drawable.cell_tower_fill0) - list += Restriction(UserManager.DISALLOW_SMS,R.string.sms,"",R.drawable.sms_fill0) - list += Restriction(UserManager.DISALLOW_OUTGOING_CALLS,R.string.outgoing_calls,"",R.drawable.phone_forwarded_fill0) + if(VERSION.SDK_INT>=23) { list += Restriction(UserManager.DISALLOW_NETWORK_RESET, R.string.network_reset, "", R.drawable.reset_wrench_fill0) } + list += Restriction(UserManager.DISALLOW_CONFIG_TETHERING, R.string.config_tethering, "", R.drawable.wifi_tethering_fill0) + list += Restriction(UserManager.DISALLOW_CONFIG_VPN, R.string.config_vpn, "", R.drawable.vpn_key_fill0) + if(VERSION.SDK_INT>=29) { list += Restriction(UserManager.DISALLOW_CONFIG_PRIVATE_DNS, R.string.config_private_dns, "", R.drawable.dns_fill0) } + if(VERSION.SDK_INT>=28) { list += Restriction(UserManager.DISALLOW_AIRPLANE_MODE, R.string.airplane_mode, "", R.drawable.airplanemode_active_fill0) } + list += Restriction(UserManager.DISALLOW_CONFIG_CELL_BROADCASTS, R.string.config_cell_broadcasts, "", R.drawable.cell_tower_fill0) + list += Restriction(UserManager.DISALLOW_SMS, R.string.sms, "", R.drawable.sms_fill0) + list += Restriction(UserManager.DISALLOW_OUTGOING_CALLS, R.string.outgoing_calls, "", R.drawable.phone_forwarded_fill0) return list } - fun connectivity():List{ + fun connectivity(): List{ val list:MutableList = mutableListOf() - if(VERSION.SDK_INT>=26){ - list += Restriction(UserManager.DISALLOW_BLUETOOTH,R.string.bluetooth,"",R.drawable.bluetooth_fill0) - list += Restriction(UserManager.DISALLOW_BLUETOOTH_SHARING,R.string.bt_share,"",R.drawable.bluetooth_searching_fill0) + if(VERSION.SDK_INT>=26) { + list += Restriction(UserManager.DISALLOW_BLUETOOTH, R.string.bluetooth, "", R.drawable.bluetooth_fill0) + list += Restriction(UserManager.DISALLOW_BLUETOOTH_SHARING, R.string.bt_share, "", R.drawable.bluetooth_searching_fill0) } - list += Restriction(UserManager.DISALLOW_SHARE_LOCATION,R.string.share_location,"",R.drawable.location_on_fill0) - if(VERSION.SDK_INT>=28){list += Restriction(UserManager.DISALLOW_CONFIG_LOCATION,R.string.config_location,"",R.drawable.location_on_fill0)} - if(VERSION.SDK_INT>=22){list += Restriction(UserManager.DISALLOW_OUTGOING_BEAM,R.string.outgoing_beam,"",R.drawable.nfc_fill0)} - list += Restriction(UserManager.DISALLOW_USB_FILE_TRANSFER,R.string.usb_file_transfer,"",R.drawable.usb_fill0) - list += Restriction(UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,R.string.mount_physical_media, "", R.drawable.sd_card_fill0) - if(VERSION.SDK_INT>=28){list += Restriction(UserManager.DISALLOW_PRINTING,R.string.printing,"",R.drawable.print_fill0)} + list += Restriction(UserManager.DISALLOW_SHARE_LOCATION, R.string.share_location, "", R.drawable.location_on_fill0) + if(VERSION.SDK_INT>=28) { list += Restriction(UserManager.DISALLOW_CONFIG_LOCATION, R.string.config_location, "", R.drawable.location_on_fill0) } + if(VERSION.SDK_INT>=22) { list += Restriction(UserManager.DISALLOW_OUTGOING_BEAM, R.string.outgoing_beam, "", R.drawable.nfc_fill0) } + list += Restriction(UserManager.DISALLOW_USB_FILE_TRANSFER, R.string.usb_file_transfer, "", R.drawable.usb_fill0) + list += Restriction(UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA, R.string.mount_physical_media, "", R.drawable.sd_card_fill0) + if(VERSION.SDK_INT>=28) { list += Restriction(UserManager.DISALLOW_PRINTING, R.string.printing, "", R.drawable.print_fill0) } return list } - fun application(context: Context):List{ + fun application(context: Context): List{ val list:MutableList = mutableListOf() - list += Restriction(UserManager.DISALLOW_INSTALL_APPS,R.string.install_app,"",R.drawable.android_fill0) - if(VERSION.SDK_INT>=29){list += Restriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY,R.string.install_unknown_src_globally,"",R.drawable.android_fill0)} - list += Restriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,R.string.inst_unknown_src,"",R.drawable.android_fill0) - list += Restriction(UserManager.DISALLOW_UNINSTALL_APPS,R.string.uninstall_app,"",R.drawable.delete_fill0) - list += Restriction(UserManager.DISALLOW_APPS_CONTROL,R.string.apps_ctrl, context.getString(R.string.apps_control_desc),R.drawable.apps_fill0) - if(VERSION.SDK_INT>=34){ list += Restriction(UserManager.DISALLOW_CONFIG_DEFAULT_APPS,R.string.config_default_apps,"",R.drawable.apps_fill0) } + list += Restriction(UserManager.DISALLOW_INSTALL_APPS, R.string.install_app, "", R.drawable.android_fill0) + if(VERSION.SDK_INT>=29) { list += Restriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, R.string.install_unknown_src_globally, "", R.drawable.android_fill0) } + list += Restriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, R.string.inst_unknown_src, "", R.drawable.android_fill0) + list += Restriction(UserManager.DISALLOW_UNINSTALL_APPS, R.string.uninstall_app, "", R.drawable.delete_fill0) + list += Restriction(UserManager.DISALLOW_APPS_CONTROL, R.string.apps_ctrl, context.getString(R.string.apps_control_desc), R.drawable.apps_fill0) + if(VERSION.SDK_INT>=34) { list += Restriction(UserManager.DISALLOW_CONFIG_DEFAULT_APPS, R.string.config_default_apps, "", R.drawable.apps_fill0) } return list } - fun media():List{ + fun media(): List{ val list:MutableList = mutableListOf() - if(VERSION.SDK_INT>=28){ - list += Restriction(UserManager.DISALLOW_CONFIG_BRIGHTNESS,R.string.config_brightness,"",R.drawable.brightness_5_fill0) - list += Restriction(UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT,R.string.config_scr_timeout,"",R.drawable.screen_lock_portrait_fill0) - list += Restriction(UserManager.DISALLOW_AMBIENT_DISPLAY,R.string.ambient_display,"",R.drawable.brightness_5_fill0) + if(VERSION.SDK_INT>=28) { + list += Restriction(UserManager.DISALLOW_CONFIG_BRIGHTNESS, R.string.config_brightness, "", R.drawable.brightness_5_fill0) + list += Restriction(UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT, R.string.config_scr_timeout, "", R.drawable.screen_lock_portrait_fill0) + list += Restriction(UserManager.DISALLOW_AMBIENT_DISPLAY, R.string.ambient_display, "", R.drawable.brightness_5_fill0) } - list += Restriction(UserManager.DISALLOW_ADJUST_VOLUME,R.string.adjust_volume,"",R.drawable.volume_up_fill0) - list += Restriction(UserManager.DISALLOW_UNMUTE_MICROPHONE,R.string.unmute_microphone,"",R.drawable.mic_fill0) - if(VERSION.SDK_INT>=31){ - list += Restriction(UserManager.DISALLOW_CAMERA_TOGGLE,R.string.camera_toggle,"",R.drawable.cameraswitch_fill0) - list += Restriction(UserManager.DISALLOW_MICROPHONE_TOGGLE,R.string.microphone_toggle,"",R.drawable.mic_fill0) + list += Restriction(UserManager.DISALLOW_ADJUST_VOLUME, R.string.adjust_volume, "", R.drawable.volume_up_fill0) + list += Restriction(UserManager.DISALLOW_UNMUTE_MICROPHONE, R.string.unmute_microphone, "", R.drawable.mic_fill0) + if(VERSION.SDK_INT>=31) { + list += Restriction(UserManager.DISALLOW_CAMERA_TOGGLE, R.string.camera_toggle, "", R.drawable.cameraswitch_fill0) + list += Restriction(UserManager.DISALLOW_MICROPHONE_TOGGLE, R.string.microphone_toggle, "", R.drawable.mic_fill0) } return list } - fun user():List{ + fun user(): List{ val list:MutableList = mutableListOf() - list += Restriction(UserManager.DISALLOW_ADD_USER,R.string.add_user,"",R.drawable.account_circle_fill0) - list += Restriction(UserManager.DISALLOW_REMOVE_USER,R.string.remove_user,"",R.drawable.account_circle_fill0) - if(VERSION.SDK_INT>=28){list += Restriction(UserManager.DISALLOW_USER_SWITCH,R.string.switch_user,"",R.drawable.account_circle_fill0)} - if(VERSION.SDK_INT>=24){list += Restriction(UserManager.DISALLOW_SET_USER_ICON,R.string.set_user_icon,"",R.drawable.account_circle_fill0)} - list += Restriction(UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE,R.string.cross_profile_copy, "",R.drawable.content_paste_fill0) - if(VERSION.SDK_INT>=28){ - list += Restriction(UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE,R.string.share_into_managed_profile,"",R.drawable.share_fill0) - list += Restriction(UserManager.DISALLOW_UNIFIED_PASSWORD,R.string.unified_pwd,"",R.drawable.work_fill0) + list += Restriction(UserManager.DISALLOW_ADD_USER, R.string.add_user, "", R.drawable.account_circle_fill0) + list += Restriction(UserManager.DISALLOW_REMOVE_USER, R.string.remove_user, "", R.drawable.account_circle_fill0) + if(VERSION.SDK_INT>=28) { list += Restriction(UserManager.DISALLOW_USER_SWITCH, R.string.switch_user, "", R.drawable.account_circle_fill0) } + if(VERSION.SDK_INT>=24) { list += Restriction(UserManager.DISALLOW_SET_USER_ICON, R.string.set_user_icon, "", R.drawable.account_circle_fill0) } + list += Restriction(UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE, R.string.cross_profile_copy, "", R.drawable.content_paste_fill0) + if(VERSION.SDK_INT>=28) { + list += Restriction(UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE, R.string.share_into_managed_profile, "", R.drawable.share_fill0) + list += Restriction(UserManager.DISALLOW_UNIFIED_PASSWORD, R.string.unified_pwd, "", R.drawable.work_fill0) } return list } - fun other(context: Context):List{ + fun other(context: Context): List{ val list:MutableList = mutableListOf() - if(VERSION.SDK_INT>=26){ list += Restriction(UserManager.DISALLOW_AUTOFILL,R.string.autofill, "",R.drawable.password_fill0) } - list += Restriction(UserManager.DISALLOW_CONFIG_CREDENTIALS,R.string.config_credentials,"",R.drawable.android_fill0) - if(VERSION.SDK_INT>=29){ - list += Restriction(UserManager.DISALLOW_CONTENT_CAPTURE,R.string.content_capture,"",R.drawable.screenshot_fill0) - list += Restriction(UserManager.DISALLOW_CONTENT_SUGGESTIONS,R.string.content_suggestions,"",R.drawable.sms_fill0) + if(VERSION.SDK_INT>=26) { list += Restriction(UserManager.DISALLOW_AUTOFILL, R.string.autofill, "", R.drawable.password_fill0) } + list += Restriction(UserManager.DISALLOW_CONFIG_CREDENTIALS, R.string.config_credentials, "", R.drawable.android_fill0) + if(VERSION.SDK_INT>=29) { + list += Restriction(UserManager.DISALLOW_CONTENT_CAPTURE, R.string.content_capture, "", R.drawable.screenshot_fill0) + list += Restriction(UserManager.DISALLOW_CONTENT_SUGGESTIONS, R.string.content_suggestions, "", R.drawable.sms_fill0) } - list += Restriction(UserManager.DISALLOW_CREATE_WINDOWS,R.string.create_windows, context.getString(R.string.create_windows_desc),R.drawable.web_asset) - if(VERSION.SDK_INT>=24){list += Restriction(UserManager.DISALLOW_SET_WALLPAPER,R.string.set_wallpaper,"",R.drawable.wallpaper_fill0)} - if(VERSION.SDK_INT>=34){ list += Restriction(UserManager.DISALLOW_GRANT_ADMIN,R.string.grant_admin,"",R.drawable.security_fill0) } - if(VERSION.SDK_INT>=23){ list += Restriction(UserManager.DISALLOW_FUN,R.string.`fun`, context.getString(R.string.fun_desc),R.drawable.stadia_controller_fill0) } - list += Restriction(UserManager.DISALLOW_MODIFY_ACCOUNTS,R.string.modify_accounts,"",R.drawable.manage_accounts_fill0) - if(VERSION.SDK_INT>=28){ - list += Restriction(UserManager.DISALLOW_CONFIG_LOCALE,R.string.config_locale,"",R.drawable.language_fill0) - list += Restriction(UserManager.DISALLOW_CONFIG_DATE_TIME,R.string.config_date_time,"",R.drawable.schedule_fill0) + list += Restriction(UserManager.DISALLOW_CREATE_WINDOWS, R.string.create_windows, context.getString(R.string.create_windows_desc), R.drawable.web_asset) + if(VERSION.SDK_INT>=24) { list += Restriction(UserManager.DISALLOW_SET_WALLPAPER, R.string.set_wallpaper, "", R.drawable.wallpaper_fill0) } + if(VERSION.SDK_INT>=34) { list += Restriction(UserManager.DISALLOW_GRANT_ADMIN, R.string.grant_admin, "", R.drawable.security_fill0) } + if(VERSION.SDK_INT>=23) { list += Restriction(UserManager.DISALLOW_FUN, R.string.`fun`, context.getString(R.string.fun_desc), R.drawable.stadia_controller_fill0) } + list += Restriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, R.string.modify_accounts, "", R.drawable.manage_accounts_fill0) + if(VERSION.SDK_INT>=28) { + list += Restriction(UserManager.DISALLOW_CONFIG_LOCALE, R.string.config_locale, "", R.drawable.language_fill0) + list += Restriction(UserManager.DISALLOW_CONFIG_DATE_TIME, R.string.config_date_time, "", R.drawable.schedule_fill0) } - if(VERSION.SDK_INT>=28){list += Restriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,R.string.sys_err_dialog,"",R.drawable.warning_fill0)} - list += Restriction(UserManager.DISALLOW_FACTORY_RESET,R.string.factory_reset,"",R.drawable.android_fill0) - if(VERSION.SDK_INT>=23){ list += Restriction(UserManager.DISALLOW_SAFE_BOOT,R.string.safe_boot,"",R.drawable.security_fill0) } - list += Restriction(UserManager.DISALLOW_DEBUGGING_FEATURES,R.string.debug_features,"",R.drawable.adb_fill0) + if(VERSION.SDK_INT>=28) { list += Restriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS, R.string.sys_err_dialog, "", R.drawable.warning_fill0) } + list += Restriction(UserManager.DISALLOW_FACTORY_RESET, R.string.factory_reset, "", R.drawable.android_fill0) + if(VERSION.SDK_INT>=23) { list += Restriction(UserManager.DISALLOW_SAFE_BOOT, R.string.safe_boot, "", R.drawable.security_fill0) } + list += Restriction(UserManager.DISALLOW_DEBUGGING_FEATURES, R.string.debug_features, "", R.drawable.adb_fill0) return list } } diff --git a/app/src/main/java/com/bintianqi/owndroid/ui/Animations.kt b/app/src/main/java/com/bintianqi/owndroid/ui/Animations.kt index 19c9e4a..ba79fb1 100644 --- a/app/src/main/java/com/bintianqi/owndroid/ui/Animations.kt +++ b/app/src/main/java/com/bintianqi/owndroid/ui/Animations.kt @@ -5,7 +5,7 @@ import androidx.compose.animation.core.* import androidx.compose.ui.unit.IntOffset import androidx.navigation.NavBackStackEntry -object Animations{ +object Animations { private const val INITIAL_OFFSET_VALUE = 96 private const val TARGET_OFFSET_VALUE = 96 @@ -20,7 +20,7 @@ object Animations{ slideIntoContainer( animationSpec = tween, towards = AnimatedContentTransitionScope.SlideDirection.End, - initialOffset = {INITIAL_OFFSET_VALUE} + initialOffset = { INITIAL_OFFSET_VALUE } ) } @@ -29,7 +29,7 @@ object Animations{ slideOutOfContainer( animationSpec = tween, towards = AnimatedContentTransitionScope.SlideDirection.Start, - targetOffset = {-TARGET_OFFSET_VALUE} + targetOffset = { -TARGET_OFFSET_VALUE } ) } @@ -38,7 +38,7 @@ object Animations{ slideIntoContainer( animationSpec = tween, towards = AnimatedContentTransitionScope.SlideDirection.End, - initialOffset = {-INITIAL_OFFSET_VALUE} + initialOffset = { -INITIAL_OFFSET_VALUE } ) } @@ -47,7 +47,7 @@ object Animations{ slideOutOfContainer( animationSpec = tween, towards = AnimatedContentTransitionScope.SlideDirection.Start, - targetOffset = {TARGET_OFFSET_VALUE} + targetOffset = { TARGET_OFFSET_VALUE } ) } diff --git a/app/src/main/java/com/bintianqi/owndroid/ui/Components.kt b/app/src/main/java/com/bintianqi/owndroid/ui/Components.kt index 6579270..d9268f5 100644 --- a/app/src/main/java/com/bintianqi/owndroid/ui/Components.kt +++ b/app/src/main/java/com/bintianqi/owndroid/ui/Components.kt @@ -33,25 +33,25 @@ fun SubPageItem( desc:String, @DrawableRes icon: Int? = null, operation: () -> Unit -){ +) { Row( modifier = Modifier.fillMaxWidth().clickable(onClick = operation).padding(vertical = 15.dp), verticalAlignment = Alignment.CenterVertically - ){ + ) { Spacer(Modifier.padding(start = 30.dp)) - if(icon!=null){ + if(icon!=null) { Icon(painter = painterResource(icon), contentDescription = stringResource(title), modifier = Modifier.padding(top = 1.dp)) Spacer(Modifier.padding(start = 15.dp)) } Column { - Text(text = stringResource(title), style = typography.titleLarge, modifier = Modifier.padding(bottom = if(zhCN){2}else{0}.dp)) - if(desc!=""){Text(text = desc, color = colorScheme.onBackground.copy(alpha = 0.8F))} + Text(text = stringResource(title), style = typography.titleLarge, modifier = Modifier.padding(bottom = if(zhCN) { 2 } else { 0 }.dp)) + if(desc!="") { Text(text = desc, color = colorScheme.onBackground.copy(alpha = 0.8F)) } } } } @Composable -fun NavIcon(operation: () -> Unit){ +fun NavIcon(operation: () -> Unit) { Icon( painter = painterResource(R.drawable.arrow_back_fill0), contentDescription = "Back arrow", @@ -64,9 +64,13 @@ fun NavIcon(operation: () -> Unit){ } @Composable -fun Information(content: @Composable ()->Unit){ - Column(modifier = Modifier.fillMaxWidth().padding(start = 5.dp)){ - Icon(painter = painterResource(R.drawable.info_fill0),contentDescription = "info", tint = colorScheme.onBackground.copy(alpha = 0.8F)) +fun Information(content: @Composable ()->Unit) { + Column(modifier = Modifier.fillMaxWidth().padding(start = 5.dp)) { + Icon( + painter = painterResource(R.drawable.info_fill0), + contentDescription = "info", + tint = colorScheme.onBackground.copy(alpha = 0.8F) + ) Spacer(Modifier.padding(vertical = 1.dp)) Row { Spacer(Modifier.padding(horizontal = 1.dp)) @@ -77,28 +81,28 @@ fun Information(content: @Composable ()->Unit){ @Composable fun RadioButtonItem( - text:String, - selected:()->Boolean, - operation:()->Unit, + text: String, + selected: ()->Boolean, + operation: ()->Unit, textColor: Color = colorScheme.onBackground -){ +) { Row(verticalAlignment = Alignment.CenterVertically,modifier = Modifier .fillMaxWidth() .clip(RoundedCornerShape(25)) .clickable(onClick = operation) ) { RadioButton(selected = selected(), onClick = operation) - Text(text = text, color = textColor, modifier = Modifier.padding(bottom = if(zhCN){2}else{0}.dp)) + Text(text = text, color = textColor, modifier = Modifier.padding(bottom = if(zhCN) { 2 } else { 0 }.dp)) } } @Composable fun CheckBoxItem( - text:String, - checked:()->Boolean, - operation:()->Unit, - textColor:Color = colorScheme.onBackground -){ + text: String, + checked: ()->Boolean, + operation: ()->Unit, + textColor: Color = colorScheme.onBackground +) { Row(verticalAlignment = Alignment.CenterVertically,modifier = Modifier .fillMaxWidth() .clip(RoundedCornerShape(25)) @@ -106,9 +110,9 @@ fun CheckBoxItem( ) { Checkbox( checked = checked(), - onCheckedChange = {operation()} + onCheckedChange = { operation() } ) - Text(text = text, color = textColor, modifier = Modifier.padding(bottom = if(zhCN){2}else{0}.dp)) + Text(text = text, color = textColor, modifier = Modifier.padding(bottom = if(zhCN) { 2 } else { 0 }.dp)) } } @@ -119,36 +123,36 @@ fun SwitchItem( @DrawableRes icon: Int?, getState: ()->Boolean, onCheckedChange: (Boolean)->Unit, - enable:Boolean = true, + enable: Boolean = true, onClickBlank: (() -> Unit)? = null -){ - var checked by remember{mutableStateOf(false)} +) { + var checked by remember { mutableStateOf(false) } checked = getState() Box( modifier = Modifier .fillMaxWidth() - .clickable(enabled = onClickBlank!=null, onClick = onClickBlank?:{}) + .clickable(enabled = onClickBlank != null, onClick = onClickBlank?:{}) .padding(vertical = 5.dp) ) { Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier.align(Alignment.CenterStart) - ){ + ) { Spacer(Modifier.padding(start = 30.dp)) - if(icon!=null){ + if(icon!=null) { Icon(painter = painterResource(icon),contentDescription = null) Spacer(Modifier.padding(start = 15.dp)) } - Column(modifier = Modifier.padding(end = 60.dp)){ + Column(modifier = Modifier.padding(end = 60.dp)) { Text(text = stringResource(title), style = typography.titleLarge) - if(desc!=""){ + if(desc!="") { Text(text = desc, color = colorScheme.onBackground.copy(alpha = 0.8F)) } - if(zhCN){ Spacer(Modifier.padding(vertical = 1.dp)) } + if(zhCN) { Spacer(Modifier.padding(vertical = 1.dp)) } } } Switch( - checked = checked, onCheckedChange = {onCheckedChange(it);checked=getState()}, + checked = checked, onCheckedChange = {onCheckedChange(it);checked=getState() }, modifier = Modifier.align(Alignment.CenterEnd).padding(end = 12.dp), enabled = enable ) } @@ -157,17 +161,16 @@ fun SwitchItem( @OptIn(ExperimentalMaterial3Api::class) @Composable fun TopBar( - backStackEntry:NavBackStackEntry?, - navCtrl:NavHostController, - localNavCtrl:NavHostController, - title:@Composable ()->Unit = {} -){ + backStackEntry: NavBackStackEntry?, + navCtrl: NavHostController, + localNavCtrl: NavHostController, + title: @Composable ()->Unit = {} +) { TopAppBar( - //Text(text = stringResource(titleMap[backStackEntry?.destination?.route]?:R.string.user_restrict)) title = title, navigationIcon = { NavIcon{ - if(backStackEntry?.destination?.route=="Home"){ navCtrl.navigateUp() }else{ localNavCtrl.navigateUp() } + if(backStackEntry?.destination?.route == "Home") { navCtrl.navigateUp() } else { localNavCtrl.navigateUp() } } }, colors = TopAppBarDefaults.topAppBarColors(containerColor = colorScheme.background) @@ -175,26 +178,26 @@ fun TopBar( } @Composable -fun CopyTextButton(@StringRes label: Int, content: String){ +fun CopyTextButton(@StringRes label: Int, content: String) { val context = LocalContext.current - var ok by remember{mutableStateOf(false)} + var ok by remember{ mutableStateOf(false) } val scope = rememberCoroutineScope() Button( onClick = { - if(!ok){ - scope.launch{ - if(writeClipBoard(context,content)){ ok = true; delay(2000); ok = false } + if(!ok) { + scope.launch { + if(writeClipBoard(context,content)) { ok = true; delay(2000); ok = false } else{ Toast.makeText(context, R.string.fail, Toast.LENGTH_SHORT).show() } } } } - ){ + ) { Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier.animateContentSize() - ){ - Icon(painter = painterResource(if(ok){R.drawable.check_fill0}else{R.drawable.content_copy_fill0}),contentDescription = null) + ) { + Icon(painter = painterResource(if(ok) R.drawable.check_fill0 else R.drawable.content_copy_fill0), contentDescription = null) Spacer(modifier = Modifier.padding(horizontal = 2.dp)) - Text(text = stringResource(if(ok){R.string.success}else{label})) + Text(text = stringResource(if(ok) R.string.success else label)) } } } diff --git a/app/src/main/java/com/bintianqi/owndroid/ui/theme/Theme.kt b/app/src/main/java/com/bintianqi/owndroid/ui/theme/Theme.kt index d76b6c1..2522880 100644 --- a/app/src/main/java/com/bintianqi/owndroid/ui/theme/Theme.kt +++ b/app/src/main/java/com/bintianqi/owndroid/ui/theme/Theme.kt @@ -86,20 +86,20 @@ fun OwnDroidTheme( val darkTheme = isSystemInDarkTheme() val context = LocalContext.current val sharedPref = context.getSharedPreferences("data", Context.MODE_PRIVATE) - if(!sharedPref.contains("dynamicColor")&&VERSION.SDK_INT>=32){ - sharedPref.edit().putBoolean("dynamicColor",true).apply() + if(!sharedPref.contains("dynamicColor") && VERSION.SDK_INT >= 32) { + sharedPref.edit().putBoolean("dynamicColor", true).apply() } var colorScheme = when { materialYou && VERSION.SDK_INT>=31 -> { - if(darkTheme){ dynamicDarkColorScheme(context) }else{ dynamicLightColorScheme(context) } + if(darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) } darkTheme -> DarkColorScheme else -> LightColorScheme } - if(darkTheme&&blackTheme){ + if(darkTheme&&blackTheme) { colorScheme = colorScheme.copy(background = Color.Black) } - if(!darkTheme){ + if(!darkTheme) { colorScheme = colorScheme.copy(background = colorScheme.primary.copy(alpha = 0.05f)) } val view = LocalView.current