summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java21
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl1
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java9
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java27
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java29
5 files changed, 74 insertions, 13 deletions
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 42427fa825eb..247d6f0de831 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -3721,6 +3721,27 @@ public class DevicePolicyManager {
}
/**
+ * Returns the password complexity that applies to this user, aggregated from other users if
+ * necessary (for example, if the DPC has set password complexity requirements on the parent
+ * profile DPM instance of a managed profile user, they would apply to the primary user on the
+ * device).
+ * @hide
+ */
+ @PasswordComplexity
+ public int getAggregatedPasswordComplexityForUser(int userId) {
+ if (mService == null) {
+ return PASSWORD_COMPLEXITY_NONE;
+ }
+
+ try {
+ return mService.getAggregatedPasswordComplexityForUser(userId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+
+ /**
* When called by a profile owner of a managed profile returns true if the profile uses unified
* challenge with its parent user.
*
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 58368bc3779a..37d34511902d 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -89,6 +89,7 @@ interface IDevicePolicyManager {
int getPasswordComplexity(boolean parent);
void setRequiredPasswordComplexity(int passwordComplexity, boolean parent);
int getRequiredPasswordComplexity(boolean parent);
+ int getAggregatedPasswordComplexityForUser(int userId);
boolean isUsingUnifiedPassword(in ComponentName admin);
int getCurrentFailedPasswordAttempts(int userHandle, boolean parent);
int getProfileWithMinimumFailedPasswordsForWipe(int userHandle, boolean parent);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index b562ef838633..9712b4e794c5 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -311,6 +311,15 @@ public class LockPatternUtils {
return getDevicePolicyManager().getPasswordMinimumMetrics(userId);
}
+ /**
+ * Returns the effective complexity for the user.
+ * @param userId The user to return the complexity for.
+ * @return complexity level for the user.
+ */
+ public @DevicePolicyManager.PasswordComplexity int getRequestedPasswordComplexity(int userId) {
+ return getDevicePolicyManager().getAggregatedPasswordComplexityForUser(userId);
+ }
+
public int getRequestedPasswordQuality(int userId) {
return getDevicePolicyManager().getPasswordQuality(null, userId);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
index 9f16d033aea5..ac20ee14ced2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
@@ -408,7 +408,8 @@ public class RestrictedLockUtilsInternal extends RestrictedLockUtils {
}
/**
- * Checks if an admin has enforced minimum password quality requirements on the given user.
+ * Checks if an admin has enforced minimum password quality or complexity requirements on the
+ * given user.
*
* @return EnforcedAdmin Object containing the enforced admin component and admin user details,
* or {@code null} if no quality requirements are set. If the requirements are set by
@@ -428,6 +429,30 @@ public class RestrictedLockUtilsInternal extends RestrictedLockUtils {
}
LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
+ final int aggregatedComplexity = dpm.getAggregatedPasswordComplexityForUser(userId);
+ if (aggregatedComplexity > DevicePolicyManager.PASSWORD_COMPLEXITY_NONE) {
+ // First, check if there's a Device Owner. If so, then only it can apply password
+ // complexity requiremnts (there can be no secondary profiles).
+ final UserHandle deviceOwnerUser = dpm.getDeviceOwnerUser();
+ if (deviceOwnerUser != null) {
+ return new EnforcedAdmin(dpm.getDeviceOwnerComponentOnAnyUser(), deviceOwnerUser);
+ }
+
+ // The complexity could be enforced by a Profile Owner - either in the current user
+ // or the current user is the parent user that is affected by the profile owner.
+ for (UserInfo userInfo : UserManager.get(context).getProfiles(userId)) {
+ final ComponentName profileOwnerComponent = dpm.getProfileOwnerAsUser(userInfo.id);
+ if (profileOwnerComponent != null) {
+ return new EnforcedAdmin(profileOwnerComponent, getUserHandleOf(userInfo.id));
+ }
+ }
+
+ // Should not get here: A Device Owner or Profile Owner should be found.
+ throw new IllegalStateException(
+ String.format("Could not find admin enforcing complexity %d for user %d",
+ aggregatedComplexity, userId));
+ }
+
if (sProxy.isSeparateProfileChallengeEnabled(lockPatternUtils, userId)) {
// userId is managed profile and has a separate challenge, only consider
// the admins in that user.
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 81ce8ff3c72f..2f477afecf12 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -4203,11 +4203,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
int maxRequiredComplexity = PASSWORD_COMPLEXITY_NONE;
for (ActiveAdmin admin : admins) {
adminMetrics.add(admin.mPasswordPolicy.getMinMetrics());
- if (isDeviceOwner(admin) || isProfileOwnerUncheckedLocked(admin.info.getComponent(),
- admin.getUserHandle().getIdentifier())) {
- maxRequiredComplexity = Math.max(maxRequiredComplexity,
- admin.mPasswordComplexity);
- }
+ maxRequiredComplexity = Math.max(maxRequiredComplexity, admin.mPasswordComplexity);
}
return PasswordMetrics.validatePasswordMetrics(PasswordMetrics.merge(adminMetrics),
maxRequiredComplexity, false, metrics).isEmpty();
@@ -4320,13 +4316,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(userHandle);
int maxRequiredComplexity = PASSWORD_COMPLEXITY_NONE;
for (ActiveAdmin admin : admins) {
- final ComponentName adminComponent = admin.info.getComponent();
- final int adminUser = admin.getUserHandle().getIdentifier();
- // Password complexity is only taken into account from DO/PO
- if (isDeviceOwner(adminComponent, adminUser)
- || isProfileOwnerUncheckedLocked(adminComponent, adminUser)) {
- maxRequiredComplexity = Math.max(maxRequiredComplexity, admin.mPasswordComplexity);
- }
+ maxRequiredComplexity = Math.max(maxRequiredComplexity, admin.mPasswordComplexity);
}
return maxRequiredComplexity;
}
@@ -4351,6 +4341,21 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
@Override
+ public int getAggregatedPasswordComplexityForUser(int userId) {
+ if (!mHasFeature) {
+ return PASSWORD_COMPLEXITY_NONE;
+ }
+
+ final CallerIdentity caller = getCallerIdentity();
+ Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userId));
+
+ synchronized (getLockObject()) {
+ return getEffectivePasswordComplexityRequirementLocked(userId);
+ }
+ }
+
+
+ @Override
public int getCurrentFailedPasswordAttempts(int userHandle, boolean parent) {
if (!mLockPatternUtils.hasSecureLockScreen()) {
return 0;