mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-29 05:15:58 +00:00
reformat code
This commit is contained in:
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -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
|
||||
|
||||
@@ -28,12 +28,12 @@ import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
fun AuthScreen(activity: FragmentActivity, showAuth: MutableState<Boolean>){
|
||||
fun AuthScreen(activity: FragmentActivity, showAuth: MutableState<Boolean>) {
|
||||
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<Boolean>){
|
||||
}
|
||||
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<Boolean>){
|
||||
}
|
||||
}
|
||||
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<Boolean>){
|
||||
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<Boolean>){
|
||||
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)
|
||||
|
||||
@@ -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<Boolean>, blackTheme:MutableState<Boolean>){
|
||||
fun Home(materialYou:MutableState<Boolean>, blackTheme:MutableState<Boolean>) {
|
||||
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<Boolean>, blackTheme:MutableState<Boolean>){
|
||||
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<Boolean>, blackTheme:MutableState<Boolean>){
|
||||
.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<String>){
|
||||
private fun HomePage(navCtrl:NavHostController, pkgName: MutableState<String>) {
|
||||
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<String>){
|
||||
.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)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<Pair<String,Int>>{
|
||||
val list = mutableListOf<Pair<String,Int>>()
|
||||
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
|
||||
}
|
||||
|
||||
@@ -43,14 +43,14 @@ private val pkgs = mutableListOf<PkgInfo>()
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun PackageSelector(navCtrl:NavHostController, pkgName: MutableState<String>){
|
||||
fun PackageSelector(navCtrl: NavHostController, pkgName: MutableState<String>) {
|
||||
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<String>){
|
||||
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<String>){
|
||||
.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<String>){
|
||||
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<String>){
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun PackageItem(pkg: PkgInfo, navCtrl: NavHostController, pkgName: MutableState<String>){
|
||||
private fun PackageItem(pkg: PkgInfo, navCtrl: NavHostController, pkgName: MutableState<String>) {
|
||||
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",
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,22 +24,14 @@ import androidx.navigation.compose.rememberNavController
|
||||
import com.bintianqi.owndroid.ui.*
|
||||
|
||||
@Composable
|
||||
fun AppSetting(navCtrl:NavHostController, materialYou: MutableState<Boolean>, blackTheme: MutableState<Boolean>){
|
||||
fun AppSetting(navCtrl:NavHostController, materialYou: MutableState<Boolean>, blackTheme: MutableState<Boolean>) {
|
||||
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<Boolean>, 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<Boolean>, blackTheme:MutableState<Boolean>){
|
||||
private fun ThemeSettings(materialYou:MutableState<Boolean>, blackTheme:MutableState<Boolean>) {
|
||||
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<Boolean>, 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)
|
||||
|
||||
@@ -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<Any>.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<Any>.toText():String{
|
||||
fun Set<Any>.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()
|
||||
|
||||
@@ -67,7 +67,7 @@ private var dialogDismissButtonAction = {}
|
||||
private var dialogGetStatus = { false }
|
||||
|
||||
@Composable
|
||||
fun ApplicationManage(navCtrl:NavHostController, pkgName: MutableState<String>, dialogStatus: MutableIntState){
|
||||
fun ApplicationManage(navCtrl:NavHostController, pkgName: MutableState<String>, dialogStatus: MutableIntState) {
|
||||
val focusMgr = LocalFocusManager.current
|
||||
val localNavCtrl = rememberNavController()
|
||||
val backStackEntry by localNavCtrl.currentBackStackEntryAsState()
|
||||
@@ -88,18 +88,15 @@ fun ApplicationManage(navCtrl:NavHostController, pkgName: MutableState<String>,
|
||||
)
|
||||
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<String>,
|
||||
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<String>
|
||||
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)
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,28 +48,14 @@ import com.bintianqi.owndroid.ui.*
|
||||
|
||||
var ssidSet = mutableSetOf<WifiSsid>()
|
||||
@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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.profile_owner, stringResource(if(isProfileOwner(dpm)){R.string.activated}else{R.string.deactivated}),
|
||||
operation = {localNavCtrl.navigate("ProfileOwner")}
|
||||
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") }
|
||||
)
|
||||
}
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <T> scrollAnim(
|
||||
): SpringSpec<T> = 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()) {
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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<String>()
|
||||
@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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Restriction>{
|
||||
fun internet(): List<Restriction>{
|
||||
val list:MutableList<Restriction> = 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<Restriction>{
|
||||
fun connectivity(): List<Restriction>{
|
||||
val list:MutableList<Restriction> = 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<Restriction>{
|
||||
fun application(context: Context): List<Restriction>{
|
||||
val list:MutableList<Restriction> = 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<Restriction>{
|
||||
fun media(): List<Restriction>{
|
||||
val list:MutableList<Restriction> = 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<Restriction>{
|
||||
fun user(): List<Restriction>{
|
||||
val list:MutableList<Restriction> = 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<Restriction>{
|
||||
fun other(context: Context): List<Restriction>{
|
||||
val list:MutableList<Restriction> = 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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 }
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user