diff --git a/core/api/system-current.txt b/core/api/system-current.txt index a80de5a4e911e..952e145ff75fd 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -1115,6 +1115,7 @@ package android.app.admin { method public void setSecondaryLockscreenEnabled(@NonNull android.content.ComponentName, boolean); method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_MANAGEMENT_RESOURCES) public void setStrings(@NonNull java.util.Set); method @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public void setUserProvisioningState(int, @NonNull android.os.UserHandle); + method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public boolean shouldAllowBypassingDevicePolicyManagementRoleQualification(); field public static final String ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_ALLOWED = "android.account.DEVICE_OR_PROFILE_OWNER_ALLOWED"; field public static final String ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_DISALLOWED = "android.account.DEVICE_OR_PROFILE_OWNER_DISALLOWED"; field public static final String ACTION_BIND_SECONDARY_LOCKSCREEN_SERVICE = "android.app.action.BIND_SECONDARY_LOCKSCREEN_SERVICE"; diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 88094b78bc67a..8a521ec37ab09 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -15765,4 +15765,23 @@ public class DevicePolicyManager { } return deviceManagerConfig; } + + /** + * @return {@code true} if bypassing the device policy management role qualification is allowed + * with the current state of the device. + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) + public boolean shouldAllowBypassingDevicePolicyManagementRoleQualification() { + if (mService != null) { + try { + return mService.shouldAllowBypassingDevicePolicyManagementRoleQualification(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + return false; + } } diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index 77db146545926..fb1ca41ccc569 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -558,4 +558,6 @@ interface IDevicePolicyManager { void setStrings(in List strings); void resetStrings(in String[] stringIds); ParcelableResource getString(String stringId); + + boolean shouldAllowBypassingDevicePolicyManagementRoleQualification(); } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java index 200b120843ccc..ba00beea47cce 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java @@ -189,4 +189,9 @@ abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub { public ParcelableResource getString(String stringId) { return null; } + + @Override + public boolean shouldAllowBypassingDevicePolicyManagementRoleQualification() { + return false; + } } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 7dff614ba42ce..c79fcf3e4e6c5 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -18790,4 +18790,18 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { mInjector.binderWithCleanCallingIdentity(() -> Settings.Secure.putInt( mContext.getContentResolver(), MANAGED_PROVISIONING_DPC_DOWNLOADED, setTo)); } + + @Override + public boolean shouldAllowBypassingDevicePolicyManagementRoleQualification() { + Preconditions.checkCallAuthorization(hasCallingOrSelfPermission( + android.Manifest.permission.MANAGE_ROLE_HOLDERS)); + return mInjector.binderWithCleanCallingIdentity(() -> { + if (mUserManager.getUserCount() > 1) { + return false; + } + AccountManager am = AccountManager.get(mContext); + Account[] accounts = am.getAccounts(); + return accounts.length == 0; + }); + } }