Loading services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java +0 −11 Original line number Diff line number Diff line Loading @@ -104,8 +104,6 @@ class ActiveAdmin { private static final String TAG_PASSWORD_HISTORY_LENGTH = "password-history-length"; private static final String TAG_MIN_PASSWORD_LENGTH = "min-password-length"; private static final String TAG_PASSWORD_QUALITY = "password-quality"; private static final String TAG_PASSWORD_QUALITY_APPLIES_TO_PARENT = "password-quality-applies-parent"; private static final String TAG_POLICIES = "policies"; private static final String TAG_CROSS_PROFILE_WIDGET_PROVIDERS = "cross-profile-widget-providers"; Loading Loading @@ -158,7 +156,6 @@ class ActiveAdmin { @NonNull PasswordPolicy mPasswordPolicy = new PasswordPolicy(); boolean mPasswordPolicyAppliesToParent = true; @DevicePolicyManager.PasswordComplexity int mPasswordComplexity = PASSWORD_COMPLEXITY_NONE; Loading Loading @@ -363,9 +360,6 @@ class ActiveAdmin { writeAttributeValueToXml( out, TAG_MIN_PASSWORD_NONLETTER, mPasswordPolicy.nonLetter); } writeAttributeValueToXml(out, TAG_PASSWORD_QUALITY_APPLIES_TO_PARENT, mPasswordPolicyAppliesToParent); } if (passwordHistoryLength != DEF_PASSWORD_HISTORY_LENGTH) { writeAttributeValueToXml( Loading Loading @@ -669,8 +663,6 @@ class ActiveAdmin { mPasswordPolicy.symbols = parser.getAttributeInt(null, ATTR_VALUE); } else if (TAG_MIN_PASSWORD_NONLETTER.equals(tag)) { mPasswordPolicy.nonLetter = parser.getAttributeInt(null, ATTR_VALUE); } else if (TAG_PASSWORD_QUALITY_APPLIES_TO_PARENT.equals(tag)) { mPasswordPolicyAppliesToParent = parser.getAttributeBoolean(null, ATTR_VALUE); } else if (TAG_MAX_TIME_TO_UNLOCK.equals(tag)) { maximumTimeToUnlock = parser.getAttributeLong(null, ATTR_VALUE); } else if (TAG_STRONG_AUTH_UNLOCK_TIMEOUT.equals(tag)) { Loading Loading @@ -1036,9 +1028,6 @@ class ActiveAdmin { pw.print("minimumPasswordNonLetter="); pw.println(mPasswordPolicy.nonLetter); pw.print("passwordPolicyAppliesToParent="); pw.println(mPasswordPolicyAppliesToParent); pw.print("maximumTimeToUnlock="); pw.println(maximumTimeToUnlock); Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +5 −17 Original line number Diff line number Diff line Loading @@ -3827,10 +3827,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { isProfileOwner(caller) || isDeviceOwner(caller) || isSystemUid(caller) || isPasswordLimitingAdminTargetingP(caller)); final boolean qualityMayApplyToParent = canSetPasswordQualityOnParent(who.getPackageName(), caller); if (!qualityMayApplyToParent) { Preconditions.checkCallAuthorization(!parent, if (parent) { Preconditions.checkCallAuthorization( canSetPasswordQualityOnParent(who.getPackageName(), caller), "Profile Owner may not apply password quality requirements device-wide"); } Loading @@ -3856,7 +3855,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (passwordPolicy.quality != quality) { passwordPolicy.quality = quality; ap.mPasswordComplexity = PASSWORD_COMPLEXITY_NONE; ap.mPasswordPolicyAppliesToParent = qualityMayApplyToParent; resetInactivePasswordRequirementsIfRPlus(userId, ap); updatePasswordValidityCheckpointLocked(userId, parent); updatePasswordQualityCacheForUserGroup(userId); Loading Loading @@ -4588,8 +4586,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } ArrayList<PasswordMetrics> adminMetrics = new ArrayList<>(); synchronized (getLockObject()) { final List<ActiveAdmin> admins; synchronized (getLockObject()) { if (deviceWideOnly) { admins = getActiveAdminsForUserAndItsManagedProfilesLocked(userId, /* shouldIncludeProfileAdmins */ (user) -> false); Loading @@ -4597,18 +4595,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { admins = getActiveAdminsForLockscreenPoliciesLocked(userId); } for (ActiveAdmin admin : admins) { final boolean isAdminOfUser = userId == admin.getUserHandle().getIdentifier(); // Use the password metrics from the admin in one of three cases: // (1) The admin is of the user we're getting the minimum metrics for. The admin // always affects the user it's managing. This applies also to the parent // ActiveAdmin instance: It'd have the same user handle. // (2) The mPasswordPolicyAppliesToParent field is true: That indicates the // call to setPasswordQuality was made by an admin that may affect the parent. if (isAdminOfUser || admin.mPasswordPolicyAppliesToParent) { adminMetrics.add(admin.mPasswordPolicy.getMinMetrics()); } } } return PasswordMetrics.merge(adminMetrics); } Loading Loading @@ -4821,7 +4810,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { admin.mPasswordComplexity = passwordComplexity; // Reset the password policy. admin.mPasswordPolicy = new PasswordPolicy(); admin.mPasswordPolicyAppliesToParent = true; updatePasswordValidityCheckpointLocked(caller.getUserId(), calledOnParent); updatePasswordQualityCacheForUserGroup(caller.getUserId()); saveSettingsLocked(caller.getUserId()); Loading services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +199 −0 Original line number Diff line number Diff line Loading @@ -5427,6 +5427,205 @@ public class DevicePolicyManagerTest extends DpmTestBase { } } @Test public void isActivePasswordSufficient_SeparateWorkChallenge_ProfileQualityRequirementMet() throws Exception { // Create work profile with empty separate challenge final int managedProfileUserId = 15; final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, /* separateChallenge */ true); // Set profile password quality requirement. No password added yet so // profile.isActivePasswordSufficient should return false mContext.binder.callingUid = managedProfileAdminUid; dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC); assertThat(dpm.isActivePasswordSufficient()).isFalse(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); // Set a work challenge and verify profile.isActivePasswordSufficient is now true when(getServices().lockSettingsInternal.getUserPasswordMetrics(managedProfileUserId)) .thenReturn(computeForPasswordOrPin("abcdXYZ5".getBytes(), /* isPin */ false)); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } @Test public void isActivePasswordSufficient_SeparateWorkChallenge_ProfileComplexityRequirementMet() throws Exception { // Create work profile with empty separate challenge final int managedProfileUserId = 15; final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, /* separateChallenge */ true); // Set profile password complexity requirement. No password added yet so // profile.isActivePasswordSufficient should return false mContext.binder.callingUid = managedProfileAdminUid; dpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_MEDIUM); assertThat(dpm.isActivePasswordSufficient()).isFalse(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); // Set a work challenge and verify profile.isActivePasswordSufficient is now true when(getServices().lockSettingsInternal.getUserPasswordMetrics(managedProfileUserId)) .thenReturn(computeForPasswordOrPin("5156".getBytes(), /* isPin */ true)); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } @Test public void isActivePasswordSufficient_SeparateWorkChallenge_ParentQualityRequirementMet() throws Exception { // Create work profile with empty separate challenge final int managedProfileUserId = 15; final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, /* separateChallenge */ true); // Set parent password quality requirement. No password added yet so // parent.isActivePasswordSufficient should return false mContext.binder.callingUid = managedProfileAdminUid; parentDpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isFalse(); // Set a device lockscreen and verify parent.isActivePasswordSufficient is now true when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) .thenReturn(computeForPasswordOrPin("acbdXYZ5".getBytes(), /* isPin */ false)); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } @Test public void isActivePasswordSufficient_SeparateWorkChallenge_ParentComplexityRequirementMet() throws Exception { // Create work profile with empty separate challenge final int managedProfileUserId = 15; final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, /* separateChallenge */ true); // Set parent password complexity requirement. No password added yet so // parent.isActivePasswordSufficient should return false mContext.binder.callingUid = managedProfileAdminUid; parentDpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_LOW); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isFalse(); // Set a device lockscreen and verify parent.isActivePasswordSufficient is now true when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) .thenReturn(computeForPasswordOrPin("1234".getBytes(), /* isPin */ true)); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } @Test public void isActivePasswordSufficient_UnifiedWorkChallenge_ProfileQualityRequirementMet() throws Exception { // Create work profile with unified challenge final int managedProfileUserId = 15; final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, /* separateChallenge */ false); // Set profile password quality requirement. No password added yet so // {profile, parent}.isActivePasswordSufficient should return false mContext.binder.callingUid = managedProfileAdminUid; dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC); assertThat(dpm.isActivePasswordSufficient()).isFalse(); assertThat(parentDpm.isActivePasswordSufficient()).isFalse(); // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) .thenReturn(computeForPasswordOrPin("abcdXYZ5".getBytes(), /* isPin */ false)); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } @Test public void isActivePasswordSufficient_UnifiedWorkChallenge_ProfileComplexityRequirementMet() throws Exception { // Create work profile with unified challenge final int managedProfileUserId = 15; final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, /* separateChallenge */ false); // Set profile password complexity requirement. No password added yet so // {profile, parent}.isActivePasswordSufficient should return false mContext.binder.callingUid = managedProfileAdminUid; dpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_HIGH); assertThat(dpm.isActivePasswordSufficient()).isFalse(); assertThat(parentDpm.isActivePasswordSufficient()).isFalse(); // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) .thenReturn(computeForPasswordOrPin("51567548".getBytes(), /* isPin */ true)); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } @Test public void isActivePasswordSufficient_UnifiedWorkChallenge_ParentQualityRequirementMet() throws Exception { // Create work profile with unified challenge final int managedProfileUserId = 15; final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, /* separateChallenge */ false); // Set parent password quality requirement. No password added yet so // {profile, parent}.isActivePasswordSufficient should return false mContext.binder.callingUid = managedProfileAdminUid; parentDpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC); assertThat(dpm.isActivePasswordSufficient()).isFalse(); assertThat(parentDpm.isActivePasswordSufficient()).isFalse(); // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) .thenReturn(computeForPasswordOrPin("abcdXYZ5".getBytes(), /* isPin */ false)); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } @Test public void isActivePasswordSufficient_UnifiedWorkChallenge_ParentComplexityRequirementMet() throws Exception { // Create work profile with unified challenge final int managedProfileUserId = 15; final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, /* separateChallenge */ false); // Set parent password complexity requirement. No password added yet so // {profile, parent}.isActivePasswordSufficient should return false mContext.binder.callingUid = managedProfileAdminUid; parentDpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_MEDIUM); assertThat(dpm.isActivePasswordSufficient()).isFalse(); assertThat(parentDpm.isActivePasswordSufficient()).isFalse(); // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) .thenReturn(computeForPasswordOrPin("5156".getBytes(), /* isPin */ true)); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } private void addManagedProfileForPasswordTests(int userId, int adminUid, boolean separateChallenge) throws Exception { addManagedProfile(admin1, adminUid, admin1); when(getServices().userManager.getProfileParent(userId)) .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); doReturn(separateChallenge).when(getServices().lockPatternUtils) .isSeparateProfileChallengeEnabled(userId); when(getServices().userManager.getCredentialOwnerProfile(userId)) .thenReturn(separateChallenge ? userId : UserHandle.USER_SYSTEM); when(getServices().lockSettingsInternal.getUserPasswordMetrics(userId)) .thenReturn(new PasswordMetrics(CREDENTIAL_TYPE_NONE)); when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) .thenReturn(new PasswordMetrics(CREDENTIAL_TYPE_NONE)); } @Test public void testPasswordQualityAppliesToParentPreS() throws Exception { final int managedProfileUserId = CALLER_USER_HANDLE; Loading Loading
services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java +0 −11 Original line number Diff line number Diff line Loading @@ -104,8 +104,6 @@ class ActiveAdmin { private static final String TAG_PASSWORD_HISTORY_LENGTH = "password-history-length"; private static final String TAG_MIN_PASSWORD_LENGTH = "min-password-length"; private static final String TAG_PASSWORD_QUALITY = "password-quality"; private static final String TAG_PASSWORD_QUALITY_APPLIES_TO_PARENT = "password-quality-applies-parent"; private static final String TAG_POLICIES = "policies"; private static final String TAG_CROSS_PROFILE_WIDGET_PROVIDERS = "cross-profile-widget-providers"; Loading Loading @@ -158,7 +156,6 @@ class ActiveAdmin { @NonNull PasswordPolicy mPasswordPolicy = new PasswordPolicy(); boolean mPasswordPolicyAppliesToParent = true; @DevicePolicyManager.PasswordComplexity int mPasswordComplexity = PASSWORD_COMPLEXITY_NONE; Loading Loading @@ -363,9 +360,6 @@ class ActiveAdmin { writeAttributeValueToXml( out, TAG_MIN_PASSWORD_NONLETTER, mPasswordPolicy.nonLetter); } writeAttributeValueToXml(out, TAG_PASSWORD_QUALITY_APPLIES_TO_PARENT, mPasswordPolicyAppliesToParent); } if (passwordHistoryLength != DEF_PASSWORD_HISTORY_LENGTH) { writeAttributeValueToXml( Loading Loading @@ -669,8 +663,6 @@ class ActiveAdmin { mPasswordPolicy.symbols = parser.getAttributeInt(null, ATTR_VALUE); } else if (TAG_MIN_PASSWORD_NONLETTER.equals(tag)) { mPasswordPolicy.nonLetter = parser.getAttributeInt(null, ATTR_VALUE); } else if (TAG_PASSWORD_QUALITY_APPLIES_TO_PARENT.equals(tag)) { mPasswordPolicyAppliesToParent = parser.getAttributeBoolean(null, ATTR_VALUE); } else if (TAG_MAX_TIME_TO_UNLOCK.equals(tag)) { maximumTimeToUnlock = parser.getAttributeLong(null, ATTR_VALUE); } else if (TAG_STRONG_AUTH_UNLOCK_TIMEOUT.equals(tag)) { Loading Loading @@ -1036,9 +1028,6 @@ class ActiveAdmin { pw.print("minimumPasswordNonLetter="); pw.println(mPasswordPolicy.nonLetter); pw.print("passwordPolicyAppliesToParent="); pw.println(mPasswordPolicyAppliesToParent); pw.print("maximumTimeToUnlock="); pw.println(maximumTimeToUnlock); Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +5 −17 Original line number Diff line number Diff line Loading @@ -3827,10 +3827,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { isProfileOwner(caller) || isDeviceOwner(caller) || isSystemUid(caller) || isPasswordLimitingAdminTargetingP(caller)); final boolean qualityMayApplyToParent = canSetPasswordQualityOnParent(who.getPackageName(), caller); if (!qualityMayApplyToParent) { Preconditions.checkCallAuthorization(!parent, if (parent) { Preconditions.checkCallAuthorization( canSetPasswordQualityOnParent(who.getPackageName(), caller), "Profile Owner may not apply password quality requirements device-wide"); } Loading @@ -3856,7 +3855,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (passwordPolicy.quality != quality) { passwordPolicy.quality = quality; ap.mPasswordComplexity = PASSWORD_COMPLEXITY_NONE; ap.mPasswordPolicyAppliesToParent = qualityMayApplyToParent; resetInactivePasswordRequirementsIfRPlus(userId, ap); updatePasswordValidityCheckpointLocked(userId, parent); updatePasswordQualityCacheForUserGroup(userId); Loading Loading @@ -4588,8 +4586,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } ArrayList<PasswordMetrics> adminMetrics = new ArrayList<>(); synchronized (getLockObject()) { final List<ActiveAdmin> admins; synchronized (getLockObject()) { if (deviceWideOnly) { admins = getActiveAdminsForUserAndItsManagedProfilesLocked(userId, /* shouldIncludeProfileAdmins */ (user) -> false); Loading @@ -4597,18 +4595,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { admins = getActiveAdminsForLockscreenPoliciesLocked(userId); } for (ActiveAdmin admin : admins) { final boolean isAdminOfUser = userId == admin.getUserHandle().getIdentifier(); // Use the password metrics from the admin in one of three cases: // (1) The admin is of the user we're getting the minimum metrics for. The admin // always affects the user it's managing. This applies also to the parent // ActiveAdmin instance: It'd have the same user handle. // (2) The mPasswordPolicyAppliesToParent field is true: That indicates the // call to setPasswordQuality was made by an admin that may affect the parent. if (isAdminOfUser || admin.mPasswordPolicyAppliesToParent) { adminMetrics.add(admin.mPasswordPolicy.getMinMetrics()); } } } return PasswordMetrics.merge(adminMetrics); } Loading Loading @@ -4821,7 +4810,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { admin.mPasswordComplexity = passwordComplexity; // Reset the password policy. admin.mPasswordPolicy = new PasswordPolicy(); admin.mPasswordPolicyAppliesToParent = true; updatePasswordValidityCheckpointLocked(caller.getUserId(), calledOnParent); updatePasswordQualityCacheForUserGroup(caller.getUserId()); saveSettingsLocked(caller.getUserId()); Loading
services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +199 −0 Original line number Diff line number Diff line Loading @@ -5427,6 +5427,205 @@ public class DevicePolicyManagerTest extends DpmTestBase { } } @Test public void isActivePasswordSufficient_SeparateWorkChallenge_ProfileQualityRequirementMet() throws Exception { // Create work profile with empty separate challenge final int managedProfileUserId = 15; final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, /* separateChallenge */ true); // Set profile password quality requirement. No password added yet so // profile.isActivePasswordSufficient should return false mContext.binder.callingUid = managedProfileAdminUid; dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC); assertThat(dpm.isActivePasswordSufficient()).isFalse(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); // Set a work challenge and verify profile.isActivePasswordSufficient is now true when(getServices().lockSettingsInternal.getUserPasswordMetrics(managedProfileUserId)) .thenReturn(computeForPasswordOrPin("abcdXYZ5".getBytes(), /* isPin */ false)); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } @Test public void isActivePasswordSufficient_SeparateWorkChallenge_ProfileComplexityRequirementMet() throws Exception { // Create work profile with empty separate challenge final int managedProfileUserId = 15; final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, /* separateChallenge */ true); // Set profile password complexity requirement. No password added yet so // profile.isActivePasswordSufficient should return false mContext.binder.callingUid = managedProfileAdminUid; dpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_MEDIUM); assertThat(dpm.isActivePasswordSufficient()).isFalse(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); // Set a work challenge and verify profile.isActivePasswordSufficient is now true when(getServices().lockSettingsInternal.getUserPasswordMetrics(managedProfileUserId)) .thenReturn(computeForPasswordOrPin("5156".getBytes(), /* isPin */ true)); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } @Test public void isActivePasswordSufficient_SeparateWorkChallenge_ParentQualityRequirementMet() throws Exception { // Create work profile with empty separate challenge final int managedProfileUserId = 15; final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, /* separateChallenge */ true); // Set parent password quality requirement. No password added yet so // parent.isActivePasswordSufficient should return false mContext.binder.callingUid = managedProfileAdminUid; parentDpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isFalse(); // Set a device lockscreen and verify parent.isActivePasswordSufficient is now true when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) .thenReturn(computeForPasswordOrPin("acbdXYZ5".getBytes(), /* isPin */ false)); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } @Test public void isActivePasswordSufficient_SeparateWorkChallenge_ParentComplexityRequirementMet() throws Exception { // Create work profile with empty separate challenge final int managedProfileUserId = 15; final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, /* separateChallenge */ true); // Set parent password complexity requirement. No password added yet so // parent.isActivePasswordSufficient should return false mContext.binder.callingUid = managedProfileAdminUid; parentDpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_LOW); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isFalse(); // Set a device lockscreen and verify parent.isActivePasswordSufficient is now true when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) .thenReturn(computeForPasswordOrPin("1234".getBytes(), /* isPin */ true)); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } @Test public void isActivePasswordSufficient_UnifiedWorkChallenge_ProfileQualityRequirementMet() throws Exception { // Create work profile with unified challenge final int managedProfileUserId = 15; final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, /* separateChallenge */ false); // Set profile password quality requirement. No password added yet so // {profile, parent}.isActivePasswordSufficient should return false mContext.binder.callingUid = managedProfileAdminUid; dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC); assertThat(dpm.isActivePasswordSufficient()).isFalse(); assertThat(parentDpm.isActivePasswordSufficient()).isFalse(); // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) .thenReturn(computeForPasswordOrPin("abcdXYZ5".getBytes(), /* isPin */ false)); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } @Test public void isActivePasswordSufficient_UnifiedWorkChallenge_ProfileComplexityRequirementMet() throws Exception { // Create work profile with unified challenge final int managedProfileUserId = 15; final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, /* separateChallenge */ false); // Set profile password complexity requirement. No password added yet so // {profile, parent}.isActivePasswordSufficient should return false mContext.binder.callingUid = managedProfileAdminUid; dpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_HIGH); assertThat(dpm.isActivePasswordSufficient()).isFalse(); assertThat(parentDpm.isActivePasswordSufficient()).isFalse(); // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) .thenReturn(computeForPasswordOrPin("51567548".getBytes(), /* isPin */ true)); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } @Test public void isActivePasswordSufficient_UnifiedWorkChallenge_ParentQualityRequirementMet() throws Exception { // Create work profile with unified challenge final int managedProfileUserId = 15; final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, /* separateChallenge */ false); // Set parent password quality requirement. No password added yet so // {profile, parent}.isActivePasswordSufficient should return false mContext.binder.callingUid = managedProfileAdminUid; parentDpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC); assertThat(dpm.isActivePasswordSufficient()).isFalse(); assertThat(parentDpm.isActivePasswordSufficient()).isFalse(); // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) .thenReturn(computeForPasswordOrPin("abcdXYZ5".getBytes(), /* isPin */ false)); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } @Test public void isActivePasswordSufficient_UnifiedWorkChallenge_ParentComplexityRequirementMet() throws Exception { // Create work profile with unified challenge final int managedProfileUserId = 15; final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, /* separateChallenge */ false); // Set parent password complexity requirement. No password added yet so // {profile, parent}.isActivePasswordSufficient should return false mContext.binder.callingUid = managedProfileAdminUid; parentDpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_MEDIUM); assertThat(dpm.isActivePasswordSufficient()).isFalse(); assertThat(parentDpm.isActivePasswordSufficient()).isFalse(); // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) .thenReturn(computeForPasswordOrPin("5156".getBytes(), /* isPin */ true)); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } private void addManagedProfileForPasswordTests(int userId, int adminUid, boolean separateChallenge) throws Exception { addManagedProfile(admin1, adminUid, admin1); when(getServices().userManager.getProfileParent(userId)) .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); doReturn(separateChallenge).when(getServices().lockPatternUtils) .isSeparateProfileChallengeEnabled(userId); when(getServices().userManager.getCredentialOwnerProfile(userId)) .thenReturn(separateChallenge ? userId : UserHandle.USER_SYSTEM); when(getServices().lockSettingsInternal.getUserPasswordMetrics(userId)) .thenReturn(new PasswordMetrics(CREDENTIAL_TYPE_NONE)); when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) .thenReturn(new PasswordMetrics(CREDENTIAL_TYPE_NONE)); } @Test public void testPasswordQualityAppliesToParentPreS() throws Exception { final int managedProfileUserId = CALLER_USER_HANDLE; Loading