Call getPasswordComplexity on the parent profile

Previously, this API did not support explicitly querying the parent profile.
This CL will now allow the WP DPC to call this method since all other password
related methods can already be called.

Screenshot of TestDPC: https://hsv.googleplex.com/4804408720228352 (WP DPC)
                       https://hsv.googleplex.com/5189846769336320

Bug: 138709470
Test: manual testing using Personal and WP TestDPC
      atest com.android.cts.devicepolicy.ManagedProfileTest
      atest com.android.cts.devicepolicy.PasswordComplexityTest
      atest com.android.server.devicepolicy.DevicePolicyManagerTest

Change-Id: I0fb3a96c4469046c8712b5de582c501ea7eb3d8b
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index ad671df..9eff4b0 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -3499,24 +3499,25 @@
      * Returns how complex the current user's screen lock is.
      *
      * <p>Note that when called from a profile which uses an unified challenge with its parent, the
-     * screen lock complexity of the parent will be returned. However, this API does not support
-     * explicitly querying the parent profile screen lock complexity via {@link
-     * #getParentProfileInstance}.
+     * screen lock complexity of the parent will be returned.
+     *
+     * <p>This method can be called on the {@link DevicePolicyManager} instance
+     * returned by {@link #getParentProfileInstance(ComponentName)} in order to retrieve
+     * restrictions on the parent profile.
      *
      * @throws IllegalStateException if the user is not unlocked.
-     * @throws SecurityException if the calling application does not have the permission
-     *                           {@link permission#REQUEST_PASSWORD_COMPLEXITY}
+     * @throws SecurityException     if the calling application does not have the permission
+     *                               {@link permission#REQUEST_PASSWORD_COMPLEXITY}
      */
     @PasswordComplexity
     @RequiresPermission(android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY)
     public int getPasswordComplexity() {
-        throwIfParentInstance("getPasswordComplexity");
         if (mService == null) {
             return PASSWORD_COMPLEXITY_NONE;
         }
 
         try {
-            return mService.getPasswordComplexity();
+            return mService.getPasswordComplexity(mParentInstance);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -9254,6 +9255,7 @@
      * <li>{@link #setPasswordExpirationTimeout}</li>
      * <li>{@link #getPasswordExpiration}</li>
      * <li>{@link #getPasswordMaximumLength}</li>
+     * <li>{@link #getPasswordComplexity}</li>
      * <li>{@link #isActivePasswordSufficient}</li>
      * <li>{@link #getCurrentFailedPasswordAttempts}</li>
      * <li>{@link #getMaximumFailedPasswordsForWipe}</li>
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 6b50522..4894751 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -84,7 +84,7 @@
 
     boolean isActivePasswordSufficient(int userHandle, boolean parent);
     boolean isProfileActivePasswordSufficientForParent(int userHandle);
-    int getPasswordComplexity();
+    int getPasswordComplexity(boolean parent);
     boolean isUsingUnifiedPassword(in ComponentName admin);
     int getCurrentFailedPasswordAttempts(int userHandle, boolean parent);
     int getProfileWithMinimumFailedPasswordsForWipe(int userHandle, boolean parent);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index a39cc20..9dac03f 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -4928,21 +4928,25 @@
 
     @Override
     @PasswordComplexity
-    public int getPasswordComplexity() {
+    public int getPasswordComplexity(boolean parent) {
         DevicePolicyEventLogger
                 .createEvent(DevicePolicyEnums.GET_USER_PASSWORD_COMPLEXITY_LEVEL)
                 .setStrings(mInjector.getPackageManager()
                         .getPackagesForUid(mInjector.binderGetCallingUid()))
                 .write();
         final int callingUserId = mInjector.userHandleGetCallingUserId();
+
+        if (parent) {
+            enforceProfileOwnerOrSystemUser();
+        }
         enforceUserUnlocked(callingUserId);
         mContext.enforceCallingOrSelfPermission(
                 REQUEST_PASSWORD_COMPLEXITY,
                 "Must have " + REQUEST_PASSWORD_COMPLEXITY + " permission.");
 
         synchronized (getLockObject()) {
-            int targetUserId = getCredentialOwner(callingUserId, /* parent= */ false);
-            PasswordMetrics metrics = mLockSettingsInternal.getUserPasswordMetrics(targetUserId);
+            final int credentialOwner = getCredentialOwner(callingUserId, parent);
+            PasswordMetrics metrics = mLockSettingsInternal.getUserPasswordMetrics(credentialOwner);
             return metrics == null ? PASSWORD_COMPLEXITY_NONE : metrics.determineComplexity();
         }
     }
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index f571411..f270724 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -5295,13 +5295,17 @@
         });
     }
 
-    public void testGetPasswordComplexity_securityExceptionIfParentInstance() {
-        assertThrows(SecurityException.class,
-                () -> new DevicePolicyManagerTestable(
-                        mServiceContext,
-                        dpms,
-                        /* parentInstance= */ true)
-                        .getPasswordComplexity());
+    public void testGetPasswordComplexity_securityExceptionNotThrownForParentInstance() {
+        mServiceContext.permissions.add(permission.REQUEST_PASSWORD_COMPLEXITY);
+        setAsProfileOwner(admin1);
+
+        new DevicePolicyManagerTestable(
+                mServiceContext,
+                dpms,
+                /* parentInstance= */ true)
+                .getPasswordComplexity();
+
+        assertEquals(PASSWORD_COMPLEXITY_NONE, dpm.getPasswordComplexity());
     }
 
     public void testGetPasswordComplexity_illegalStateExceptionIfLocked() {