Content protection policy

Change targetSdk and compileSdk to 35
Fix GitHub action build.yml
Upgrade Compose BOM
This commit is contained in:
BinTianqi
2025-01-24 17:58:50 +08:00
parent a8392adb42
commit 6893ef58aa
16 changed files with 74 additions and 23 deletions

View File

@@ -20,7 +20,7 @@
android:enableOnBackInvokedCallback="true"
android:testOnly="false"
android:manageSpaceActivity=".ManageSpaceActivity"
tools:targetApi="34">
tools:targetApi="35">
<activity
android:name=".MainActivity"
android:exported="true"

View File

@@ -68,6 +68,7 @@ import com.bintianqi.owndroid.dpm.ChangeTime
import com.bintianqi.owndroid.dpm.ChangeTimeZone
import com.bintianqi.owndroid.dpm.ChangeUserIcon
import com.bintianqi.owndroid.dpm.ChangeUsername
import com.bintianqi.owndroid.dpm.ContentProtectionPolicy
import com.bintianqi.owndroid.dpm.CreateUser
import com.bintianqi.owndroid.dpm.CreateWorkProfile
import com.bintianqi.owndroid.dpm.CurrentUserInfo
@@ -233,6 +234,7 @@ fun Home(activity: FragmentActivity, vm: MyViewModel) {
composable(route = "ChangeTime") { ChangeTime(navCtrl) }
composable(route = "ChangeTimeZone") { ChangeTimeZone(navCtrl) }
//composable(route = "KeyPairs") { KeyPairs(navCtrl) }
composable(route = "ContentProtectionPolicy") { ContentProtectionPolicy(navCtrl) }
composable(route = "PermissionPolicy") { PermissionPolicy(navCtrl) }
composable(route = "MTEPolicy") { MTEPolicy(navCtrl) }
composable(route = "NearbyStreamingPolicy") { NearbyStreamingPolicy(navCtrl) }
@@ -412,9 +414,8 @@ private fun HomePage(navCtrl:NavHostController) {
HomePageItem(R.string.system, R.drawable.android_fill0, "System", navCtrl)
if(deviceOwner || profileOwner) { HomePageItem(R.string.network, R.drawable.wifi_fill0, "Network", navCtrl) }
if(
(VERSION.SDK_INT < 24 && !deviceOwner) || (
VERSION.SDK_INT >= 24 && (dpm.isProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE) ||
(profileOwner && dpm.isManagedProfile(receiver)))
(VERSION.SDK_INT < 24 && !deviceOwner) || (dpm.isProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE) ||
(profileOwner && dpm.isManagedProfile(receiver))
)
) {
HomePageItem(R.string.work_profile, R.drawable.work_fill0, "ManagedProfile", navCtrl)

View File

@@ -136,7 +136,7 @@ fun ApplicationManage(navCtrl:NavHostController, vm: MyViewModel) {
)
}
) { paddingValues->
NavHost(
@Suppress("NewApi") NavHost(
modifier = Modifier.padding(top = paddingValues.calculateTopPadding()),
navController = localNavCtrl, startDestination = "Home",
enterTransition = Animations.navHostEnterTransition,
@@ -225,7 +225,7 @@ private fun Home(navCtrl:NavHostController, pkgName: String) {
onCheckedChange = { appControlAction = 3; appControl(it) },
onClickBlank = { appControlAction = 3; dialogStatus = 4 }
)
if((VERSION.SDK_INT >= 33 && profileOwner) || (VERSION.SDK_INT >= 30 && deviceOwner)) {
if(VERSION.SDK_INT >= 30 && (deviceOwner || (VERSION.SDK_INT >= 33 && profileOwner))) {
FunctionItem(title = R.string.ucd, icon = R.drawable.do_not_touch_fill0) { navCtrl.navigate("UserControlDisabled") }
}
if(VERSION.SDK_INT>=23) {

View File

@@ -375,7 +375,7 @@ fun processSecurityLogs(securityEvents: List<SecurityLog.SecurityEvent>, outputS
@RequiresApi(24)
fun parseSecurityEventData(event: SecurityLog.SecurityEvent): JsonElement? {
return when(event.tag) { //TODO: backup service tag (API35)
return when(event.tag) {
SecurityLog.TAG_ADB_SHELL_CMD -> JsonPrimitive(event.data as String)
SecurityLog.TAG_ADB_SHELL_INTERACTIVE -> null
SecurityLog.TAG_APP_PROCESS_START -> {
@@ -389,6 +389,14 @@ fun parseSecurityEventData(event: SecurityLog.SecurityEvent): JsonElement? {
put("apk_hash", payload[5] as String)
}
}
SecurityLog.TAG_BACKUP_SERVICE_TOGGLED -> {
val payload = event.data as Array<*>
buildJsonObject {
put("admin", payload[0] as String)
put("admin_user_id", payload[1] as Int)
put("state", payload[2] as Int)
}
}
SecurityLog.TAG_BLUETOOTH_CONNECTION -> {
val payload = event.data as Array<*>
buildJsonObject {

View File

@@ -75,16 +75,16 @@ fun WorkProfile(navCtrl: NavHostController) {
if(VERSION.SDK_INT >= 30 && profileOwner && dpm.isManagedProfile(receiver)) {
FunctionItem(R.string.org_owned_work_profile, icon = R.drawable.corporate_fare_fill0) { navCtrl.navigate("OrgOwnedWorkProfile") }
}
if(VERSION.SDK_INT<24 || (VERSION.SDK_INT>=24 && dpm.isProvisioningAllowed(ACTION_PROVISION_MANAGED_PROFILE))) {
if(VERSION.SDK_INT < 24 || dpm.isProvisioningAllowed(ACTION_PROVISION_MANAGED_PROFILE)) {
FunctionItem(R.string.create_work_profile, icon = R.drawable.work_fill0) { navCtrl.navigate("CreateWorkProfile") }
}
if(dpm.isOrgProfile(receiver)) {
FunctionItem(R.string.suspend_personal_app, icon = R.drawable.block_fill0) { navCtrl.navigate("SuspendPersonalApp") }
}
if(profileOwner && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver)))) {
if(profileOwner && (VERSION.SDK_INT < 24 || dpm.isManagedProfile(receiver))) {
FunctionItem(R.string.intent_filter, icon = R.drawable.filter_alt_fill0) { navCtrl.navigate("IntentFilter") }
}
if(profileOwner && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver)))) {
if(profileOwner && (VERSION.SDK_INT < 24 || dpm.isManagedProfile(receiver))) {
FunctionItem(R.string.delete_work_profile, icon = R.drawable.delete_forever_fill0) { navCtrl.navigate("DeleteWorkProfile") }
}
}

View File

@@ -1081,7 +1081,7 @@ fun NetworkStats(navCtrl: NavHostController, vm: MyViewModel) {
}
}
if(VERSION.SDK_INT >= 24 && (target == NetworkStatsTarget.UidTag || target == NetworkStatsTarget.UidTagState))
ExposedDropdownMenuBox(
ExposedDropdownMenuBox(
activeTextField == NetworkStatsActiveTextField.Tag,
{ activeTextField == if(it) NetworkStatsActiveTextField.Tag else NetworkStatsActiveTextField.None }
) {
@@ -1155,7 +1155,7 @@ fun NetworkStats(navCtrl: NavHostController, vm: MyViewModel) {
querying = true
coroutine.launch {
val buckets = try {
if(queryType == 1) {
@Suppress("NewApi") if(queryType == 1) {
if(target == NetworkStatsTarget.Device)
listOf(nsm.querySummaryForDevice(networkType.type, subscriberId, startTime, endTime))
else listOf(nsm.querySummaryForUser(networkType.type, subscriberId, startTime, endTime))

View File

@@ -131,7 +131,7 @@ fun Permissions(navCtrl: NavHostController) {
if(VERSION.SDK_INT >= 26 && (deviceOwner || profileOwner))
FunctionItem(R.string.delegated_admins) { navCtrl.navigate("DelegatedAdmins") }
FunctionItem(R.string.device_info, icon = R.drawable.perm_device_information_fill0) { navCtrl.navigate("DeviceInfo") }
if((VERSION.SDK_INT >= 26 && deviceOwner) || (VERSION.SDK_INT >= 24 && profileOwner)) {
if(VERSION.SDK_INT >= 24 && (profileOwner || (VERSION.SDK_INT >= 26 && deviceOwner))) {
FunctionItem(R.string.org_name, icon = R.drawable.corporate_fare_fill0) { dialog = 2 }
}
if(VERSION.SDK_INT >= 31 && (profileOwner || deviceOwner)) {

View File

@@ -3,6 +3,7 @@ package com.bintianqi.owndroid.dpm
import android.annotation.SuppressLint
import android.app.ActivityOptions
import android.app.AlertDialog
import android.app.admin.DevicePolicyManager
import android.app.admin.DevicePolicyManager.FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY
import android.app.admin.DevicePolicyManager.InstallSystemUpdateCallback
import android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK
@@ -166,7 +167,7 @@ fun SystemManage(navCtrl: NavHostController) {
if(VERSION.SDK_INT >= 24 && deviceOwner) {
FunctionItem(R.string.reboot, icon = R.drawable.restart_alt_fill0) { dialog = 1 }
}
if(deviceOwner && ((VERSION.SDK_INT >= 28 && dpm.isAffiliatedUser) || VERSION.SDK_INT >= 24)) {
if(deviceOwner && VERSION.SDK_INT >= 24 && (VERSION.SDK_INT < 28 || dpm.isAffiliatedUser)) {
FunctionItem(R.string.bug_report, icon = R.drawable.bug_report_fill0) { dialog = 2 }
}
if(VERSION.SDK_INT >= 28 && (deviceOwner || dpm.isOrgProfile(receiver))) {
@@ -175,6 +176,8 @@ fun SystemManage(navCtrl: NavHostController) {
}
/*if(VERSION.SDK_INT >= 28 && (deviceOwner || profileOwner))
FunctionItem(R.string.key_pairs, icon = R.drawable.key_vertical_fill0) { navCtrl.navigate("KeyPairs") }*/
if(VERSION.SDK_INT >= 35 && (deviceOwner || (profileOwner && dpm.isAffiliatedUser)))
FunctionItem(R.string.content_protection_policy, icon = R.drawable.search_fill0) { navCtrl.navigate("ContentProtectionPolicy") }
if(VERSION.SDK_INT >= 23 && (deviceOwner || profileOwner)) {
FunctionItem(R.string.permission_policy, icon = R.drawable.key_fill0) { navCtrl.navigate("PermissionPolicy") }
}
@@ -274,7 +277,7 @@ fun SystemOptions(navCtrl: NavHostController) {
getState = { dpm.autoTimeRequired }, onCheckedChange = { dpm.setAutoTimeRequired(receiver,it) }, padding = false)
}
}
if(deviceOwner || (profileOwner && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && !dpm.isManagedProfile(receiver))))) {
if(deviceOwner || profileOwner) {
SwitchItem(R.string.master_mute, icon = R.drawable.volume_up_fill0,
getState = { dpm.isMasterVolumeMuted(receiver) }, onCheckedChange = { dpm.setMasterVolumeMuted(receiver,it) }
)
@@ -812,6 +815,37 @@ fun KeyPairs(navCtrl: NavHostController) {
}
}*/
@RequiresApi(35)
@Composable
fun ContentProtectionPolicy(navCtrl: NavHostController) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
var policy by remember { mutableIntStateOf(DevicePolicyManager.CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY) }
fun refresh() { policy = dpm.getContentProtectionPolicy(receiver) }
LaunchedEffect(Unit) { refresh() }
MyScaffold(R.string.content_protection_policy, 8.dp, navCtrl) {
mapOf(
DevicePolicyManager.CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY to R.string.not_controlled_by_policy,
DevicePolicyManager.CONTENT_PROTECTION_ENABLED to R.string.enabled,
DevicePolicyManager.CONTENT_PROTECTION_DISABLED to R.string.disabled
).forEach { (policyId, string) ->
RadioButtonItem(string, policy == policyId) { policy = policyId }
}
Button(
onClick = {
dpm.setContentProtectionPolicy(receiver, policy)
refresh()
context.showOperationResultToast(true)
},
modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp)
) {
Text(stringResource(R.string.apply))
}
InfoCard(R.string.info_content_protection_policy)
}
}
@RequiresApi(23)
@Composable
fun PermissionPolicy(navCtrl: NavHostController) {
@@ -1515,7 +1549,7 @@ fun WipeData(navCtrl: NavHostController) {
)
}
Spacer(Modifier.padding(vertical = 5.dp))
if(VERSION.SDK_INT < 34 || (VERSION.SDK_INT >= 34 && !userManager.isSystemUser)) {
if(VERSION.SDK_INT < 34 || !userManager.isSystemUser) {
Button(
onClick = {
focusMgr.clearFocus()

View File

@@ -35,7 +35,7 @@ fun UserRestriction(navCtrl:NavHostController) {
MyScaffold(R.string.user_restriction, 0.dp, navCtrl) {
Text(text = stringResource(R.string.switch_to_disable_feature), modifier = Modifier.padding(start = 16.dp))
if(context.isProfileOwner) { Text(text = stringResource(R.string.profile_owner_is_restricted), modifier = Modifier.padding(start = 16.dp)) }
if(context.isProfileOwner && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver)))) {
if(context.isProfileOwner && (VERSION.SDK_INT < 24 || dpm.isManagedProfile(receiver))) {
Text(text = stringResource(R.string.some_features_invalid_in_work_profile), modifier = Modifier.padding(start = 16.dp))
}
Spacer(Modifier.padding(vertical = 2.dp))

View File

@@ -176,6 +176,8 @@
<string name="change_timezone">Change timezone</string>
<string name="timezone_id">Идентификатор часового пояса</string>
<string name="disable_auto_time_zone_before_set">Автоматический часовой пояс должен быть отключен перед установкой пользовательского часового пояса.</string>
<string name="content_protection_policy">Content protection policy</string> <!--TODO-->
<string name="not_controlled_by_policy">Not controlled by policy</string> <!--TODO-->
<string name="permission_policy">Политика разрешений</string>
<string name="auto_grant">Автоматически разрешать</string>
<string name="auto_deny">Автоматически запрещать</string>

View File

@@ -178,6 +178,8 @@
<string name="change_timezone">Change timezone</string>
<string name="timezone_id">Saat dilimi kimliği</string>
<string name="disable_auto_time_zone_before_set">Özel bir saat dilimi ayarlamadan önce otomatik saat dilimi devre dışı bırakılmalıdır</string>
<string name="content_protection_policy">Content protection policy</string> <!--TODO-->
<string name="not_controlled_by_policy">Not controlled by policy</string> <!--TODO-->
<string name="permission_policy">İzin politikası</string>
<string name="auto_grant">Otomatik ver</string>
<string name="auto_deny">Otomatik reddet</string>

View File

@@ -169,6 +169,8 @@
<string name="change_timezone">更改时区</string>
<string name="timezone_id">时区ID</string>
<string name="disable_auto_time_zone_before_set">在设置时区前需要关闭自动时区</string>
<string name="content_protection_policy">内容保护策略</string>
<string name="not_controlled_by_policy">不受策略控制</string>
<string name="permission_policy">权限策略</string>
<string name="auto_grant">自动允许</string>
<string name="auto_deny">自动拒绝</string>
@@ -664,6 +666,7 @@
<string name="info_evict_credential_encryption_key">从密钥环中移除用户的凭证加密密钥。用户需要再次输入凭证才能将密钥存储回密钥环中。为了保护用户数据,用户将重新启动</string>
<string name="info_reboot">打电话时不能使用此功能</string>
<string name="info_change_time">输入以毫秒为单位的UNIX时间</string>
<string name="info_content_protection_policy">内容保护策略控制对欺骗性应用程序的扫描。</string>
<string name="info_permission_policy">设置应用申请运行时权限时的默认选择</string>
<string name="info_mte_policy">设置内存标记扩展(Memory Tagging Extension)策略。重启设备以应用更改。</string>
<string name="info_nearby_app_streaming_policy">应用流式传输当app在虚拟显示器上启动传输这个app的视频流到附近的设备。</string>

View File

@@ -90,7 +90,6 @@
<string name="add_delegated_admin">Add delegated admin</string>
<string name="dhizuku_will_be_deactivated">Dhizuku will be deactivated</string>
<string name="reset_device_policy">Reset device policy</string>
<string name="activate_device_admin">Activate Device admin</string>
<string name="activate_device_admin_command" translatable="false">dpm set-active-admin com.bintianqi.owndroid/com.bintianqi.owndroid.Receiver</string>
<string name="activate_profile_owner_command" translatable="false">dpm set-profile-owner --user %1$s com.bintianqi.owndroid/com.bintianqi.owndroid.Receiver</string>
<string name="activate_device_owner_command" translatable="false">dpm set-device-owner com.bintianqi.owndroid/com.bintianqi.owndroid.Receiver</string>
@@ -139,7 +138,6 @@
<string name="dpm_activate_do_command" translatable="false">dpm set-device-owner com.bintianqi.owndroid/com.bintianqi.owndroid.Receiver</string>
<string name="activate_device_owner">Activate Device owner</string>
<string name="activate_org_profile">Activate organization-owned work profile</string>
<string name="shizuku_service_disconnected">Shizuku service disconnected</string>
<string name="accounts">Accounts</string>
<!--System-->
@@ -199,6 +197,8 @@
<string name="base_info">Base info</string>
<string name="individual_certificate">Individual certificate</string>
<string name="generate">Generate</string>-->
<string name="content_protection_policy">Content protection policy</string>
<string name="not_controlled_by_policy">Not controlled by policy</string>
<string name="permission_policy">Permission policy</string>
<string name="auto_grant">Auto grant</string>
<string name="auto_deny">Auto deny</string>
@@ -702,6 +702,7 @@
<string name="info_evict_credential_encryption_key">Evict the user\'s credential encryption key from the keyring. The user\'s credential will need to be entered again in order to derive the credential encryption key that will be stored back in the keyring for future use. In order to secure user data, the user will be stopped and restarted.</string>
<string name="info_reboot">You can\'t use this function if there is an ongoing call on the device.</string>
<string name="info_change_time">Input UNIX time in milliseconds</string>
<string name="info_content_protection_policy">Content protection policy controls scanning for deceptive apps.</string>
<string name="info_permission_policy">Set the default response for future runtime permission requests by applications.</string>
<string name="info_mte_policy">Set the Memory Tagging Extension policy. Reboot the device to apply changes.</string>
<string name="info_nearby_app_streaming_policy">App streaming is when the device starts an app on a virtual display and sends a video stream of the app to nearby devices.</string>