diff options
3 files changed, 26 insertions, 4 deletions
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index c4458b30c2db..10309a9b4a03 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -4424,11 +4424,13 @@ public class DevicePolicyManager { * the current factory reset protection (FRP) policy set previously by * {@link #setFactoryResetProtectionPolicy}. * <p> - * This method can also be called by the FRP management agent on device, in which case, - * it can pass {@code null} as the ComponentName. + * This method can also be called by the FRP management agent on device or with the permission + * {@link android.Manifest.permission#MASTER_CLEAR}, in which case, it can pass {@code null} + * as the ComponentName. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with or - * {@code null} if called by the FRP management agent on device. + * {@code null} if called by the FRP management agent on device or with the + * permission {@link android.Manifest.permission#MASTER_CLEAR}. * @return The current FRP policy object or {@code null} if no policy is set. * @throws SecurityException if {@code admin} is not a device owner, a profile owner of * an organization-owned device or the FRP management agent. diff --git a/core/java/android/app/admin/FactoryResetProtectionPolicy.java b/core/java/android/app/admin/FactoryResetProtectionPolicy.java index 954db0459f99..aa94e817c152 100644 --- a/core/java/android/app/admin/FactoryResetProtectionPolicy.java +++ b/core/java/android/app/admin/FactoryResetProtectionPolicy.java @@ -43,6 +43,12 @@ import java.util.List; * reset protection policy for the device by calling the {@code DevicePolicyManager} method * {@link DevicePolicyManager#setFactoryResetProtectionPolicy(ComponentName, * FactoryResetProtectionPolicy)}}. + * <p> + * Normally factory reset protection does not kick in if the device is factory reset via Settings. + * This is also the case when a device owner sets factory reset protection policy. However, + * when a profile owner of an organization-owned device sets factory reset protection policy that + * locks the device to specific accounts, the policy will take effect even if factory reset is + * performed from Settings. * * @see DevicePolicyManager#setFactoryResetProtectionPolicy * @see DevicePolicyManager#getFactoryResetProtectionPolicy @@ -236,4 +242,16 @@ public final class FactoryResetProtectionPolicy implements Parcelable { } } + /** + * Returns if the policy will result in factory reset protection being locked to + * admin-specified accounts. + * <p> + * When a device has a non-empty factory reset protection policy, trusted factory reset + * via Settings will no longer remove factory reset protection from the device. + * @hide + */ + public boolean isNotEmpty() { + return !mFactoryResetProtectionAccounts.isEmpty() && mFactoryResetProtectionEnabled; + } + } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 09fab3e29fe0..e304bca4553c 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -7171,7 +7171,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { ActiveAdmin admin; synchronized (getLockObject()) { if (who == null) { - if ((frpManagementAgentUid != mInjector.binderGetCallingUid())) { + if ((frpManagementAgentUid != mInjector.binderGetCallingUid()) + && (mContext.checkCallingPermission(permission.MASTER_CLEAR) + != PackageManager.PERMISSION_GRANTED)) { throw new SecurityException( "Must be called by the FRP management agent on device"); } |