From 59cbc1246a81d264a7b3555a50112e2fbe4db445 Mon Sep 17 00:00:00 2001 From: BinTianqi <1220958406@qq.com> Date: Mon, 22 Jan 2024 14:13:20 +0800 Subject: [PATCH] support profile owner --- app/src/main/AndroidManifest.xml | 3 + .../binbin/androidowner/ApplicationManage.kt | 8 +- .../com/binbin/androidowner/DeviceControl.kt | 113 ++++++------ .../com/binbin/androidowner/MainActivity.kt | 8 +- .../java/com/binbin/androidowner/Password.kt | 17 +- .../com/binbin/androidowner/Permissions.kt | 95 ++++++++--- .../main/java/com/binbin/androidowner/User.kt | 39 +++-- .../com/binbin/androidowner/UserRestrict.kt | 161 ++++++++++-------- gradle.properties | 22 +-- 9 files changed, 279 insertions(+), 187 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 48efe20..26ad53a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,6 +4,9 @@ + + + Unit ){ var isEnabled by remember{ mutableStateOf(false) } - if(myDpm.isDeviceOwnerApp("com.binbin.androidowner")){ + if(isDeviceOwner(myDpm)|| isProfileOwner(myDpm)){ isEnabled = getMethod() } Row( @@ -141,7 +141,7 @@ private fun AppManageItem( setMethod(!isEnabled) isEnabled = getMethod() }, - enabled = myDpm.isDeviceOwnerApp("com.binbin.androidowner") + enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm) ) } } diff --git a/app/src/main/java/com/binbin/androidowner/DeviceControl.kt b/app/src/main/java/com/binbin/androidowner/DeviceControl.kt index 11f0550..ecd55c0 100644 --- a/app/src/main/java/com/binbin/androidowner/DeviceControl.kt +++ b/app/src/main/java/com/binbin/androidowner/DeviceControl.kt @@ -4,9 +4,9 @@ import android.app.admin.DevicePolicyManager import android.content.ComponentName import android.content.Context import android.os.Build.VERSION +import android.os.UserManager import android.widget.Toast import androidx.compose.foundation.background -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -21,7 +21,6 @@ import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.RadioButton import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -46,62 +45,73 @@ fun DeviceControl(myDpm: DevicePolicyManager, myComponent: ComponentName,myConte .padding(bottom = 20.dp) .navigationBarsPadding() ) { - DeviceCtrlItem(R.string.disable_cam,R.string.place_holder, R.drawable.photo_camera_fill0,myDpm,{myDpm.getCameraDisabled(null)},{b -> myDpm.setCameraDisabled(myComponent,b)}) - DeviceCtrlItem(R.string.disable_scrcap,R.string.aosp_scrrec_also_work,R.drawable.screenshot_fill0,myDpm,{myDpm.getScreenCaptureDisabled(null)},{b -> myDpm.setScreenCaptureDisabled(myComponent,b) }) - if(VERSION.SDK_INT>=34){ + if(isDeviceOwner(myDpm)){ + DeviceCtrlItem(R.string.disable_cam,R.string.place_holder, R.drawable.photo_camera_fill0,myDpm,{myDpm.getCameraDisabled(null)},{b -> myDpm.setCameraDisabled(myComponent,b)}) + } + if(isDeviceOwner(myDpm)){ + DeviceCtrlItem(R.string.disable_scrcap,R.string.aosp_scrrec_also_work,R.drawable.screenshot_fill0,myDpm,{myDpm.getScreenCaptureDisabled(null)},{b -> myDpm.setScreenCaptureDisabled(myComponent,b) }) + } + if(VERSION.SDK_INT>=34&&(isDeviceOwner(myDpm)|| (isProfileOwner(myDpm)&&myDpm.isAffiliatedUser))){ DeviceCtrlItem(R.string.hide_status_bar,R.string.may_hide_notifi_icon_only,R.drawable.notifications_fill0,myDpm,{myDpm.isStatusBarDisabled},{b -> myDpm.setStatusBarDisabled(myComponent,b) }) } - if(VERSION.SDK_INT>=30){ + if(VERSION.SDK_INT>=30&&isDeviceOwner(myDpm)){ DeviceCtrlItem(R.string.auto_time,R.string.place_holder,R.drawable.schedule_fill0,myDpm,{myDpm.getAutoTimeEnabled(myComponent)},{b -> myDpm.setAutoTimeEnabled(myComponent,b) }) DeviceCtrlItem(R.string.auto_timezone,R.string.place_holder,R.drawable.globe_fill0,myDpm,{myDpm.getAutoTimeZoneEnabled(myComponent)},{b -> myDpm.setAutoTimeZoneEnabled(myComponent,b) }) } - DeviceCtrlItem(R.string.master_mute,R.string.place_holder,R.drawable.volume_up_fill0,myDpm,{myDpm.isMasterVolumeMuted(myComponent)},{b -> myDpm.setMasterVolumeMuted(myComponent,b) }) - if(VERSION.SDK_INT>=26){ + if(isDeviceOwner(myDpm)|| isProfileOwner(myDpm)){ + DeviceCtrlItem(R.string.master_mute,R.string.place_holder,R.drawable.volume_up_fill0,myDpm,{myDpm.isMasterVolumeMuted(myComponent)},{b -> myDpm.setMasterVolumeMuted(myComponent,b) }) + } + if(VERSION.SDK_INT>=26&&(isDeviceOwner(myDpm)|| isProfileOwner(myDpm))){ DeviceCtrlItem(R.string.backup_service,R.string.place_holder,R.drawable.backup_fill0,myDpm,{myDpm.isBackupServiceEnabled(myComponent)},{b -> myDpm.setBackupServiceEnabled(myComponent,b) }) } - DeviceCtrlItem(R.string.disable_bt_contact_share,R.string.place_holder,R.drawable.account_circle_fill0,myDpm,{myDpm.getBluetoothContactSharingDisabled(myComponent)},{b -> myDpm.setBluetoothContactSharingDisabled(myComponent,b)}) - if(VERSION.SDK_INT>=31){ + if(isDeviceOwner(myDpm)|| isProfileOwner(myDpm)){ + DeviceCtrlItem(R.string.disable_bt_contact_share,R.string.place_holder,R.drawable.account_circle_fill0,myDpm,{myDpm.getBluetoothContactSharingDisabled(myComponent)},{b -> myDpm.setBluetoothContactSharingDisabled(myComponent,b)}) + } + if(VERSION.SDK_INT>=31&&isDeviceOwner(myDpm)){ if(myDpm.canUsbDataSignalingBeDisabled()){ DeviceCtrlItem(R.string.usb_signal,R.string.place_holder,R.drawable.usb_fill0,myDpm,{myDpm.isUsbDataSignalingEnabled},{b -> myDpm.isUsbDataSignalingEnabled = b }) }else{ Text("你的设备不支持关闭USB信号") } } - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 6.dp, vertical = 4.dp) - .clip(RoundedCornerShape(15)) - .background(color = MaterialTheme.colorScheme.primaryContainer) - .padding(vertical = 5.dp), - horizontalArrangement = Arrangement.SpaceEvenly - ) { - Button( - onClick = { - if(myDpm.setKeyguardDisabled(myComponent,true)){ - Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() - }else{ - Toast.makeText(myContext, "失败", Toast.LENGTH_SHORT).show() - } - }, - enabled = isDeviceOwner(myDpm) + if(VERSION.SDK_INT>=28){ + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 6.dp, vertical = 4.dp) + .clip(RoundedCornerShape(15)) + .background(color = MaterialTheme.colorScheme.primaryContainer) + .padding(vertical = 5.dp), + horizontalArrangement = Arrangement.SpaceEvenly ) { - Text("禁用锁屏(需无密码)") - } - Spacer(Modifier.padding(horizontal = 5.dp)) - Button( - onClick = { - if(myDpm.setKeyguardDisabled(myComponent,false)){ - Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() - }else{ - Toast.makeText(myContext, "失败", Toast.LENGTH_SHORT).show() - } - }, - enabled = isDeviceOwner(myDpm) - ) { - Text("启用锁屏") + Button( + onClick = { + if(myDpm.setKeyguardDisabled(myComponent,true)){ + Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() + }else{ + Toast.makeText(myContext, "失败", Toast.LENGTH_SHORT).show() + } + }, + enabled = isDeviceOwner(myDpm)|| (isProfileOwner(myDpm)&&myDpm.isAffiliatedUser) + ) { + Text("禁用锁屏(需无密码)") + } + Spacer(Modifier.padding(horizontal = 5.dp)) + Button( + onClick = { + if(myDpm.setKeyguardDisabled(myComponent,false)){ + Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() + }else{ + Toast.makeText(myContext, "失败", Toast.LENGTH_SHORT).show() + } + }, + enabled = isDeviceOwner(myDpm)|| (isProfileOwner(myDpm)&&myDpm.isAffiliatedUser) + ) { + Text("启用锁屏") + } } } + Row( horizontalArrangement = Arrangement.SpaceAround, modifier = Modifier @@ -141,10 +151,16 @@ fun DeviceControl(myDpm: DevicePolicyManager, myComponent: ComponentName,myConte if(VERSION.SDK_INT<34){ Text("隐藏状态栏需要API34") } - Button(onClick = {myDpm.uninstallAllUserCaCerts(myComponent)},modifier = Modifier.align(Alignment.CenterHorizontally), enabled = isDeviceOwner(myDpm)) { + Button( + onClick = {myDpm.uninstallAllUserCaCerts(myComponent)}, + modifier = Modifier.align(Alignment.CenterHorizontally), + enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm) + ) { Text(text = "清除用户Ca证书") } - SysUpdatePolicy(myDpm,myComponent,myContext) + if(isDeviceOwner(myDpm)){ + SysUpdatePolicy(myDpm,myComponent,myContext) + } Column( modifier = Modifier .fillMaxWidth() @@ -168,7 +184,7 @@ fun DeviceControl(myDpm: DevicePolicyManager, myComponent: ComponentName,myConte containerColor = if(confirmed){MaterialTheme.colorScheme.primary}else{MaterialTheme.colorScheme.error}, contentColor = if(confirmed){MaterialTheme.colorScheme.onPrimary}else{MaterialTheme.colorScheme.onError} ), - enabled = isDeviceOwner(myDpm) + enabled = myDpm.isAdminActive(myComponent) ) { Text(text = if(confirmed){"取消"}else{"确定"}) } @@ -241,16 +257,13 @@ private fun DeviceCtrlItem( } } } - if(isDeviceOwner(myDpm)){ - isEnabled = getMethod() - } + isEnabled = getMethod() Switch( checked = isEnabled, onCheckedChange = { setMethod(!isEnabled) isEnabled=getMethod() - }, - enabled = isDeviceOwner(myDpm) + } ) } } diff --git a/app/src/main/java/com/binbin/androidowner/MainActivity.kt b/app/src/main/java/com/binbin/androidowner/MainActivity.kt index b09720d..d65350c 100644 --- a/app/src/main/java/com/binbin/androidowner/MainActivity.kt +++ b/app/src/main/java/com/binbin/androidowner/MainActivity.kt @@ -128,7 +128,7 @@ fun MyScaffold(mainDpm:DevicePolicyManager, mainComponent:ComponentName, mainCon composable(route = "DeviceControl", content = { DeviceControl(mainDpm,mainComponent,mainContext)}) composable(route = "Permissions", content = { DpmPermissions(mainDpm,mainComponent,mainContext,navCtrl)}) composable(route = "ApplicationManage", content = { ApplicationManage(mainDpm,mainComponent,mainContext)}) - composable(route = "UserRestriction", content = { UserRestriction(mainDpm,mainComponent)}) + composable(route = "UserRestriction", content = { UserRestriction(mainDpm,mainComponent,mainContext)}) composable(route = "UserManage", content = { UserManage(mainDpm,mainComponent,mainContext)}) composable(route = "Password", content = { Password(mainDpm,mainComponent,mainContext)}) } @@ -139,7 +139,7 @@ fun MyScaffold(mainDpm:DevicePolicyManager, mainComponent:ComponentName, mainCon fun HomePage(navCtrl:NavHostController,myDpm:DevicePolicyManager,myComponent:ComponentName){ val isda = myDpm.isAdminActive(myComponent) val isdo = myDpm.isDeviceOwnerApp("com.binbin.androidowner") - val activateType = if(isdo){"Device Owner"}else if(isda){"Device Admin"}else{""} + val activateType = if(isDeviceOwner(myDpm)){"Device Owner"}else if(isProfileOwner(myDpm)){"Profile Owner"}else if(isda){"Device Admin"}else{""} val isActivated = if(isdo||isda){"已激活"}else{"未激活"} Column { Row( @@ -235,3 +235,7 @@ fun RadioButtonItem( fun isDeviceOwner(dpm:DevicePolicyManager): Boolean { return dpm.isDeviceOwnerApp("com.binbin.androidowner") } + +fun isProfileOwner(dpm:DevicePolicyManager): Boolean { + return dpm.isProfileOwnerApp("com.binbin.androidowner") +} diff --git a/app/src/main/java/com/binbin/androidowner/Password.kt b/app/src/main/java/com/binbin/androidowner/Password.kt index 8b0c738..5e622a3 100644 --- a/app/src/main/java/com/binbin/androidowner/Password.kt +++ b/app/src/main/java/com/binbin/androidowner/Password.kt @@ -145,19 +145,26 @@ fun Password(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext:Conte modifier = Modifier .fillMaxWidth() .padding(horizontal = 8.dp, vertical = 4.dp) - .clip(RoundedCornerShape(10)) + .clip(RoundedCornerShape(16.dp)) .background(color = MaterialTheme.colorScheme.primaryContainer) .padding(10.dp) ) { TextField( value = newPwd, onValueChange = {newPwd=it}, - enabled = !confirmed&& isDeviceOwner(myDpm), + enabled = !confirmed&&(isDeviceOwner(myDpm)||isProfileOwner(myDpm)), label = { Text("密码")}, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password, imeAction = ImeAction.Done), keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), ) Text(text = stringResource(R.string.reset_pwd_desc), modifier = Modifier.padding(vertical = 5.dp)) + var resetPwdFlag by remember{ mutableStateOf(0) } + RadioButtonItem("RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT", + {resetPwdFlag==DevicePolicyManager.RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT}, + {resetPwdFlag=DevicePolicyManager.RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT}) + RadioButtonItem("RESET_PASSWORD_REQUIRE_ENTRY",{resetPwdFlag==DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY}, + {resetPwdFlag=DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY}) + RadioButtonItem("无",{resetPwdFlag==0},{resetPwdFlag=0}) Row { Button( onClick = { @@ -165,14 +172,14 @@ fun Password(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext:Conte }else{ Toast.makeText(myContext, "需要4位数字或字母", Toast.LENGTH_SHORT).show() } }, modifier = Modifier.padding(end = 10.dp), - enabled = isDeviceOwner(myDpm) + enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm) ) { Text("确认密码") } if(VERSION.SDK_INT>=26){ Button( onClick = { - val resetSuccess = myDpm.resetPasswordWithToken(myComponent,newPwd,myByteArray,0) + val resetSuccess = myDpm.resetPasswordWithToken(myComponent,newPwd,myByteArray,resetPwdFlag) if(resetSuccess){ Toast.makeText(myContext, "设置成功", Toast.LENGTH_SHORT).show() }else{ Toast.makeText(myContext, "设置失败", Toast.LENGTH_SHORT).show() } confirmed=false @@ -185,7 +192,7 @@ fun Password(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext:Conte }else{ Button( onClick = { - val resetSuccess = myDpm.resetPassword(newPwd,0) + val resetSuccess = myDpm.resetPassword(newPwd,resetPwdFlag) if(resetSuccess){ Toast.makeText(myContext, "设置成功", Toast.LENGTH_SHORT).show() }else{ Toast.makeText(myContext, "设置失败", Toast.LENGTH_SHORT).show() } confirmed=false diff --git a/app/src/main/java/com/binbin/androidowner/Permissions.kt b/app/src/main/java/com/binbin/androidowner/Permissions.kt index e1932b2..7154e6e 100644 --- a/app/src/main/java/com/binbin/androidowner/Permissions.kt +++ b/app/src/main/java/com/binbin/androidowner/Permissions.kt @@ -102,6 +102,58 @@ fun DpmPermissions(myDpm: DevicePolicyManager, myComponent: ComponentName, myCon Text("或者进入设置 -> 安全 -> 更多安全设置 -> 设备管理应用 -> Android Owner") } } + Row( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 5.dp) + .clip(RoundedCornerShape(15)) + .background(color = MaterialTheme.colorScheme.primaryContainer) + .padding(10.dp), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + Column { + Text(text = "Profile Owner", style = MaterialTheme.typography.titleLarge) + Text(if(isProfileOwner(myDpm)){"已激活"}else{"未激活"}) + } + if(isProfileOwner(myDpm)&&VERSION.SDK_INT>=24){ + Button( + onClick = { + myDpm.clearProfileOwner(myComponent) + navCtrl.navigate("HomePage") { + popUpTo( + navCtrl.graph.findStartDestination().id + ) { saveState = true } + } + } + ) { + Text("撤销") + } + } + } + if(!isProfileOwner(myDpm)){ + Column( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 5.dp) + .clip(RoundedCornerShape(15.dp)) + .background(color = MaterialTheme.colorScheme.tertiaryContainer) + .padding(10.dp), + horizontalAlignment = Alignment.Start + ) { + if(!isDeviceOwner(myDpm)){ + Text("你可以在adb shell中使用以下命令激活Profile Owner") + SelectionContainer { + Text("dpm set-profile-owner com.binbin.androidowner/com.binbin.androidowner.MyDeviceAdminReceiver", + color = MaterialTheme.colorScheme.onTertiaryContainer) + } + Text("一个设备只能有一个Device owner,强烈建议激活Device owner") + } + if(isDeviceOwner(myDpm)){ + Text("Device owner创建其他用户后,这个应用会成为新用户的Profile owner") + } + } + } Row( modifier = Modifier .fillMaxWidth() @@ -131,7 +183,7 @@ fun DpmPermissions(myDpm: DevicePolicyManager, myComponent: ComponentName, myCon } } } - if(isdo||isda){ + if(isDeviceOwner(myDpm)|| isProfileOwner(myDpm)||myDpm.isAdminActive(myComponent)){ Text( text = "注意!在这里撤销权限不会清除配置。比如:被停用的应用会保持停用状态", color = MaterialTheme.colorScheme.onErrorContainer, @@ -143,27 +195,7 @@ fun DpmPermissions(myDpm: DevicePolicyManager, myComponent: ComponentName, myCon .padding(6.dp) ) } - if(isdo){ - Column( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 5.dp) - .clip(RoundedCornerShape(15)) - .background(color = MaterialTheme.colorScheme.primaryContainer) - .padding(8.dp) - ) { - Text(text = "设备信息", style = MaterialTheme.typography.titleLarge) - if(VERSION.SDK_INT>=30){ - val orgDevice = myDpm.isOrganizationOwnedDeviceWithManagedProfile - Text("由组织拥有的工作资料设备:$orgDevice") - } - if(VERSION.SDK_INT>=34&&(myDpm.isProfileOwnerApp("com.binbin.androidowner")||myDpm.isManagedProfile(myComponent))){ - val financed = myDpm.isDeviceFinanced - Text("Financed Device : $financed") - } - } - } - if(!isdo){ + if(!isdo&&!isProfileOwner(myDpm)){ Column( modifier = Modifier .fillMaxWidth() @@ -183,6 +215,25 @@ fun DpmPermissions(myDpm: DevicePolicyManager, myComponent: ComponentName, myCon } } } + if(VERSION.SDK_INT>=30){ + Column( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 5.dp) + .clip(RoundedCornerShape(15)) + .background(color = MaterialTheme.colorScheme.primaryContainer) + .padding(8.dp) + ) { + Text(text = "设备信息", style = MaterialTheme.typography.titleLarge) + val orgDevice = myDpm.isOrganizationOwnedDeviceWithManagedProfile + Text("由组织拥有的受管理资料设备:$orgDevice") + Text("Managed profile: ${myDpm.isManagedProfile(myComponent)}") + if(VERSION.SDK_INT>=34&&(isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&myDpm.isOrganizationOwnedDeviceWithManagedProfile))){ + val financed = myDpm.isDeviceFinanced + Text("企业资产 : $financed") + } + } + } if(isdo&&VERSION.SDK_INT>=24){ DeviceOwnerInfo(R.string.owner_lockscr_info,R.string.place_holder,R.string.owner_lockscr_info,focusManager,myContext, diff --git a/app/src/main/java/com/binbin/androidowner/User.kt b/app/src/main/java/com/binbin/androidowner/User.kt index a3e80e0..81bab3d 100644 --- a/app/src/main/java/com/binbin/androidowner/User.kt +++ b/app/src/main/java/com/binbin/androidowner/User.kt @@ -1,5 +1,6 @@ package com.binbin.androidowner +import android.app.ActivityManager import android.app.admin.DevicePolicyManager import android.content.ComponentName import android.content.Context @@ -43,7 +44,6 @@ fun UserManage(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext: Co //val myUM = myContext.getSystemService(Context.USER_SERVICE) val currentUser = android.os.Process.myUserHandle() val userList = Test.returnUsers(myContext) - Text("因为我的模拟器的多用户无法使用,部分功能并未测试") Column( modifier = Modifier .fillMaxWidth() @@ -60,16 +60,16 @@ fun UserManage(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext: Co Text("支持多用户:${UserManager.supportsMultipleUsers()}") } if(VERSION.SDK_INT>=31){ - Text("Headless system user: ${UserManager.isHeadlessSystemUserMode()}") + Text("系统用户: ${UserManager.isHeadlessSystemUserMode()}") } Spacer(Modifier.padding(vertical = 5.dp)) - if (VERSION.SDK_INT >= 28&& isDeviceOwner(myDpm)) { + if (VERSION.SDK_INT >= 28) { val logoutable = myDpm.isLogoutEnabled Text(text = "用户可以退出 : $logoutable") val ephemeralUser = myDpm.isEphemeralUser(myComponent) Text(text = "临时用户: $ephemeralUser") val affiliatedUser = myDpm.isAffiliatedUser - Text(text = "Affiliated User: $affiliatedUser") + Text(text = "次级用户: $affiliatedUser") } Spacer(Modifier.padding(5.dp)) Text("切换用户后或设备重启后会删除临时用户") @@ -88,7 +88,7 @@ fun UserManage(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext: Co var resultForLogout by remember{ mutableIntStateOf(-1) } var resultForStop by remember{ mutableIntStateOf(-1) } Text("登出用户需要成为次级用户的Profile Owner") - Button(onClick = {resultForLogout = myDpm.logoutUser(myComponent)}, enabled = isDeviceOwner(myDpm)) { + Button(onClick = {resultForLogout = myDpm.logoutUser(myComponent)}, enabled = isProfileOwner(myDpm)) { Text("登出用户") } if(resultForLogout!=-1){ @@ -100,6 +100,11 @@ fun UserManage(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext: Co if(resultForStop!=-1){ Text(userOperationResultCode(resultForStop)) } + if(isProfileOwner(myDpm)){ + Button(onClick = {myDpm.setProfileEnabled(myComponent)}) { + Text(text = "启用资料") + } + } } Button( onClick = { @@ -169,10 +174,10 @@ fun UserManage(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext: Co }else{ Text("创建用户需安卓7") } - UserSessionMessage("用户名","用户名",myDpm,myContext,{null},{msg -> myDpm.setProfileName(myComponent, msg.toString())}) + UserSessionMessage("用户名","用户名",true,myDpm,myContext,{null},{msg -> myDpm.setProfileName(myComponent, msg.toString())}) if(VERSION.SDK_INT>=28){ - UserSessionMessage("用户会话开始消息","消息",myDpm,myContext,{myDpm.getStartUserSessionMessage(myComponent)},{msg -> myDpm.setStartUserSessionMessage(myComponent,msg)}) - UserSessionMessage("用户会话结束消息","消息",myDpm,myContext,{myDpm.getEndUserSessionMessage(myComponent)},{msg -> myDpm.setEndUserSessionMessage(myComponent,msg)}) + UserSessionMessage("用户会话开始消息","消息",false,myDpm,myContext,{myDpm.getStartUserSessionMessage(myComponent)},{msg -> myDpm.setStartUserSessionMessage(myComponent,msg)}) + UserSessionMessage("用户会话结束消息","消息",false,myDpm,myContext,{myDpm.getEndUserSessionMessage(myComponent)},{msg -> myDpm.setEndUserSessionMessage(myComponent,msg)}) } Spacer(Modifier.padding(vertical = 30.dp)) } @@ -182,6 +187,7 @@ fun UserManage(myDpm:DevicePolicyManager,myComponent:ComponentName,myContext: Co fun UserSessionMessage( text:String, textField:String, + profileOwner:Boolean, myDpm:DevicePolicyManager, myContext: Context, get:()->CharSequence?, @@ -196,29 +202,26 @@ fun UserSessionMessage( .padding(10.dp) ) { val focusMgr = LocalFocusManager.current - var msg:CharSequence? by remember{ mutableStateOf(null) } - if(isDeviceOwner(myDpm)){ - msg = if(get()==null){""}else{get()} - } + var msg by remember{ mutableStateOf(if(isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&profileOwner)){ if(get()==null){""}else{get().toString()} }else{""}) } Text(text = text, style = MaterialTheme.typography.titleLarge, color = MaterialTheme.colorScheme.onPrimaryContainer) TextField( - value = msg.toString(), + value = msg, onValueChange = {msg=it}, label = {Text(textField)}, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}), modifier = Modifier.padding(vertical = 6.dp), - enabled = isDeviceOwner(myDpm) + enabled = isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&profileOwner) ) Row { Button( onClick = { focusMgr.clearFocus() setMsg(msg) - msg = if(get()==null){""}else{get()} + msg = if(get()==null){""}else{get().toString()} Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() }, - enabled = isDeviceOwner(myDpm) + enabled = isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&profileOwner) ) { Text("应用") } @@ -227,10 +230,10 @@ fun UserSessionMessage( onClick = { focusMgr.clearFocus() setMsg(null) - msg = if(get()==null){""}else{get()} + msg = if(get()==null){""}else{get().toString()} Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() }, - enabled = isDeviceOwner(myDpm) + enabled = isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&profileOwner) ) { Text("使用默认") } diff --git a/app/src/main/java/com/binbin/androidowner/UserRestrict.kt b/app/src/main/java/com/binbin/androidowner/UserRestrict.kt index 73f9907..5678867 100644 --- a/app/src/main/java/com/binbin/androidowner/UserRestrict.kt +++ b/app/src/main/java/com/binbin/androidowner/UserRestrict.kt @@ -2,8 +2,10 @@ package com.binbin.androidowner import android.app.admin.DevicePolicyManager import android.content.ComponentName +import android.content.Context import android.os.Build.VERSION import android.os.UserManager +import android.widget.Toast import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -35,7 +37,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp @Composable -fun UserRestriction(myDpm: DevicePolicyManager, myComponent: ComponentName){ +fun UserRestriction(myDpm: DevicePolicyManager, myComponent: ComponentName,myContext: Context){ val verticalScrolling = rememberScrollState() var currentSection by remember{ mutableIntStateOf(0) } Column( @@ -46,110 +48,113 @@ fun UserRestriction(myDpm: DevicePolicyManager, myComponent: ComponentName){ .navigationBarsPadding() ) { Text("打开开关后会禁用对应的功能") + if(isProfileOwner(myDpm)){ + Text("Profile owner无法更改部分功能") + } SectionTab("网络和互联网",{currentSection==1}) { currentSection = if(currentSection==1){ 0 }else{ 1 } } if(currentSection==1){ - UserRestrictionItem(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,R.string.config_mobile_network,"",R.drawable.signal_cellular_alt_fill0,myComponent, myDpm) - if(VERSION.SDK_INT>=24){UserRestrictionItem(UserManager.DISALLOW_DATA_ROAMING,R.string.data_roaming,"",R.drawable.network_cell_fill0,myComponent, myDpm)} + UserRestrictionItem(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,R.string.config_mobile_network,"",R.drawable.signal_cellular_alt_fill0, myContext, myComponent, myDpm) + if(VERSION.SDK_INT>=24){UserRestrictionItem(UserManager.DISALLOW_DATA_ROAMING,R.string.data_roaming,"",R.drawable.network_cell_fill0, myContext, myComponent, myDpm)} if(VERSION.SDK_INT>=34){ - UserRestrictionItem(UserManager.DISALLOW_CELLULAR_2G,R.string.cellular_2g,"",R.drawable.network_cell_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_ULTRA_WIDEBAND_RADIO,R.string.ultra_wideband_radio,"",R.drawable.android_fill0,myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_CELLULAR_2G,R.string.cellular_2g,"",R.drawable.network_cell_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_ULTRA_WIDEBAND_RADIO,R.string.ultra_wideband_radio,"",R.drawable.android_fill0, myContext, myComponent, myDpm) } - UserRestrictionItem(UserManager.DISALLOW_CONFIG_WIFI,R.string.config_wifi,"",R.drawable.wifi_fill0,myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_CONFIG_WIFI,R.string.config_wifi,"",R.drawable.wifi_fill0, myContext, myComponent, myDpm) if(VERSION.SDK_INT>=33){ - UserRestrictionItem(UserManager.DISALLOW_ADD_WIFI_CONFIG,R.string.add_wifi_conf,"",R.drawable.wifi_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_CHANGE_WIFI_STATE,R.string.change_wifi_state,"",R.drawable.wifi_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_WIFI_DIRECT,R.string.wifi_direct,"",R.drawable.wifi_tethering_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_WIFI_TETHERING,R.string.wifi_tethering,"",R.drawable.wifi_tethering_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_SHARING_ADMIN_CONFIGURED_WIFI,R.string.share_admin_wifi,"",R.drawable.share_fill0,myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_ADD_WIFI_CONFIG,R.string.add_wifi_conf,"",R.drawable.wifi_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_CHANGE_WIFI_STATE,R.string.change_wifi_state,"",R.drawable.wifi_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_WIFI_DIRECT,R.string.wifi_direct,"",R.drawable.wifi_tethering_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_WIFI_TETHERING,R.string.wifi_tethering,"",R.drawable.wifi_tethering_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_SHARING_ADMIN_CONFIGURED_WIFI,R.string.share_admin_wifi,"",R.drawable.share_fill0, myContext, myComponent, myDpm) } - UserRestrictionItem(UserManager.DISALLOW_NETWORK_RESET,R.string.network_reset,"",R.drawable.reset_wrench_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_CONFIG_TETHERING,R.string.config_tethering,"",R.drawable.wifi_tethering_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_CONFIG_VPN,R.string.config_vpn,"",R.drawable.vpn_key_fill0,myComponent, myDpm) - if(VERSION.SDK_INT>=29){UserRestrictionItem(UserManager.DISALLOW_CONFIG_PRIVATE_DNS,R.string.config_private_dns,"",R.drawable.dns_fill0,myComponent, myDpm)} + UserRestrictionItem(UserManager.DISALLOW_NETWORK_RESET,R.string.network_reset,"",R.drawable.reset_wrench_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_CONFIG_TETHERING,R.string.config_tethering,"",R.drawable.wifi_tethering_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_CONFIG_VPN,R.string.config_vpn,"",R.drawable.vpn_key_fill0, myContext, myComponent, myDpm) + if(VERSION.SDK_INT>=29){UserRestrictionItem(UserManager.DISALLOW_CONFIG_PRIVATE_DNS,R.string.config_private_dns,"",R.drawable.dns_fill0, myContext, myComponent, myDpm)} - if(VERSION.SDK_INT>=28){ UserRestrictionItem(UserManager.DISALLOW_AIRPLANE_MODE,R.string.airplane_mode,"",R.drawable.airplanemode_active_fill0,myComponent, myDpm) } - UserRestrictionItem(UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,R.string.config_cell_broadcasts,"",R.drawable.cell_tower_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_SMS,R.string.sms,"",R.drawable.sms_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_OUTGOING_CALLS,R.string.outgoing_calls,"",R.drawable.phone_forwarded_fill0,myComponent, myDpm) + if(VERSION.SDK_INT>=28){ UserRestrictionItem(UserManager.DISALLOW_AIRPLANE_MODE,R.string.airplane_mode,"",R.drawable.airplanemode_active_fill0, myContext, myComponent, myDpm) } + UserRestrictionItem(UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,R.string.config_cell_broadcasts,"",R.drawable.cell_tower_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_SMS,R.string.sms,"",R.drawable.sms_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_OUTGOING_CALLS,R.string.outgoing_calls,"",R.drawable.phone_forwarded_fill0, myContext, myComponent, myDpm) } SectionTab("其他连接",{currentSection==6}) { currentSection = if(currentSection==6){ 0 }else{ 6 } } if(currentSection==6){ if(VERSION.SDK_INT>=26){ - UserRestrictionItem(UserManager.DISALLOW_BLUETOOTH,R.string.bluetooth,"",R.drawable.bluetooth_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_BLUETOOTH_SHARING,R.string.bt_share,"",R.drawable.bluetooth_searching_fill0,myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_BLUETOOTH,R.string.bluetooth,"",R.drawable.bluetooth_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_BLUETOOTH_SHARING,R.string.bt_share,"",R.drawable.bluetooth_searching_fill0, myContext, myComponent, myDpm) } - UserRestrictionItem(UserManager.DISALLOW_SHARE_LOCATION,R.string.share_location,"",R.drawable.location_on_fill0,myComponent, myDpm) - if(VERSION.SDK_INT>=28){UserRestrictionItem(UserManager.DISALLOW_CONFIG_LOCATION,R.string.config_location,"",R.drawable.location_on_fill0,myComponent, myDpm)} - UserRestrictionItem(UserManager.DISALLOW_OUTGOING_BEAM,R.string.outgoing_beam,"",R.drawable.nfc_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_USB_FILE_TRANSFER,R.string.usb_file_transfer,"",R.drawable.usb_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,R.string.mount_physical_media, stringResource(R.string.mount_phisical_media_desc),R.drawable.sd_card_fill0,myComponent, myDpm) - if(VERSION.SDK_INT>=28){UserRestrictionItem(UserManager.DISALLOW_PRINTING,R.string.printing,"",R.drawable.print_fill0,myComponent, myDpm)} + UserRestrictionItem(UserManager.DISALLOW_SHARE_LOCATION,R.string.share_location,"",R.drawable.location_on_fill0, myContext, myComponent, myDpm) + if(VERSION.SDK_INT>=28){UserRestrictionItem(UserManager.DISALLOW_CONFIG_LOCATION,R.string.config_location,"",R.drawable.location_on_fill0, myContext, myComponent, myDpm)} + UserRestrictionItem(UserManager.DISALLOW_OUTGOING_BEAM,R.string.outgoing_beam,"",R.drawable.nfc_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_USB_FILE_TRANSFER,R.string.usb_file_transfer,"",R.drawable.usb_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,R.string.mount_physical_media, stringResource(R.string.mount_phisical_media_desc),R.drawable.sd_card_fill0, myContext, myComponent, myDpm) + if(VERSION.SDK_INT>=28){UserRestrictionItem(UserManager.DISALLOW_PRINTING,R.string.printing,"",R.drawable.print_fill0, myContext, myComponent, myDpm)} } SectionTab("应用",{currentSection==2}) { currentSection = if(currentSection==2){ 0 }else{ 2 } } if(currentSection==2){ - UserRestrictionItem(UserManager.DISALLOW_INSTALL_APPS,R.string.install_apps,"",R.drawable.android_fill0,myComponent, myDpm) - if(VERSION.SDK_INT>=29){UserRestrictionItem(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY,R.string.install_unknown_src_globally,"",R.drawable.android_fill0,myComponent, myDpm)} - UserRestrictionItem(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,R.string.inst_unknown_src,"",R.drawable.android_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_UNINSTALL_APPS,R.string.uninstall_apps,"",R.drawable.delete_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_APPS_CONTROL,R.string.apps_ctrl, stringResource(R.string.apps_ctrl_description),R.drawable.apps_fill0,myComponent, myDpm) - if(VERSION.SDK_INT>=34){ UserRestrictionItem(UserManager.DISALLOW_CONFIG_DEFAULT_APPS,R.string.config_default_apps,"",R.drawable.apps_fill0,myComponent, myDpm) } + UserRestrictionItem(UserManager.DISALLOW_INSTALL_APPS,R.string.install_apps,"",R.drawable.android_fill0, myContext, myComponent, myDpm) + if(VERSION.SDK_INT>=29){UserRestrictionItem(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY,R.string.install_unknown_src_globally,"",R.drawable.android_fill0, myContext, myComponent, myDpm)} + UserRestrictionItem(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,R.string.inst_unknown_src,"",R.drawable.android_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_UNINSTALL_APPS,R.string.uninstall_apps,"",R.drawable.delete_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_APPS_CONTROL,R.string.apps_ctrl, stringResource(R.string.apps_ctrl_description),R.drawable.apps_fill0, myContext, myComponent, myDpm) + if(VERSION.SDK_INT>=34){ UserRestrictionItem(UserManager.DISALLOW_CONFIG_DEFAULT_APPS,R.string.config_default_apps,"",R.drawable.apps_fill0, myContext, myComponent, myDpm) } } SectionTab("显示与音量",{currentSection==3}) { currentSection = if(currentSection==3){ 0 }else{ 3 } } if(currentSection==3){ if(VERSION.SDK_INT>=28){ - UserRestrictionItem(UserManager.DISALLOW_CONFIG_BRIGHTNESS,R.string.config_brightness,"",R.drawable.brightness_5_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT,R.string.config_scr_timeout,"",R.drawable.screen_lock_portrait_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_AMBIENT_DISPLAY,R.string.ambient_display,"",R.drawable.brightness_5_fill0,myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_CONFIG_BRIGHTNESS,R.string.config_brightness,"",R.drawable.brightness_5_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT,R.string.config_scr_timeout,"",R.drawable.screen_lock_portrait_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_AMBIENT_DISPLAY,R.string.ambient_display,"",R.drawable.brightness_5_fill0, myContext, myComponent, myDpm) } - UserRestrictionItem(UserManager.DISALLOW_ADJUST_VOLUME,R.string.adjust_volume,"",R.drawable.volume_up_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_UNMUTE_MICROPHONE,R.string.unmute_microphone,"",R.drawable.mic_fill0,myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_ADJUST_VOLUME,R.string.adjust_volume,"",R.drawable.volume_up_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_UNMUTE_MICROPHONE,R.string.unmute_microphone,"",R.drawable.mic_fill0, myContext, myComponent, myDpm) if(VERSION.SDK_INT>=31){ - UserRestrictionItem(UserManager.DISALLOW_CAMERA_TOGGLE,R.string.camera_toggle,"",R.drawable.cameraswitch_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_MICROPHONE_TOGGLE,R.string.microphone_toggle,"",R.drawable.mic_fill0,myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_CAMERA_TOGGLE,R.string.camera_toggle,"",R.drawable.cameraswitch_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_MICROPHONE_TOGGLE,R.string.microphone_toggle,"",R.drawable.mic_fill0, myContext, myComponent, myDpm) } } SectionTab("用户与工作资料",{currentSection==4}) { currentSection = if(currentSection==4){ 0 }else{ 4 } } if(currentSection==4){ - UserRestrictionItem(UserManager.DISALLOW_ADD_USER,R.string.add_user,"",R.drawable.account_circle_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_REMOVE_USER,R.string.remove_user,"",R.drawable.account_circle_fill0,myComponent, myDpm) - if(VERSION.SDK_INT>=28){UserRestrictionItem(UserManager.DISALLOW_USER_SWITCH,R.string.switch_user,"",R.drawable.account_circle_fill0,myComponent, myDpm)} - if(VERSION.SDK_INT>=24){UserRestrictionItem(UserManager.DISALLOW_SET_USER_ICON,R.string.set_user_icon,"",R.drawable.account_circle_fill0,myComponent, myDpm)} - UserRestrictionItem(UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE,R.string.cross_profile_copy, stringResource(R.string.cross_profile_copy_desc),R.drawable.content_paste_fill0,myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_ADD_USER,R.string.add_user,"",R.drawable.account_circle_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_REMOVE_USER,R.string.remove_user,"",R.drawable.account_circle_fill0, myContext, myComponent, myDpm) + if(VERSION.SDK_INT>=28){UserRestrictionItem(UserManager.DISALLOW_USER_SWITCH,R.string.switch_user,"",R.drawable.account_circle_fill0, myContext, myComponent, myDpm)} + if(VERSION.SDK_INT>=24){UserRestrictionItem(UserManager.DISALLOW_SET_USER_ICON,R.string.set_user_icon,"",R.drawable.account_circle_fill0, myContext, myComponent, myDpm)} + UserRestrictionItem(UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE,R.string.cross_profile_copy, stringResource(R.string.cross_profile_copy_desc),R.drawable.content_paste_fill0, myContext, myComponent, myDpm) if(VERSION.SDK_INT>=26){ - UserRestrictionItem(UserManager.DISALLOW_ADD_MANAGED_PROFILE,R.string.add_managed_profile,"",R.drawable.work_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE,R.string.remove_managed_profile,"",R.drawable.work_fill0,myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_ADD_MANAGED_PROFILE,R.string.add_managed_profile,"",R.drawable.work_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE,R.string.remove_managed_profile,"",R.drawable.work_fill0, myContext, myComponent, myDpm) } if(VERSION.SDK_INT>=28){ - UserRestrictionItem(UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE,R.string.share_into_managed_profile,"",R.drawable.share_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_UNIFIED_PASSWORD,R.string.unifiied_pwd,"",R.drawable.work_fill0,myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE,R.string.share_into_managed_profile,"",R.drawable.share_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_UNIFIED_PASSWORD,R.string.unifiied_pwd,"",R.drawable.work_fill0, myContext, myComponent, myDpm) } } SectionTab("杂项",{currentSection==5}) { currentSection = if(currentSection==5){ 0 }else{ 5 } } if(currentSection==5){ - if(VERSION.SDK_INT>=26){ UserRestrictionItem(UserManager.DISALLOW_AUTOFILL,R.string.autofill, "",R.drawable.password_fill0,myComponent, myDpm) } - UserRestrictionItem(UserManager.DISALLOW_CONFIG_CREDENTIALS,R.string.config_credentials,"",R.drawable.android_fill0,myComponent, myDpm) + if(VERSION.SDK_INT>=26){ UserRestrictionItem(UserManager.DISALLOW_AUTOFILL,R.string.autofill, "",R.drawable.password_fill0, myContext, myComponent, myDpm) } + UserRestrictionItem(UserManager.DISALLOW_CONFIG_CREDENTIALS,R.string.config_credentials,"",R.drawable.android_fill0, myContext, myComponent, myDpm) if(VERSION.SDK_INT>=29){ - UserRestrictionItem(UserManager.DISALLOW_CONTENT_CAPTURE,R.string.content_capture,"",R.drawable.android_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_CONTENT_SUGGESTIONS,R.string.content_suggestions,"",R.drawable.android_fill0,myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_CONTENT_CAPTURE,R.string.content_capture,"",R.drawable.android_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_CONTENT_SUGGESTIONS,R.string.content_suggestions,"",R.drawable.android_fill0, myContext, myComponent, myDpm) } - UserRestrictionItem(UserManager.DISALLOW_CREATE_WINDOWS,R.string.create_windows, stringResource(R.string.create_windows_description),R.drawable.web_asset,myComponent, myDpm) - if(VERSION.SDK_INT>=24){UserRestrictionItem(UserManager.DISALLOW_SET_WALLPAPER,R.string.set_wallpaper,"",R.drawable.wallpaper_fill0,myComponent, myDpm)} - if(VERSION.SDK_INT>=34){ UserRestrictionItem(UserManager.DISALLOW_GRANT_ADMIN,R.string.grant_admin,"",R.drawable.android_fill0,myComponent, myDpm) } - UserRestrictionItem(UserManager.DISALLOW_FUN,R.string.`fun`,"可能会影响谷歌商店的游戏",R.drawable.stadia_controller_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_MODIFY_ACCOUNTS,R.string.modify_accounts,"",R.drawable.manage_accounts_fill0,myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_CREATE_WINDOWS,R.string.create_windows, stringResource(R.string.create_windows_description),R.drawable.web_asset, myContext, myComponent, myDpm) + if(VERSION.SDK_INT>=24){UserRestrictionItem(UserManager.DISALLOW_SET_WALLPAPER,R.string.set_wallpaper,"",R.drawable.wallpaper_fill0, myContext, myComponent, myDpm)} + if(VERSION.SDK_INT>=34){ UserRestrictionItem(UserManager.DISALLOW_GRANT_ADMIN,R.string.grant_admin,"",R.drawable.android_fill0, myContext, myComponent, myDpm) } + UserRestrictionItem(UserManager.DISALLOW_FUN,R.string.`fun`,"可能会影响谷歌商店的游戏",R.drawable.stadia_controller_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_MODIFY_ACCOUNTS,R.string.modify_accounts,"",R.drawable.manage_accounts_fill0, myContext, myComponent, myDpm) if(VERSION.SDK_INT>=28){ - UserRestrictionItem(UserManager.DISALLOW_CONFIG_LOCALE,R.string.config_locale,"",R.drawable.language_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_CONFIG_DATE_TIME,R.string.config_date_time,"",R.drawable.schedule_fill0,myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_CONFIG_LOCALE,R.string.config_locale,"",R.drawable.language_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_CONFIG_DATE_TIME,R.string.config_date_time,"",R.drawable.schedule_fill0, myContext, myComponent, myDpm) } - if(VERSION.SDK_INT>=28){UserRestrictionItem(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,R.string.sys_err_dialog,"",R.drawable.android_fill0,myComponent, myDpm)} - UserRestrictionItem(UserManager.DISALLOW_FACTORY_RESET,R.string.factory_reset,"",R.drawable.android_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_SAFE_BOOT,R.string.safe_boot,"",R.drawable.android_fill0,myComponent, myDpm) - UserRestrictionItem(UserManager.DISALLOW_DEBUGGING_FEATURES,R.string.debug_features,"",R.drawable.adb_fill0,myComponent, myDpm) + if(VERSION.SDK_INT>=28){UserRestrictionItem(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,R.string.sys_err_dialog,"",R.drawable.android_fill0, myContext, myComponent, myDpm)} + UserRestrictionItem(UserManager.DISALLOW_FACTORY_RESET,R.string.factory_reset,"",R.drawable.android_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_SAFE_BOOT,R.string.safe_boot,"",R.drawable.android_fill0, myContext, myComponent, myDpm) + UserRestrictionItem(UserManager.DISALLOW_DEBUGGING_FEATURES,R.string.debug_features,"",R.drawable.adb_fill0, myContext, myComponent, myDpm) } if(VERSION.SDK_INT<24){ @@ -195,8 +200,14 @@ fun SectionTab(txt:String,getSection:()->Boolean,setSection:()->Unit){ } @Composable -private fun UserRestrictionItem(restriction:String, itemName:Int, restrictionDescription:String, leadIcon:Int,myComponent: ComponentName, myDpm: DevicePolicyManager){ - val isdo = myDpm.isDeviceOwnerApp("com.binbin.androidowner") +private fun UserRestrictionItem( + restriction:String, itemName:Int, + restrictionDescription:String, + leadIcon:Int, + myContext: Context, + myComponent: ComponentName, + myDpm: DevicePolicyManager +){ var strictState by remember{ mutableStateOf(false) } Row( modifier = Modifier @@ -228,7 +239,7 @@ private fun UserRestrictionItem(restriction:String, itemName:Int, restrictionDes if(restrictionDescription!=""){Text(text = restrictionDescription, color = MaterialTheme.colorScheme.onSecondaryContainer)} } } - if(isdo&&VERSION.SDK_INT>=24){ + if(VERSION.SDK_INT>=24&&(isDeviceOwner(myDpm)|| isProfileOwner(myDpm))){ strictState = myDpm.getUserRestrictions(myComponent).getBoolean(restriction) } if(VERSION.SDK_INT>=24){ @@ -236,14 +247,20 @@ private fun UserRestrictionItem(restriction:String, itemName:Int, restrictionDes checked = strictState, onCheckedChange = { strictState=it - if(strictState){ - myDpm.addUserRestriction(myComponent,restriction) - }else{ - myDpm.clearUserRestriction(myComponent,restriction) + try{ + if(strictState){ + myDpm.addUserRestriction(myComponent,restriction) + }else{ + myDpm.clearUserRestriction(myComponent,restriction) + } + }catch(e:SecurityException){ + if(isProfileOwner(myDpm)){ + Toast.makeText(myContext, "Profile owner 无法更改", Toast.LENGTH_SHORT).show() + } } strictState = myDpm.getUserRestrictions(myComponent).getBoolean(restriction) }, - enabled = isdo + enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm) ) } } diff --git a/gradle.properties b/gradle.properties index 3c5031e..9403523 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,23 +1,17 @@ -# Project-wide Gradle settings. -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. -# For more details on how to configure your build environment visit +## For more details on how to configure your build environment visit # http://www.gradle.org/docs/current/userguide/build_environment.html +# # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +# Default value: -Xmx1024m -XX:MaxPermSize=256m +# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 +# # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true -# AndroidX package structure to make it clearer which packages are bundled with the -# Android operating system, and which are packaged with your app's APK -# https://developer.android.com/topic/libraries/support-library/androidx-rn +#Sun Jan 21 20:24:56 CST 2024 +android.nonTransitiveRClass=true android.useAndroidX=true -# Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official -# Enables namespacing of each library's R class so that its R class includes only the -# resources declared in the library itself and none from the library's dependencies, -# thereby reducing the size of the R class for that library -android.nonTransitiveRClass=true \ No newline at end of file +org.gradle.jvmargs=-Xmx1536M -Dkotlin.daemon.jvm.options\="-Xmx1536M" -Dfile.encoding\=UTF-8