diff options
| -rw-r--r-- | core/api/current.txt | 3 | ||||
| -rw-r--r-- | core/api/lint-baseline.txt | 10 | ||||
| -rw-r--r-- | core/api/module-lib-lint-baseline.txt | 4 | ||||
| -rw-r--r-- | core/api/system-lint-baseline.txt | 16 | ||||
| -rw-r--r-- | core/api/test-current.txt | 1 | ||||
| -rw-r--r-- | core/api/test-lint-baseline.txt | 4 | ||||
| -rw-r--r-- | core/java/android/app/admin/DevicePolicyIdentifiers.java | 7 | ||||
| -rw-r--r-- | core/java/android/app/admin/DevicePolicyManager.java | 97 | ||||
| -rw-r--r-- | core/java/android/app/admin/IDevicePolicyManager.aidl | 3 | ||||
| -rw-r--r-- | services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java | 87 | ||||
| -rw-r--r-- | services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java | 9 |
11 files changed, 230 insertions, 11 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index f17d4a2958f9..8306f30f8b41 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -7895,6 +7895,7 @@ package android.app.admin { field public static final String AUTO_TIME_POLICY = "autoTime"; field public static final String BACKUP_SERVICE_POLICY = "backupService"; field public static final String CAMERA_DISABLED_POLICY = "cameraDisabled"; + field @FlaggedApi("android.view.contentprotection.flags.manage_device_policy_enabled") public static final String CONTENT_PROTECTION_POLICY = "contentProtection"; field public static final String KEYGUARD_DISABLED_FEATURES_POLICY = "keyguardDisabledFeatures"; field public static final String LOCK_TASK_POLICY = "lockTask"; field public static final String PACKAGES_SUSPENDED_POLICY = "packagesSuspended"; @@ -7945,6 +7946,7 @@ package android.app.admin { method public boolean getBluetoothContactSharingDisabled(@NonNull android.content.ComponentName); method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_CAMERA, conditional=true) public boolean getCameraDisabled(@Nullable android.content.ComponentName); method @Deprecated @Nullable public String getCertInstallerPackage(@NonNull android.content.ComponentName) throws java.lang.SecurityException; + method @FlaggedApi("android.view.contentprotection.flags.manage_device_policy_enabled") @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_CONTENT_PROTECTION, conditional=true) public int getContentProtectionPolicy(@Nullable android.content.ComponentName); method @Nullable public android.app.admin.PackagePolicy getCredentialManagerPolicy(); method @Deprecated @Nullable public java.util.Set<java.lang.String> getCrossProfileCalendarPackages(@NonNull android.content.ComponentName); method @Deprecated public boolean getCrossProfileCallerIdDisabled(@NonNull android.content.ComponentName); @@ -8101,6 +8103,7 @@ package android.app.admin { method @Deprecated public void setCertInstallerPackage(@NonNull android.content.ComponentName, @Nullable String) throws java.lang.SecurityException; method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_COMMON_CRITERIA_MODE, conditional=true) public void setCommonCriteriaModeEnabled(@Nullable android.content.ComponentName, boolean); method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_WIFI, conditional=true) public void setConfiguredNetworksLockdownState(@Nullable android.content.ComponentName, boolean); + method @FlaggedApi("android.view.contentprotection.flags.manage_device_policy_enabled") @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_CONTENT_PROTECTION, conditional=true) public void setContentProtectionPolicy(@Nullable android.content.ComponentName, int); method public void setCredentialManagerPolicy(@Nullable android.app.admin.PackagePolicy); method @Deprecated public void setCrossProfileCalendarPackages(@NonNull android.content.ComponentName, @Nullable java.util.Set<java.lang.String>); method @Deprecated public void setCrossProfileCallerIdDisabled(@NonNull android.content.ComponentName, boolean); diff --git a/core/api/lint-baseline.txt b/core/api/lint-baseline.txt index 162f54cc6d5a..e901f00d5f5f 100644 --- a/core/api/lint-baseline.txt +++ b/core/api/lint-baseline.txt @@ -389,6 +389,12 @@ InvalidNullabilityOverride: android.media.midi.MidiUmpDeviceService#onBind(andro Invalid nullability on parameter `intent` in method `onBind`. Parameters of overrides cannot be NonNull if the super parameter is unannotated. +KotlinOperator: android.graphics.Matrix44#get(int, int): + Method can be invoked with an indexing operator from Kotlin: `get` (this is usually desirable; just make sure it makes sense for this type of object) +KotlinOperator: android.graphics.Matrix44#set(int, int, float): + Method can be invoked with an indexing operator from Kotlin: `set` (this is usually desirable; just make sure it makes sense for this type of object) + + RequiresPermission: android.accounts.AccountManager#getAccountsByTypeAndFeatures(String, String[], android.accounts.AccountManagerCallback<android.accounts.Account[]>, android.os.Handler): Method 'getAccountsByTypeAndFeatures' documentation mentions permissions without declaring @RequiresPermission RequiresPermission: android.accounts.AccountManager#hasFeatures(android.accounts.Account, String[], android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler): @@ -477,6 +483,8 @@ RequiresPermission: android.app.admin.DevicePolicyManager#clearResetPasswordToke Method 'clearResetPasswordToken' documentation mentions permissions already declared by @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#generateKeyPair(android.content.ComponentName, String, android.security.keystore.KeyGenParameterSpec, int): Method 'generateKeyPair' documentation mentions permissions already declared by @RequiresPermission +RequiresPermission: android.app.admin.DevicePolicyManager#getContentProtectionPolicy(android.content.ComponentName): + Method 'getContentProtectionPolicy' documentation mentions permissions already declared by @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#getCrossProfileWidgetProviders(android.content.ComponentName): Method 'getCrossProfileWidgetProviders' documentation mentions permissions already declared by @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#getLockTaskFeatures(android.content.ComponentName): @@ -513,6 +521,8 @@ RequiresPermission: android.app.admin.DevicePolicyManager#removeCrossProfileWidg Method 'removeCrossProfileWidgetProvider' documentation mentions permissions already declared by @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#setAlwaysOnVpnPackage(android.content.ComponentName, String, boolean): Method 'setAlwaysOnVpnPackage' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.app.admin.DevicePolicyManager#setContentProtectionPolicy(android.content.ComponentName, int): + Method 'setContentProtectionPolicy' documentation mentions permissions already declared by @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#setLockTaskFeatures(android.content.ComponentName, int): Method 'setLockTaskFeatures' documentation mentions permissions already declared by @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#setLockTaskPackages(android.content.ComponentName, String[]): diff --git a/core/api/module-lib-lint-baseline.txt b/core/api/module-lib-lint-baseline.txt index a2179bc59707..42c4efc139ca 100644 --- a/core/api/module-lib-lint-baseline.txt +++ b/core/api/module-lib-lint-baseline.txt @@ -611,6 +611,8 @@ RequiresPermission: android.app.admin.DevicePolicyManager#generateKeyPair(androi Method 'generateKeyPair' documentation mentions permissions already declared by @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#getApplicationExemptions(String): Method 'getApplicationExemptions' documentation mentions permissions already declared by @RequiresPermission +RequiresPermission: android.app.admin.DevicePolicyManager#getContentProtectionPolicy(android.content.ComponentName): + Method 'getContentProtectionPolicy' documentation mentions permissions already declared by @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#getCrossProfileWidgetProviders(android.content.ComponentName): Method 'getCrossProfileWidgetProviders' documentation mentions permissions already declared by @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#getLockTaskFeatures(android.content.ComponentName): @@ -657,6 +659,8 @@ RequiresPermission: android.app.admin.DevicePolicyManager#setAlwaysOnVpnPackage( Method 'setAlwaysOnVpnPackage' documentation mentions permissions without declaring @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#setApplicationExemptions(String, java.util.Set<java.lang.Integer>): Method 'setApplicationExemptions' documentation mentions permissions already declared by @RequiresPermission +RequiresPermission: android.app.admin.DevicePolicyManager#setContentProtectionPolicy(android.content.ComponentName, int): + Method 'setContentProtectionPolicy' documentation mentions permissions already declared by @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#setDeviceProvisioningConfigApplied(): Method 'setDeviceProvisioningConfigApplied' documentation mentions permissions already declared by @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#setLockTaskFeatures(android.content.ComponentName, int): diff --git a/core/api/system-lint-baseline.txt b/core/api/system-lint-baseline.txt index 6c83fd04b76b..8a485d2a8449 100644 --- a/core/api/system-lint-baseline.txt +++ b/core/api/system-lint-baseline.txt @@ -525,6 +525,10 @@ KotlinKeyword: android.app.Notification#when: Avoid field names that are Kotlin hard keywords ("when"); see https://android.github.io/kotlin-guides/interop.html#no-hard-keywords +KotlinOperator: android.hardware.camera2.extension.CharacteristicsMap#get(String): + Method can be invoked with an indexing operator from Kotlin: `get` (this is usually desirable; just make sure it makes sense for this type of object) + + ListenerLast: android.telephony.satellite.SatelliteManager#stopSatelliteTransmissionUpdates(android.telephony.satellite.SatelliteTransmissionUpdateCallback, java.util.concurrent.Executor, java.util.function.Consumer<java.lang.Integer>) parameter #1: Listeners should always be at end of argument list (method `stopSatelliteTransmissionUpdates`) ListenerLast: android.telephony.satellite.SatelliteManager#stopSatelliteTransmissionUpdates(android.telephony.satellite.SatelliteTransmissionUpdateCallback, java.util.concurrent.Executor, java.util.function.Consumer<java.lang.Integer>) parameter #2: @@ -685,6 +689,8 @@ RequiresPermission: android.app.admin.DevicePolicyManager#generateKeyPair(androi Method 'generateKeyPair' documentation mentions permissions already declared by @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#getApplicationExemptions(String): Method 'getApplicationExemptions' documentation mentions permissions already declared by @RequiresPermission +RequiresPermission: android.app.admin.DevicePolicyManager#getContentProtectionPolicy(android.content.ComponentName): + Method 'getContentProtectionPolicy' documentation mentions permissions already declared by @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#getCrossProfileWidgetProviders(android.content.ComponentName): Method 'getCrossProfileWidgetProviders' documentation mentions permissions already declared by @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#getLockTaskFeatures(android.content.ComponentName): @@ -731,6 +737,8 @@ RequiresPermission: android.app.admin.DevicePolicyManager#setAlwaysOnVpnPackage( Method 'setAlwaysOnVpnPackage' documentation mentions permissions without declaring @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#setApplicationExemptions(String, java.util.Set<java.lang.Integer>): Method 'setApplicationExemptions' documentation mentions permissions already declared by @RequiresPermission +RequiresPermission: android.app.admin.DevicePolicyManager#setContentProtectionPolicy(android.content.ComponentName, int): + Method 'setContentProtectionPolicy' documentation mentions permissions already declared by @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#setDeviceProvisioningConfigApplied(): Method 'setDeviceProvisioningConfigApplied' documentation mentions permissions already declared by @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#setLockTaskFeatures(android.content.ComponentName, int): @@ -2305,14 +2313,14 @@ UnflaggedApi: android.telephony.satellite.SatelliteManager.SatelliteException#Sa New API must be flagged with @FlaggedApi: constructor android.telephony.satellite.SatelliteManager.SatelliteException(int) UnflaggedApi: android.telephony.satellite.SatelliteManager.SatelliteException#getErrorCode(): New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteManager.SatelliteException.getErrorCode() -UnflaggedApi: android.telephony.satellite.SatelliteProvisionStateCallback: - New API must be flagged with @FlaggedApi: class android.telephony.satellite.SatelliteProvisionStateCallback -UnflaggedApi: android.telephony.satellite.SatelliteProvisionStateCallback#onSatelliteProvisionStateChanged(boolean): - New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteProvisionStateCallback.onSatelliteProvisionStateChanged(boolean) UnflaggedApi: android.telephony.satellite.SatelliteModemStateCallback: New API must be flagged with @FlaggedApi: class android.telephony.satellite.SatelliteModemStateCallback UnflaggedApi: android.telephony.satellite.SatelliteModemStateCallback#onSatelliteModemStateChanged(int): New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteModemStateCallback.onSatelliteModemStateChanged(int) +UnflaggedApi: android.telephony.satellite.SatelliteProvisionStateCallback: + New API must be flagged with @FlaggedApi: class android.telephony.satellite.SatelliteProvisionStateCallback +UnflaggedApi: android.telephony.satellite.SatelliteProvisionStateCallback#onSatelliteProvisionStateChanged(boolean): + New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteProvisionStateCallback.onSatelliteProvisionStateChanged(boolean) UnflaggedApi: android.telephony.satellite.SatelliteTransmissionUpdateCallback: New API must be flagged with @FlaggedApi: class android.telephony.satellite.SatelliteTransmissionUpdateCallback UnflaggedApi: android.telephony.satellite.SatelliteTransmissionUpdateCallback#onReceiveDatagramStateChanged(int, int, int): diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 4a048bd315a0..bbd6bde60adf 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -624,6 +624,7 @@ package android.app.admin { field public static final int OPERATION_SET_APPLICATION_HIDDEN = 15; // 0xf field public static final int OPERATION_SET_APPLICATION_RESTRICTIONS = 16; // 0x10 field public static final int OPERATION_SET_CAMERA_DISABLED = 31; // 0x1f + field @FlaggedApi("android.view.contentprotection.flags.manage_device_policy_enabled") public static final int OPERATION_SET_CONTENT_PROTECTION_POLICY = 41; // 0x29 field public static final int OPERATION_SET_FACTORY_RESET_PROTECTION_POLICY = 32; // 0x20 field public static final int OPERATION_SET_GLOBAL_PRIVATE_DNS = 33; // 0x21 field public static final int OPERATION_SET_KEEP_UNINSTALLED_PACKAGES = 17; // 0x11 diff --git a/core/api/test-lint-baseline.txt b/core/api/test-lint-baseline.txt index 5e904ef947c8..b938f0ffef76 100644 --- a/core/api/test-lint-baseline.txt +++ b/core/api/test-lint-baseline.txt @@ -673,6 +673,8 @@ RequiresPermission: android.app.admin.DevicePolicyManager#generateKeyPair(androi Method 'generateKeyPair' documentation mentions permissions already declared by @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#getApplicationExemptions(String): Method 'getApplicationExemptions' documentation mentions permissions already declared by @RequiresPermission +RequiresPermission: android.app.admin.DevicePolicyManager#getContentProtectionPolicy(android.content.ComponentName): + Method 'getContentProtectionPolicy' documentation mentions permissions already declared by @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#getCrossProfileWidgetProviders(android.content.ComponentName): Method 'getCrossProfileWidgetProviders' documentation mentions permissions already declared by @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#getLockTaskFeatures(android.content.ComponentName): @@ -721,6 +723,8 @@ RequiresPermission: android.app.admin.DevicePolicyManager#setAlwaysOnVpnPackage( Method 'setAlwaysOnVpnPackage' documentation mentions permissions without declaring @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#setApplicationExemptions(String, java.util.Set<java.lang.Integer>): Method 'setApplicationExemptions' documentation mentions permissions already declared by @RequiresPermission +RequiresPermission: android.app.admin.DevicePolicyManager#setContentProtectionPolicy(android.content.ComponentName, int): + Method 'setContentProtectionPolicy' documentation mentions permissions already declared by @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#setDeviceOwner(android.content.ComponentName, int): Method 'setDeviceOwner' documentation mentions permissions already declared by @RequiresPermission RequiresPermission: android.app.admin.DevicePolicyManager#setDeviceProvisioningConfigApplied(): diff --git a/core/java/android/app/admin/DevicePolicyIdentifiers.java b/core/java/android/app/admin/DevicePolicyIdentifiers.java index b0bec783555b..d7aafa010e1d 100644 --- a/core/java/android/app/admin/DevicePolicyIdentifiers.java +++ b/core/java/android/app/admin/DevicePolicyIdentifiers.java @@ -22,7 +22,6 @@ import android.annotation.TestApi; import android.app.admin.flags.Flags; import android.os.UserManager; - import java.util.Objects; /** @@ -163,6 +162,12 @@ public final class DevicePolicyIdentifiers { public static final String CROSS_PROFILE_WIDGET_PROVIDER_POLICY = "crossProfileWidgetProvider"; /** + * String identifier for {@link DevicePolicyManager#setContentProtectionPolicy}. + */ + @FlaggedApi(android.view.contentprotection.flags.Flags.FLAG_MANAGE_DEVICE_POLICY_ENABLED) + public static final String CONTENT_PROTECTION_POLICY = "contentProtection"; + + /** * String identifier for {@link DevicePolicyManager#setUsbDataSignalingEnabled}. */ @FlaggedApi(Flags.FLAG_POLICY_ENGINE_MIGRATION_V2_ENABLED) diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 86d0125fd7a2..1ef434633612 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -24,6 +24,7 @@ import static android.Manifest.permission.MANAGE_DEVICE_POLICY_APPS_CONTROL; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_CAMERA; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_CERTIFICATES; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_COMMON_CRITERIA_MODE; +import static android.Manifest.permission.MANAGE_DEVICE_POLICY_CONTENT_PROTECTION; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_DEFAULT_SMS; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_FACTORY_RESET; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_INPUT_METHODS; @@ -53,7 +54,6 @@ import static android.app.admin.flags.Flags.onboardingBugreportV2Enabled; import static android.content.Intent.LOCAL_FLAG_FROM_SYSTEM; import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1; import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE; -import static android.view.contentprotection.flags.Flags.FLAG_MANAGE_DEVICE_POLICY_ENABLED; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; @@ -3825,6 +3825,10 @@ public class DevicePolicyManager { /** @hide */ @TestApi public static final int OPERATION_UNINSTALL_CA_CERT = 40; + /** @hide */ + @TestApi + @FlaggedApi(android.view.contentprotection.flags.Flags.FLAG_MANAGE_DEVICE_POLICY_ENABLED) + public static final int OPERATION_SET_CONTENT_PROTECTION_POLICY = 41; private static final String PREFIX_OPERATION = "OPERATION_"; @@ -3869,7 +3873,8 @@ public class DevicePolicyManager { OPERATION_SET_PERMISSION_GRANT_STATE, OPERATION_SET_PERMISSION_POLICY, OPERATION_SET_RESTRICTIONS_PROVIDER, - OPERATION_UNINSTALL_CA_CERT + OPERATION_UNINSTALL_CA_CERT, + OPERATION_SET_CONTENT_PROTECTION_POLICY }) @Retention(RetentionPolicy.SOURCE) public static @interface DevicePolicyOperation { @@ -4095,15 +4100,15 @@ public class DevicePolicyManager { } /** Indicates that content protection is not controlled by policy, allowing user to choose. */ - @FlaggedApi(FLAG_MANAGE_DEVICE_POLICY_ENABLED) + @FlaggedApi(android.view.contentprotection.flags.Flags.FLAG_MANAGE_DEVICE_POLICY_ENABLED) public static final int CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY = 0; - /** Indicates that content protection is controlled and disabled by a policy. */ - @FlaggedApi(FLAG_MANAGE_DEVICE_POLICY_ENABLED) + /** Indicates that content protection is controlled and disabled by a policy (default). */ + @FlaggedApi(android.view.contentprotection.flags.Flags.FLAG_MANAGE_DEVICE_POLICY_ENABLED) public static final int CONTENT_PROTECTION_DISABLED = 1; /** Indicates that content protection is controlled and enabled by a policy. */ - @FlaggedApi(FLAG_MANAGE_DEVICE_POLICY_ENABLED) + @FlaggedApi(android.view.contentprotection.flags.Flags.FLAG_MANAGE_DEVICE_POLICY_ENABLED) public static final int CONTENT_PROTECTION_ENABLED = 2; /** @hide */ @@ -4118,6 +4123,86 @@ public class DevicePolicyManager { public @interface ContentProtectionPolicy {} /** + * Sets the content protection policy which controls scanning for deceptive apps. + * <p> + * This function can only be called by the device owner, a profile owner of an affiliated user + * or profile, or the profile owner when no device owner is set or holders of the permission + * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_CONTENT_PROTECTION}. See + * {@link #isAffiliatedUser}. + * Any policy set via this method will be cleared if the user becomes unaffiliated. + * <p> + * After the content protection policy has been set, + * {@link PolicyUpdateReceiver#onPolicySetResult(Context, String, Bundle, TargetUser, + * PolicyUpdateResult)} will notify the admin on whether the policy was successfully set or not. + * This callback will contain: + * <ul> + * <li> The policy identifier {@link DevicePolicyIdentifiers#CONTENT_PROTECTION_POLICY} + * <li> The {@link TargetUser} that this policy relates to + * <li> The {@link PolicyUpdateResult}, which will be + * {@link PolicyUpdateResult#RESULT_POLICY_SET} if the policy was successfully set or the + * reason the policy failed to be set + * (e.g. {@link PolicyUpdateResult#RESULT_FAILURE_CONFLICTING_ADMIN_POLICY}) + * </ul> + * If there has been a change to the policy, + * {@link PolicyUpdateReceiver#onPolicyChanged(Context, String, Bundle, TargetUser, + * PolicyUpdateResult)} will notify the admin of this change. This callback will contain the + * same parameters as PolicyUpdateReceiver#onPolicySetResult and the {@link PolicyUpdateResult} + * will contain the reason why the policy changed. + * + * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Null if the + * caller is not a device admin. + * @param policy The content protection policy to set. One of {@link + * #CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY}, + * {@link #CONTENT_PROTECTION_DISABLED} or {@link #CONTENT_PROTECTION_ENABLED}. + * @throws SecurityException if {@code admin} is not the device owner, the profile owner of an + * affiliated user or profile, or the profile owner when no device owner is set or holder of the + * permission {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_CONTENT_PROTECTION}. + * @see #isAffiliatedUser + */ + @RequiresPermission(value = MANAGE_DEVICE_POLICY_CONTENT_PROTECTION, conditional = true) + @SupportsCoexistence + @FlaggedApi(android.view.contentprotection.flags.Flags.FLAG_MANAGE_DEVICE_POLICY_ENABLED) + public void setContentProtectionPolicy( + @Nullable ComponentName admin, @ContentProtectionPolicy int policy) { + throwIfParentInstance("setContentProtectionPolicy"); + if (mService != null) { + try { + mService.setContentProtectionPolicy(admin, mContext.getPackageName(), policy); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + + /** + * Returns the current content protection policy. + * <p> + * The returned policy will be the current resolved policy rather than the policy set by the + * calling admin. + * + * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Null if the + * caller is not a device admin. + * @throws SecurityException if {@code admin} is not the device owner, the profile owner of an + * affiliated user or profile, or the profile owner when no device owner is set or holder of the + * permission {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_CONTENT_PROTECTION}. + * @see #isAffiliatedUser + * @see #setContentProtectionPolicy + */ + @RequiresPermission(value = MANAGE_DEVICE_POLICY_CONTENT_PROTECTION, conditional = true) + @FlaggedApi(android.view.contentprotection.flags.Flags.FLAG_MANAGE_DEVICE_POLICY_ENABLED) + public @ContentProtectionPolicy int getContentProtectionPolicy(@Nullable ComponentName admin) { + throwIfParentInstance("getContentProtectionPolicy"); + if (mService != null) { + try { + return mService.getContentProtectionPolicy(admin, mContext.getPackageName()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + return CONTENT_PROTECTION_DISABLED; + } + + /** * This object is a single place to tack on invalidation and disable calls. All * binder caches in this class derive from this Config, so all can be invalidated or * disabled through this Config. diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index 575fa4cac0b8..efcf5633515d 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -610,4 +610,7 @@ interface IDevicePolicyManager { String getFinancedDeviceKioskRoleHolder(String callerPackageName); void calculateHasIncompatibleAccounts(); + + void setContentProtectionPolicy(in ComponentName who, String callerPackageName, int policy); + int getContentProtectionPolicy(in ComponentName who, String callerPackageName); } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 781ff0dfd439..6f0985aecebd 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -34,6 +34,7 @@ import static android.Manifest.permission.MANAGE_DEVICE_POLICY_CALLS; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_CAMERA; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_CERTIFICATES; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_COMMON_CRITERIA_MODE; +import static android.Manifest.permission.MANAGE_DEVICE_POLICY_CONTENT_PROTECTION; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_DEBUGGING_FEATURES; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_DEFAULT_SMS; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_DISPLAY; @@ -110,6 +111,8 @@ import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEV import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE; import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_USER; import static android.app.admin.DevicePolicyManager.ACTION_SYSTEM_UPDATE_POLICY_CHANGED; +import static android.app.admin.DevicePolicyManager.CONTENT_PROTECTION_DISABLED; +import static android.app.admin.DevicePolicyManager.ContentProtectionPolicy; import static android.app.admin.DevicePolicyManager.DELEGATION_APP_RESTRICTIONS; import static android.app.admin.DevicePolicyManager.DELEGATION_BLOCK_UNINSTALL; import static android.app.admin.DevicePolicyManager.DELEGATION_CERT_INSTALL; @@ -23173,6 +23176,90 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } + private EnforcingAdmin enforceCanCallContentProtectionLocked( + ComponentName who, String callerPackageName) { + CallerIdentity caller = getCallerIdentity(who, callerPackageName); + final int userId = caller.getUserId(); + + EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( + who, + MANAGE_DEVICE_POLICY_CONTENT_PROTECTION, + caller.getPackageName(), + userId + ); + if ((isDeviceOwner(caller) || isProfileOwner(caller)) + && !canDPCManagedUserUseLockTaskLocked(userId)) { + throw new SecurityException( + "User " + userId + " is not allowed to use content protection"); + } + return enforcingAdmin; + } + + private void enforceCanQueryContentProtectionLocked( + ComponentName who, String callerPackageName) { + CallerIdentity caller = getCallerIdentity(who, callerPackageName); + final int userId = caller.getUserId(); + + enforceCanQuery(MANAGE_DEVICE_POLICY_CONTENT_PROTECTION, caller.getPackageName(), userId); + if ((isDeviceOwner(caller) || isProfileOwner(caller)) + && !canDPCManagedUserUseLockTaskLocked(userId)) { + throw new SecurityException( + "User " + userId + " is not allowed to use content protection"); + } + } + + @Override + public void setContentProtectionPolicy( + ComponentName who, String callerPackageName, @ContentProtectionPolicy int policy) + throws SecurityException { + if (!android.view.contentprotection.flags.Flags.manageDevicePolicyEnabled()) { + return; + } + + CallerIdentity caller = getCallerIdentity(who, callerPackageName); + checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_CONTENT_PROTECTION_POLICY); + + EnforcingAdmin enforcingAdmin; + synchronized (getLockObject()) { + enforcingAdmin = enforceCanCallContentProtectionLocked(who, caller.getPackageName()); + } + + if (policy == CONTENT_PROTECTION_DISABLED) { + mDevicePolicyEngine.removeLocalPolicy( + PolicyDefinition.CONTENT_PROTECTION, + enforcingAdmin, + caller.getUserId()); + } else { + mDevicePolicyEngine.setLocalPolicy( + PolicyDefinition.CONTENT_PROTECTION, + enforcingAdmin, + new IntegerPolicyValue(policy), + caller.getUserId()); + } + } + + @Override + public @ContentProtectionPolicy int getContentProtectionPolicy( + ComponentName who, String callerPackageName) { + if (!android.view.contentprotection.flags.Flags.manageDevicePolicyEnabled()) { + return CONTENT_PROTECTION_DISABLED; + } + + CallerIdentity caller = getCallerIdentity(who, callerPackageName); + final int userHandle = caller.getUserId(); + + synchronized (getLockObject()) { + enforceCanQueryContentProtectionLocked(who, caller.getPackageName()); + } + Integer policy = mDevicePolicyEngine.getResolvedPolicy( + PolicyDefinition.CONTENT_PROTECTION, userHandle); + if (policy == null) { + return CONTENT_PROTECTION_DISABLED; + } else { + return policy; + } + } + @Override public ManagedSubscriptionsPolicy getManagedSubscriptionsPolicy() { synchronized (getLockObject()) { diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java index 0fc8c5e7a46a..27f183445cfa 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java @@ -341,6 +341,13 @@ final class PolicyDefinition<V> { PolicyEnforcerCallbacks.setUsbDataSignalingEnabled(value, context), new BooleanPolicySerializer()); + static PolicyDefinition<Integer> CONTENT_PROTECTION = new PolicyDefinition<>( + new NoArgsPolicyKey(DevicePolicyIdentifiers.CONTENT_PROTECTION_POLICY), + new MostRecent<>(), + POLICY_FLAG_LOCAL_ONLY_POLICY, + (Integer value, Context context, Integer userId, PolicyKey policyKey) -> true, + new IntegerPolicySerializer()); + private static final Map<String, PolicyDefinition<?>> POLICY_DEFINITIONS = new HashMap<>(); private static Map<String, Integer> USER_RESTRICTION_FLAGS = new HashMap<>(); @@ -374,6 +381,8 @@ final class PolicyDefinition<V> { PERSONAL_APPS_SUSPENDED); POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.USB_DATA_SIGNALING_POLICY, USB_DATA_SIGNALING); + POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.CONTENT_PROTECTION_POLICY, + CONTENT_PROTECTION); // User Restriction Policies USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_MODIFY_ACCOUNTS, /* flags= */ 0); |