Loading core/java/android/app/admin/DevicePolicyManager.java +51 −9 Original line number Diff line number Diff line Loading @@ -2678,7 +2678,10 @@ public class DevicePolicyManager { * only imposed if the administrator has also requested either {@link #PASSWORD_QUALITY_NUMERIC} * , {@link #PASSWORD_QUALITY_NUMERIC_COMPLEX}, {@link #PASSWORD_QUALITY_ALPHABETIC}, * {@link #PASSWORD_QUALITY_ALPHANUMERIC}, or {@link #PASSWORD_QUALITY_COMPLEX} with * {@link #setPasswordQuality}. * {@link #setPasswordQuality}. If an app targeting SDK level * {@link android.os.Build.VERSION_CODES#R} and above enforces this constraint without settings * password quality to one of these values first, this method will throw * {@link IllegalStateException}. * <p> * On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the * password is always treated as empty. Loading @@ -2696,6 +2699,9 @@ public class DevicePolicyManager { * restriction. * @throws SecurityException if {@code admin} is not an active administrator or {@code admin} * does not use {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} * @throws IllegalStateException if the calling app is targeting SDK level * {@link android.os.Build.VERSION_CODES#R} and above and didn't set a sufficient password * quality requirement prior to calling this method. */ public void setPasswordMinimumLength(@NonNull ComponentName admin, int length) { if (mService != null) { Loading Loading @@ -2747,7 +2753,10 @@ public class DevicePolicyManager { * place immediately. To prompt the user for a new password, use * {@link #ACTION_SET_NEW_PASSWORD} or {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after * setting this value. This constraint is only imposed if the administrator has also requested * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. The default value is 0. * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. If an app targeting * SDK level {@link android.os.Build.VERSION_CODES#R} and above enforces this constraint without * settings password quality to {@link #PASSWORD_QUALITY_COMPLEX} first, this method will throw * {@link IllegalStateException}. The default value is 0. * <p> * On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the * password is always treated as empty. Loading @@ -2765,6 +2774,9 @@ public class DevicePolicyManager { * A value of 0 means there is no restriction. * @throws SecurityException if {@code admin} is not an active administrator or {@code admin} * does not use {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} * @throws IllegalStateException if the calling app is targeting SDK level * {@link android.os.Build.VERSION_CODES#R} and above and didn't set a sufficient password * quality requirement prior to calling this method. */ public void setPasswordMinimumUpperCase(@NonNull ComponentName admin, int length) { if (mService != null) { Loading Loading @@ -2823,7 +2835,10 @@ public class DevicePolicyManager { * place immediately. To prompt the user for a new password, use * {@link #ACTION_SET_NEW_PASSWORD} or {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after * setting this value. This constraint is only imposed if the administrator has also requested * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. The default value is 0. * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. If an app targeting * SDK level {@link android.os.Build.VERSION_CODES#R} and above enforces this constraint without * settings password quality to {@link #PASSWORD_QUALITY_COMPLEX} first, this method will throw * {@link IllegalStateException}. The default value is 0. * <p> * On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the * password is always treated as empty. Loading @@ -2841,6 +2856,9 @@ public class DevicePolicyManager { * A value of 0 means there is no restriction. * @throws SecurityException if {@code admin} is not an active administrator or {@code admin} * does not use {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} * @throws IllegalStateException if the calling app is targeting SDK level * {@link android.os.Build.VERSION_CODES#R} and above and didn't set a sufficient password * quality requirement prior to calling this method. */ public void setPasswordMinimumLowerCase(@NonNull ComponentName admin, int length) { if (mService != null) { Loading Loading @@ -2899,7 +2917,10 @@ public class DevicePolicyManager { * immediately. To prompt the user for a new password, use {@link #ACTION_SET_NEW_PASSWORD} or * {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after setting this value. This constraint is * only imposed if the administrator has also requested {@link #PASSWORD_QUALITY_COMPLEX} with * {@link #setPasswordQuality}. The default value is 1. * {@link #setPasswordQuality}. If an app targeting SDK level * {@link android.os.Build.VERSION_CODES#R} and above enforces this constraint without settings * password quality to {@link #PASSWORD_QUALITY_COMPLEX} first, this method will throw * {@link IllegalStateException}. The default value is 1. * <p> * On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the * password is always treated as empty. Loading @@ -2917,6 +2938,9 @@ public class DevicePolicyManager { * 0 means there is no restriction. * @throws SecurityException if {@code admin} is not an active administrator or {@code admin} * does not use {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} * @throws IllegalStateException if the calling app is targeting SDK level * {@link android.os.Build.VERSION_CODES#R} and above and didn't set a sufficient password * quality requirement prior to calling this method. */ public void setPasswordMinimumLetters(@NonNull ComponentName admin, int length) { if (mService != null) { Loading Loading @@ -2974,7 +2998,10 @@ public class DevicePolicyManager { * place immediately. To prompt the user for a new password, use * {@link #ACTION_SET_NEW_PASSWORD} or {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after * setting this value. This constraint is only imposed if the administrator has also requested * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. The default value is 1. * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. If an app targeting * SDK level {@link android.os.Build.VERSION_CODES#R} and above enforces this constraint without * settings password quality to {@link #PASSWORD_QUALITY_COMPLEX} first, this method will throw * {@link IllegalStateException}. The default value is 1. * <p> * On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the * password is always treated as empty. Loading @@ -2992,6 +3019,9 @@ public class DevicePolicyManager { * value of 0 means there is no restriction. * @throws SecurityException if {@code admin} is not an active administrator or {@code admin} * does not use {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} * @throws IllegalStateException if the calling app is targeting SDK level * {@link android.os.Build.VERSION_CODES#R} and above and didn't set a sufficient password * quality requirement prior to calling this method. */ public void setPasswordMinimumNumeric(@NonNull ComponentName admin, int length) { if (mService != null) { Loading Loading @@ -3049,7 +3079,10 @@ public class DevicePolicyManager { * immediately. To prompt the user for a new password, use {@link #ACTION_SET_NEW_PASSWORD} or * {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after setting this value. This constraint is * only imposed if the administrator has also requested {@link #PASSWORD_QUALITY_COMPLEX} with * {@link #setPasswordQuality}. The default value is 1. * {@link #setPasswordQuality}. If an app targeting SDK level * {@link android.os.Build.VERSION_CODES#R} and above enforces this constraint without settings * password quality to {@link #PASSWORD_QUALITY_COMPLEX} first, this method will throw * {@link IllegalStateException}. The default value is 1. * <p> * On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the * password is always treated as empty. Loading @@ -3067,6 +3100,9 @@ public class DevicePolicyManager { * 0 means there is no restriction. * @throws SecurityException if {@code admin} is not an active administrator or {@code admin} * does not use {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} * @throws IllegalStateException if the calling app is targeting SDK level * {@link android.os.Build.VERSION_CODES#R} and above and didn't set a sufficient password * quality requirement prior to calling this method. */ public void setPasswordMinimumSymbols(@NonNull ComponentName admin, int length) { if (mService != null) { Loading Loading @@ -3123,7 +3159,10 @@ public class DevicePolicyManager { * one, so the change does not take place immediately. To prompt the user for a new password, * use {@link #ACTION_SET_NEW_PASSWORD} or {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after * setting this value. This constraint is only imposed if the administrator has also requested * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. The default value is 0. * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. If an app targeting * SDK level {@link android.os.Build.VERSION_CODES#R} and above enforces this constraint without * settings password quality to {@link #PASSWORD_QUALITY_COMPLEX} first, this method will throw * {@link IllegalStateException}. The default value is 0. * <p> * On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the * password is always treated as empty. Loading @@ -3141,6 +3180,9 @@ public class DevicePolicyManager { * 0 means there is no restriction. * @throws SecurityException if {@code admin} is not an active administrator or {@code admin} * does not use {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} * @throws IllegalStateException if the calling app is targeting SDK level * {@link android.os.Build.VERSION_CODES#R} and above and didn't set a sufficient password * quality requirement prior to calling this method. */ public void setPasswordMinimumNonLetter(@NonNull ComponentName admin, int length) { if (mService != null) { Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +42 −1 Original line number Diff line number Diff line Loading @@ -4133,6 +4133,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final PasswordMetrics metrics = ap.minimumPasswordMetrics; if (metrics.quality != quality) { metrics.quality = quality; resetInactivePasswordRequirementsIfRPlus(userId, ap); updatePasswordValidityCheckpointLocked(userId, parent); updatePasswordQualityCacheForUserGroup(userId); saveSettingsLocked(userId); Loading @@ -4150,6 +4151,27 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { .write(); } /** * For admins targeting R+ reset various password constraints to default values when quality is * set to a value that makes those constraints that have no effect. */ private void resetInactivePasswordRequirementsIfRPlus(int userId, ActiveAdmin admin) { if (getTargetSdk(admin.info.getPackageName(), userId) > Build.VERSION_CODES.Q) { final PasswordMetrics metrics = admin.minimumPasswordMetrics; if (metrics.quality < PASSWORD_QUALITY_NUMERIC) { metrics.length = ActiveAdmin.DEF_MINIMUM_PASSWORD_LENGTH; } if (metrics.quality < PASSWORD_QUALITY_COMPLEX) { metrics.letters = ActiveAdmin.DEF_MINIMUM_PASSWORD_LETTERS; metrics.upperCase = ActiveAdmin.DEF_MINIMUM_PASSWORD_UPPER_CASE; metrics.lowerCase = ActiveAdmin.DEF_MINIMUM_PASSWORD_LOWER_CASE; metrics.numeric = ActiveAdmin.DEF_MINIMUM_PASSWORD_NUMERIC; metrics.symbols = ActiveAdmin.DEF_MINIMUM_PASSWORD_SYMBOLS; metrics.nonLetter = ActiveAdmin.DEF_MINIMUM_PASSWORD_NON_LETTER; } } } /** * Updates a flag that tells us whether the user's password currently satisfies the * requirements set by all of the user's active admins. The flag is updated both in memory Loading Loading @@ -4281,6 +4303,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { ActiveAdmin ap = getActiveAdminForCallerLocked( who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent); final PasswordMetrics metrics = ap.minimumPasswordMetrics; ensureMinimumQuality(userId, ap, PASSWORD_QUALITY_NUMERIC, "setPasswordMinimumLength"); if (metrics.length != length) { metrics.length = length; updatePasswordValidityCheckpointLocked(userId, parent); Loading @@ -4295,10 +4318,19 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { .write(); } private void ensureMinimumQuality( int userId, ActiveAdmin admin, int minimumQuality, String operation) { if (admin.minimumPasswordMetrics.quality < minimumQuality && getTargetSdk(admin.info.getPackageName(), userId) > Build.VERSION_CODES.Q) { throw new IllegalStateException(String.format( "password quality should be at least %d for %s", minimumQuality, operation)); } } @Override public int getPasswordMinimumLength(ComponentName who, int userHandle, boolean parent) { return getStrictestPasswordRequirement(who, userHandle, parent, admin -> admin.minimumPasswordMetrics.length, PASSWORD_QUALITY_UNSPECIFIED); admin -> admin.minimumPasswordMetrics.length, PASSWORD_QUALITY_NUMERIC); } @Override Loading Loading @@ -4525,6 +4557,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { synchronized (getLockObject()) { final ActiveAdmin ap = getActiveAdminForCallerLocked( who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent); ensureMinimumQuality( userId, ap, PASSWORD_QUALITY_COMPLEX, "setPasswordMinimumUpperCase"); final PasswordMetrics metrics = ap.minimumPasswordMetrics; if (metrics.upperCase != length) { metrics.upperCase = length; Loading Loading @@ -4553,6 +4587,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { synchronized (getLockObject()) { ActiveAdmin ap = getActiveAdminForCallerLocked( who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent); ensureMinimumQuality( userId, ap, PASSWORD_QUALITY_COMPLEX, "setPasswordMinimumLowerCase"); final PasswordMetrics metrics = ap.minimumPasswordMetrics; if (metrics.lowerCase != length) { metrics.lowerCase = length; Loading Loading @@ -4584,6 +4620,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { synchronized (getLockObject()) { ActiveAdmin ap = getActiveAdminForCallerLocked( who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent); ensureMinimumQuality(userId, ap, PASSWORD_QUALITY_COMPLEX, "setPasswordMinimumLetters"); final PasswordMetrics metrics = ap.minimumPasswordMetrics; if (metrics.letters != length) { metrics.letters = length; Loading Loading @@ -4615,6 +4652,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { synchronized (getLockObject()) { ActiveAdmin ap = getActiveAdminForCallerLocked( who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent); ensureMinimumQuality(userId, ap, PASSWORD_QUALITY_COMPLEX, "setPasswordMinimumNumeric"); final PasswordMetrics metrics = ap.minimumPasswordMetrics; if (metrics.numeric != length) { metrics.numeric = length; Loading Loading @@ -4646,6 +4684,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { synchronized (getLockObject()) { ActiveAdmin ap = getActiveAdminForCallerLocked( who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent); ensureMinimumQuality(userId, ap, PASSWORD_QUALITY_COMPLEX, "setPasswordMinimumSymbols"); final PasswordMetrics metrics = ap.minimumPasswordMetrics; if (metrics.symbols != length) { ap.minimumPasswordMetrics.symbols = length; Loading Loading @@ -4677,6 +4716,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { synchronized (getLockObject()) { ActiveAdmin ap = getActiveAdminForCallerLocked( who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent); ensureMinimumQuality( userId, ap, PASSWORD_QUALITY_COMPLEX, "setPasswordMinimumNonLetter"); final PasswordMetrics metrics = ap.minimumPasswordMetrics; if (metrics.nonLetter != length) { ap.minimumPasswordMetrics.nonLetter = length; Loading Loading
core/java/android/app/admin/DevicePolicyManager.java +51 −9 Original line number Diff line number Diff line Loading @@ -2678,7 +2678,10 @@ public class DevicePolicyManager { * only imposed if the administrator has also requested either {@link #PASSWORD_QUALITY_NUMERIC} * , {@link #PASSWORD_QUALITY_NUMERIC_COMPLEX}, {@link #PASSWORD_QUALITY_ALPHABETIC}, * {@link #PASSWORD_QUALITY_ALPHANUMERIC}, or {@link #PASSWORD_QUALITY_COMPLEX} with * {@link #setPasswordQuality}. * {@link #setPasswordQuality}. If an app targeting SDK level * {@link android.os.Build.VERSION_CODES#R} and above enforces this constraint without settings * password quality to one of these values first, this method will throw * {@link IllegalStateException}. * <p> * On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the * password is always treated as empty. Loading @@ -2696,6 +2699,9 @@ public class DevicePolicyManager { * restriction. * @throws SecurityException if {@code admin} is not an active administrator or {@code admin} * does not use {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} * @throws IllegalStateException if the calling app is targeting SDK level * {@link android.os.Build.VERSION_CODES#R} and above and didn't set a sufficient password * quality requirement prior to calling this method. */ public void setPasswordMinimumLength(@NonNull ComponentName admin, int length) { if (mService != null) { Loading Loading @@ -2747,7 +2753,10 @@ public class DevicePolicyManager { * place immediately. To prompt the user for a new password, use * {@link #ACTION_SET_NEW_PASSWORD} or {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after * setting this value. This constraint is only imposed if the administrator has also requested * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. The default value is 0. * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. If an app targeting * SDK level {@link android.os.Build.VERSION_CODES#R} and above enforces this constraint without * settings password quality to {@link #PASSWORD_QUALITY_COMPLEX} first, this method will throw * {@link IllegalStateException}. The default value is 0. * <p> * On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the * password is always treated as empty. Loading @@ -2765,6 +2774,9 @@ public class DevicePolicyManager { * A value of 0 means there is no restriction. * @throws SecurityException if {@code admin} is not an active administrator or {@code admin} * does not use {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} * @throws IllegalStateException if the calling app is targeting SDK level * {@link android.os.Build.VERSION_CODES#R} and above and didn't set a sufficient password * quality requirement prior to calling this method. */ public void setPasswordMinimumUpperCase(@NonNull ComponentName admin, int length) { if (mService != null) { Loading Loading @@ -2823,7 +2835,10 @@ public class DevicePolicyManager { * place immediately. To prompt the user for a new password, use * {@link #ACTION_SET_NEW_PASSWORD} or {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after * setting this value. This constraint is only imposed if the administrator has also requested * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. The default value is 0. * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. If an app targeting * SDK level {@link android.os.Build.VERSION_CODES#R} and above enforces this constraint without * settings password quality to {@link #PASSWORD_QUALITY_COMPLEX} first, this method will throw * {@link IllegalStateException}. The default value is 0. * <p> * On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the * password is always treated as empty. Loading @@ -2841,6 +2856,9 @@ public class DevicePolicyManager { * A value of 0 means there is no restriction. * @throws SecurityException if {@code admin} is not an active administrator or {@code admin} * does not use {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} * @throws IllegalStateException if the calling app is targeting SDK level * {@link android.os.Build.VERSION_CODES#R} and above and didn't set a sufficient password * quality requirement prior to calling this method. */ public void setPasswordMinimumLowerCase(@NonNull ComponentName admin, int length) { if (mService != null) { Loading Loading @@ -2899,7 +2917,10 @@ public class DevicePolicyManager { * immediately. To prompt the user for a new password, use {@link #ACTION_SET_NEW_PASSWORD} or * {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after setting this value. This constraint is * only imposed if the administrator has also requested {@link #PASSWORD_QUALITY_COMPLEX} with * {@link #setPasswordQuality}. The default value is 1. * {@link #setPasswordQuality}. If an app targeting SDK level * {@link android.os.Build.VERSION_CODES#R} and above enforces this constraint without settings * password quality to {@link #PASSWORD_QUALITY_COMPLEX} first, this method will throw * {@link IllegalStateException}. The default value is 1. * <p> * On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the * password is always treated as empty. Loading @@ -2917,6 +2938,9 @@ public class DevicePolicyManager { * 0 means there is no restriction. * @throws SecurityException if {@code admin} is not an active administrator or {@code admin} * does not use {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} * @throws IllegalStateException if the calling app is targeting SDK level * {@link android.os.Build.VERSION_CODES#R} and above and didn't set a sufficient password * quality requirement prior to calling this method. */ public void setPasswordMinimumLetters(@NonNull ComponentName admin, int length) { if (mService != null) { Loading Loading @@ -2974,7 +2998,10 @@ public class DevicePolicyManager { * place immediately. To prompt the user for a new password, use * {@link #ACTION_SET_NEW_PASSWORD} or {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after * setting this value. This constraint is only imposed if the administrator has also requested * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. The default value is 1. * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. If an app targeting * SDK level {@link android.os.Build.VERSION_CODES#R} and above enforces this constraint without * settings password quality to {@link #PASSWORD_QUALITY_COMPLEX} first, this method will throw * {@link IllegalStateException}. The default value is 1. * <p> * On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the * password is always treated as empty. Loading @@ -2992,6 +3019,9 @@ public class DevicePolicyManager { * value of 0 means there is no restriction. * @throws SecurityException if {@code admin} is not an active administrator or {@code admin} * does not use {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} * @throws IllegalStateException if the calling app is targeting SDK level * {@link android.os.Build.VERSION_CODES#R} and above and didn't set a sufficient password * quality requirement prior to calling this method. */ public void setPasswordMinimumNumeric(@NonNull ComponentName admin, int length) { if (mService != null) { Loading Loading @@ -3049,7 +3079,10 @@ public class DevicePolicyManager { * immediately. To prompt the user for a new password, use {@link #ACTION_SET_NEW_PASSWORD} or * {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after setting this value. This constraint is * only imposed if the administrator has also requested {@link #PASSWORD_QUALITY_COMPLEX} with * {@link #setPasswordQuality}. The default value is 1. * {@link #setPasswordQuality}. If an app targeting SDK level * {@link android.os.Build.VERSION_CODES#R} and above enforces this constraint without settings * password quality to {@link #PASSWORD_QUALITY_COMPLEX} first, this method will throw * {@link IllegalStateException}. The default value is 1. * <p> * On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the * password is always treated as empty. Loading @@ -3067,6 +3100,9 @@ public class DevicePolicyManager { * 0 means there is no restriction. * @throws SecurityException if {@code admin} is not an active administrator or {@code admin} * does not use {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} * @throws IllegalStateException if the calling app is targeting SDK level * {@link android.os.Build.VERSION_CODES#R} and above and didn't set a sufficient password * quality requirement prior to calling this method. */ public void setPasswordMinimumSymbols(@NonNull ComponentName admin, int length) { if (mService != null) { Loading Loading @@ -3123,7 +3159,10 @@ public class DevicePolicyManager { * one, so the change does not take place immediately. To prompt the user for a new password, * use {@link #ACTION_SET_NEW_PASSWORD} or {@link #ACTION_SET_NEW_PARENT_PROFILE_PASSWORD} after * setting this value. This constraint is only imposed if the administrator has also requested * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. The default value is 0. * {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}. If an app targeting * SDK level {@link android.os.Build.VERSION_CODES#R} and above enforces this constraint without * settings password quality to {@link #PASSWORD_QUALITY_COMPLEX} first, this method will throw * {@link IllegalStateException}. The default value is 0. * <p> * On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the * password is always treated as empty. Loading @@ -3141,6 +3180,9 @@ public class DevicePolicyManager { * 0 means there is no restriction. * @throws SecurityException if {@code admin} is not an active administrator or {@code admin} * does not use {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} * @throws IllegalStateException if the calling app is targeting SDK level * {@link android.os.Build.VERSION_CODES#R} and above and didn't set a sufficient password * quality requirement prior to calling this method. */ public void setPasswordMinimumNonLetter(@NonNull ComponentName admin, int length) { if (mService != null) { Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +42 −1 Original line number Diff line number Diff line Loading @@ -4133,6 +4133,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final PasswordMetrics metrics = ap.minimumPasswordMetrics; if (metrics.quality != quality) { metrics.quality = quality; resetInactivePasswordRequirementsIfRPlus(userId, ap); updatePasswordValidityCheckpointLocked(userId, parent); updatePasswordQualityCacheForUserGroup(userId); saveSettingsLocked(userId); Loading @@ -4150,6 +4151,27 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { .write(); } /** * For admins targeting R+ reset various password constraints to default values when quality is * set to a value that makes those constraints that have no effect. */ private void resetInactivePasswordRequirementsIfRPlus(int userId, ActiveAdmin admin) { if (getTargetSdk(admin.info.getPackageName(), userId) > Build.VERSION_CODES.Q) { final PasswordMetrics metrics = admin.minimumPasswordMetrics; if (metrics.quality < PASSWORD_QUALITY_NUMERIC) { metrics.length = ActiveAdmin.DEF_MINIMUM_PASSWORD_LENGTH; } if (metrics.quality < PASSWORD_QUALITY_COMPLEX) { metrics.letters = ActiveAdmin.DEF_MINIMUM_PASSWORD_LETTERS; metrics.upperCase = ActiveAdmin.DEF_MINIMUM_PASSWORD_UPPER_CASE; metrics.lowerCase = ActiveAdmin.DEF_MINIMUM_PASSWORD_LOWER_CASE; metrics.numeric = ActiveAdmin.DEF_MINIMUM_PASSWORD_NUMERIC; metrics.symbols = ActiveAdmin.DEF_MINIMUM_PASSWORD_SYMBOLS; metrics.nonLetter = ActiveAdmin.DEF_MINIMUM_PASSWORD_NON_LETTER; } } } /** * Updates a flag that tells us whether the user's password currently satisfies the * requirements set by all of the user's active admins. The flag is updated both in memory Loading Loading @@ -4281,6 +4303,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { ActiveAdmin ap = getActiveAdminForCallerLocked( who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent); final PasswordMetrics metrics = ap.minimumPasswordMetrics; ensureMinimumQuality(userId, ap, PASSWORD_QUALITY_NUMERIC, "setPasswordMinimumLength"); if (metrics.length != length) { metrics.length = length; updatePasswordValidityCheckpointLocked(userId, parent); Loading @@ -4295,10 +4318,19 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { .write(); } private void ensureMinimumQuality( int userId, ActiveAdmin admin, int minimumQuality, String operation) { if (admin.minimumPasswordMetrics.quality < minimumQuality && getTargetSdk(admin.info.getPackageName(), userId) > Build.VERSION_CODES.Q) { throw new IllegalStateException(String.format( "password quality should be at least %d for %s", minimumQuality, operation)); } } @Override public int getPasswordMinimumLength(ComponentName who, int userHandle, boolean parent) { return getStrictestPasswordRequirement(who, userHandle, parent, admin -> admin.minimumPasswordMetrics.length, PASSWORD_QUALITY_UNSPECIFIED); admin -> admin.minimumPasswordMetrics.length, PASSWORD_QUALITY_NUMERIC); } @Override Loading Loading @@ -4525,6 +4557,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { synchronized (getLockObject()) { final ActiveAdmin ap = getActiveAdminForCallerLocked( who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent); ensureMinimumQuality( userId, ap, PASSWORD_QUALITY_COMPLEX, "setPasswordMinimumUpperCase"); final PasswordMetrics metrics = ap.minimumPasswordMetrics; if (metrics.upperCase != length) { metrics.upperCase = length; Loading Loading @@ -4553,6 +4587,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { synchronized (getLockObject()) { ActiveAdmin ap = getActiveAdminForCallerLocked( who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent); ensureMinimumQuality( userId, ap, PASSWORD_QUALITY_COMPLEX, "setPasswordMinimumLowerCase"); final PasswordMetrics metrics = ap.minimumPasswordMetrics; if (metrics.lowerCase != length) { metrics.lowerCase = length; Loading Loading @@ -4584,6 +4620,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { synchronized (getLockObject()) { ActiveAdmin ap = getActiveAdminForCallerLocked( who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent); ensureMinimumQuality(userId, ap, PASSWORD_QUALITY_COMPLEX, "setPasswordMinimumLetters"); final PasswordMetrics metrics = ap.minimumPasswordMetrics; if (metrics.letters != length) { metrics.letters = length; Loading Loading @@ -4615,6 +4652,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { synchronized (getLockObject()) { ActiveAdmin ap = getActiveAdminForCallerLocked( who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent); ensureMinimumQuality(userId, ap, PASSWORD_QUALITY_COMPLEX, "setPasswordMinimumNumeric"); final PasswordMetrics metrics = ap.minimumPasswordMetrics; if (metrics.numeric != length) { metrics.numeric = length; Loading Loading @@ -4646,6 +4684,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { synchronized (getLockObject()) { ActiveAdmin ap = getActiveAdminForCallerLocked( who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent); ensureMinimumQuality(userId, ap, PASSWORD_QUALITY_COMPLEX, "setPasswordMinimumSymbols"); final PasswordMetrics metrics = ap.minimumPasswordMetrics; if (metrics.symbols != length) { ap.minimumPasswordMetrics.symbols = length; Loading Loading @@ -4677,6 +4716,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { synchronized (getLockObject()) { ActiveAdmin ap = getActiveAdminForCallerLocked( who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent); ensureMinimumQuality( userId, ap, PASSWORD_QUALITY_COMPLEX, "setPasswordMinimumNonLetter"); final PasswordMetrics metrics = ap.minimumPasswordMetrics; if (metrics.nonLetter != length) { ap.minimumPasswordMetrics.nonLetter = length; Loading