Loading core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -6989,6 +6989,7 @@ package android.app.admin { method public boolean installKeyPair(@Nullable android.content.ComponentName, @NonNull java.security.PrivateKey, @NonNull java.security.cert.Certificate[], @NonNull String, int); method public void installSystemUpdate(@NonNull android.content.ComponentName, @NonNull android.net.Uri, @NonNull java.util.concurrent.Executor, @NonNull android.app.admin.DevicePolicyManager.InstallSystemUpdateCallback); method public boolean isActivePasswordSufficient(); method public boolean isActivePasswordSufficientForDeviceRequirement(); method public boolean isAdminActive(@NonNull android.content.ComponentName); method public boolean isAffiliatedUser(); method public boolean isAlwaysOnVpnLockdownEnabled(@NonNull android.content.ComponentName); core/java/android/app/admin/DevicePolicyManager.java +45 −0 Original line number Diff line number Diff line Loading @@ -3885,6 +3885,51 @@ public class DevicePolicyManager { return false; } /** * Called by profile owner of a managed profile to determine whether the current device password * meets policy requirements set explicitly device-wide. * <p> This API is similar to {@link #isActivePasswordSufficient()}, with two notable * differences: * <ul> * <li>this API always targets the device password. As a result it should always be called on * the {@link #getParentProfileInstance(ComponentName)} instance.</li> * <li>password policy requirement set on the managed profile is not taken into consideration * by this API, even if the device currently does not have a separate work challenge set.</li> * </ul> * * <p>This API is designed to facilite progressive password enrollment flows when the DPC * imposes both device and profile password policies. DPC applies profile password policy by * calling {@link #setPasswordQuality(ComponentName, int)} or * {@link #setRequiredPasswordComplexity} on the regular {@link DevicePolicyManager} instance, * while it applies device-wide policy by calling {@link #setRequiredPasswordComplexity} on the * {@link #getParentProfileInstance(ComponentName)} instance. The DPC can utilize this check to * guide the user to set a device password first taking into consideration the device-wide * policy only, and then prompt the user to either upgrade it to be fully compliant, or enroll a * separate work challenge to satisfy the profile password policy only. * * <p>The device user must be unlocked (@link {@link UserManager#isUserUnlocked(UserHandle)}) * to perform this check. * * @return {@code true} if the device password meets explicit requirement set on it, * {@code false} otherwise. * @throws SecurityException if the calling application is not a profile owner of a managed * profile, or if this API is not called on the parent DevicePolicyManager instance. * @throws IllegalStateException if the user isn't unlocked */ public boolean isActivePasswordSufficientForDeviceRequirement() { if (!mParentInstance) { throw new SecurityException("only callable on the parent instance"); } if (mService != null) { try { return mService.isActivePasswordSufficientForDeviceRequirement(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } return false; } /** * Returns how complex the current user's screen lock is. * Loading core/java/android/app/admin/IDevicePolicyManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ interface IDevicePolicyManager { long getPasswordExpiration(in ComponentName who, int userHandle, boolean parent); boolean isActivePasswordSufficient(int userHandle, boolean parent); boolean isActivePasswordSufficientForDeviceRequirement(); boolean isProfileActivePasswordSufficientForParent(int userHandle); boolean isPasswordSufficientAfterProfileUnification(int userHandle, int profileUser); int getPasswordComplexity(boolean parent); Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +37 −0 Original line number Diff line number Diff line Loading @@ -4164,6 +4164,43 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } @Override public boolean isActivePasswordSufficientForDeviceRequirement() { if (!mHasFeature) { return true; } final CallerIdentity caller = getCallerIdentity(); Preconditions.checkCallAuthorization(isProfileOwner(caller)); final int profileUserId = caller.getUserId(); Preconditions.checkCallingUser(isManagedProfile(profileUserId)); // This method is always called on the parent DPM instance to check if its password (i.e. // the device password) is sufficient for all explicit password requirement set on it // So retrieve the parent user Id to which the device password belongs. final int parentUser = getProfileParentId(profileUserId); enforceUserUnlocked(parentUser); synchronized (getLockObject()) { // Combine password policies across the user and its profiles. Profile admins are // excluded since we only want explicit password requirements, while profile admin // requirement are applicable only when the profile has unified challenge. List<ActiveAdmin> admins = getActiveAdminsForUserAndItsManagedProfilesLocked(parentUser, /* shouldIncludeProfileAdmins */ (user) -> false); ArrayList<PasswordMetrics> adminMetrics = new ArrayList<>(admins.size()); int maxRequiredComplexity = PASSWORD_COMPLEXITY_NONE; for (ActiveAdmin admin : admins) { adminMetrics.add(admin.mPasswordPolicy.getMinMetrics()); maxRequiredComplexity = Math.max(maxRequiredComplexity, admin.mPasswordComplexity); } PasswordMetrics metrics = mLockSettingsInternal.getUserPasswordMetrics(parentUser); return PasswordMetrics.validatePasswordMetrics(PasswordMetrics.merge(adminMetrics), maxRequiredComplexity, false, metrics).isEmpty(); } } @Override public boolean isUsingUnifiedPassword(ComponentName admin) { if (!mHasFeature) { Loading Loading
core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -6989,6 +6989,7 @@ package android.app.admin { method public boolean installKeyPair(@Nullable android.content.ComponentName, @NonNull java.security.PrivateKey, @NonNull java.security.cert.Certificate[], @NonNull String, int); method public void installSystemUpdate(@NonNull android.content.ComponentName, @NonNull android.net.Uri, @NonNull java.util.concurrent.Executor, @NonNull android.app.admin.DevicePolicyManager.InstallSystemUpdateCallback); method public boolean isActivePasswordSufficient(); method public boolean isActivePasswordSufficientForDeviceRequirement(); method public boolean isAdminActive(@NonNull android.content.ComponentName); method public boolean isAffiliatedUser(); method public boolean isAlwaysOnVpnLockdownEnabled(@NonNull android.content.ComponentName);
core/java/android/app/admin/DevicePolicyManager.java +45 −0 Original line number Diff line number Diff line Loading @@ -3885,6 +3885,51 @@ public class DevicePolicyManager { return false; } /** * Called by profile owner of a managed profile to determine whether the current device password * meets policy requirements set explicitly device-wide. * <p> This API is similar to {@link #isActivePasswordSufficient()}, with two notable * differences: * <ul> * <li>this API always targets the device password. As a result it should always be called on * the {@link #getParentProfileInstance(ComponentName)} instance.</li> * <li>password policy requirement set on the managed profile is not taken into consideration * by this API, even if the device currently does not have a separate work challenge set.</li> * </ul> * * <p>This API is designed to facilite progressive password enrollment flows when the DPC * imposes both device and profile password policies. DPC applies profile password policy by * calling {@link #setPasswordQuality(ComponentName, int)} or * {@link #setRequiredPasswordComplexity} on the regular {@link DevicePolicyManager} instance, * while it applies device-wide policy by calling {@link #setRequiredPasswordComplexity} on the * {@link #getParentProfileInstance(ComponentName)} instance. The DPC can utilize this check to * guide the user to set a device password first taking into consideration the device-wide * policy only, and then prompt the user to either upgrade it to be fully compliant, or enroll a * separate work challenge to satisfy the profile password policy only. * * <p>The device user must be unlocked (@link {@link UserManager#isUserUnlocked(UserHandle)}) * to perform this check. * * @return {@code true} if the device password meets explicit requirement set on it, * {@code false} otherwise. * @throws SecurityException if the calling application is not a profile owner of a managed * profile, or if this API is not called on the parent DevicePolicyManager instance. * @throws IllegalStateException if the user isn't unlocked */ public boolean isActivePasswordSufficientForDeviceRequirement() { if (!mParentInstance) { throw new SecurityException("only callable on the parent instance"); } if (mService != null) { try { return mService.isActivePasswordSufficientForDeviceRequirement(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } return false; } /** * Returns how complex the current user's screen lock is. * Loading
core/java/android/app/admin/IDevicePolicyManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ interface IDevicePolicyManager { long getPasswordExpiration(in ComponentName who, int userHandle, boolean parent); boolean isActivePasswordSufficient(int userHandle, boolean parent); boolean isActivePasswordSufficientForDeviceRequirement(); boolean isProfileActivePasswordSufficientForParent(int userHandle); boolean isPasswordSufficientAfterProfileUnification(int userHandle, int profileUser); int getPasswordComplexity(boolean parent); Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +37 −0 Original line number Diff line number Diff line Loading @@ -4164,6 +4164,43 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } @Override public boolean isActivePasswordSufficientForDeviceRequirement() { if (!mHasFeature) { return true; } final CallerIdentity caller = getCallerIdentity(); Preconditions.checkCallAuthorization(isProfileOwner(caller)); final int profileUserId = caller.getUserId(); Preconditions.checkCallingUser(isManagedProfile(profileUserId)); // This method is always called on the parent DPM instance to check if its password (i.e. // the device password) is sufficient for all explicit password requirement set on it // So retrieve the parent user Id to which the device password belongs. final int parentUser = getProfileParentId(profileUserId); enforceUserUnlocked(parentUser); synchronized (getLockObject()) { // Combine password policies across the user and its profiles. Profile admins are // excluded since we only want explicit password requirements, while profile admin // requirement are applicable only when the profile has unified challenge. List<ActiveAdmin> admins = getActiveAdminsForUserAndItsManagedProfilesLocked(parentUser, /* shouldIncludeProfileAdmins */ (user) -> false); ArrayList<PasswordMetrics> adminMetrics = new ArrayList<>(admins.size()); int maxRequiredComplexity = PASSWORD_COMPLEXITY_NONE; for (ActiveAdmin admin : admins) { adminMetrics.add(admin.mPasswordPolicy.getMinMetrics()); maxRequiredComplexity = Math.max(maxRequiredComplexity, admin.mPasswordComplexity); } PasswordMetrics metrics = mLockSettingsInternal.getUserPasswordMetrics(parentUser); return PasswordMetrics.validatePasswordMetrics(PasswordMetrics.merge(adminMetrics), maxRequiredComplexity, false, metrics).isEmpty(); } } @Override public boolean isUsingUnifiedPassword(ComponentName admin) { if (!mHasFeature) { Loading