Merge "Import translations. DO NOT MERGE ANYWHERE"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 34b4041..114b41c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -5239,6 +5239,8 @@
         <item quantity="one"><xliff:g id="number_device_count">%1$d</xliff:g> saved hearing aid</item>
         <item quantity="other"><xliff:g id="number_device_count">%1$d</xliff:g> saved hearing aids</item>
     </plurals>
+    <!-- Title for the accessibility audio adjustment page. [CHAR LIMIT=50] -->
+    <string name="accessibility_audio_adjustment_title">Audio adjustment</string>
 
     <!-- Preference's shortcut when enabled. [CHAR LIMIT=NONE] -->
     <string name="accessibility_summary_shortcut_enabled">Shortcut on</string>
diff --git a/res/xml/accessibility_audio_adjustment.xml b/res/xml/accessibility_audio_adjustment.xml
new file mode 100644
index 0000000..c38b4ad
--- /dev/null
+++ b/res/xml/accessibility_audio_adjustment.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    android:key="accessibility_audio_adjustment"
+    android:persistent="false"
+    android:title="@string/accessibility_audio_adjustment_title">
+
+    <SwitchPreference
+        android:key="toggle_primary_mono"
+        android:persistent="false"
+        android:summary="@string/accessibility_toggle_primary_mono_summary"
+        android:title="@string/accessibility_toggle_primary_mono_title"
+        settings:controller="com.android.settings.accessibility.PrimaryMonoPreferenceController"/>
+
+    <com.android.settings.accessibility.BalanceSeekBarPreference
+        android:key="seekbar_primary_balance"
+        android:persistent="false"
+        android:title="@string/accessibility_toggle_primary_balance_title"/>
+</PreferenceScreen>
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index b7c28b4..36125b3 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -100,18 +100,6 @@
             settings:searchable="false"
             settings:controller="com.android.settings.accessibility.LiveCaptionPreferenceController"/>
 
-        <SwitchPreference
-            android:key="toggle_primary_mono"
-            android:persistent="false"
-            android:summary="@string/accessibility_toggle_primary_mono_summary"
-            android:title="@string/accessibility_toggle_primary_mono_title"
-            settings:controller="com.android.settings.accessibility.PrimaryMonoPreferenceController"/>
-
-        <com.android.settings.accessibility.BalanceSeekBarPreference
-            android:key="seekbar_primary_balance"
-            android:persistent="false"
-            android:title="@string/accessibility_toggle_primary_balance_title"/>
-
         <Preference
             android:key="hearing_aid_preference"
             android:persistent="false"
@@ -120,6 +108,13 @@
             settings:controller="com.android.settings.accessibility.AccessibilityHearingAidPreferenceController"/>
 
         <Preference
+            android:fragment="com.android.settings.accessibility.AudioAdjustmentFragment"
+            android:key="audio_adjustment_preference_screen"
+            android:persistent="false"
+            android:title="@string/accessibility_audio_adjustment_title"
+            settings:searchable="true"/>
+
+        <Preference
             android:key="rtt_setting"
             android:summary="@string/summary_placeholder"
             android:title="@string/rtt_settings_title"
diff --git a/src/com/android/settings/accessibility/AudioAdjustmentFragment.java b/src/com/android/settings/accessibility/AudioAdjustmentFragment.java
new file mode 100644
index 0000000..c80216b
--- /dev/null
+++ b/src/com/android/settings/accessibility/AudioAdjustmentFragment.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import android.app.settings.SettingsEnums;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.search.SearchIndexable;
+
+/** Accessibility settings for audio adjustment. */
+@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
+public class AudioAdjustmentFragment extends DashboardFragment {
+
+    private static final String TAG = "AudioAdjustmentFragment";
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.ACCESSIBILITY_AUDIO_ADJUSTMENT;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.accessibility_audio_adjustment;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.accessibility_audio_adjustment);
+
+}
diff --git a/src/com/android/settings/password/ChooseLockGeneric.java b/src/com/android/settings/password/ChooseLockGeneric.java
index 8b0c2c9..90c9859 100644
--- a/src/com/android/settings/password/ChooseLockGeneric.java
+++ b/src/com/android/settings/password/ChooseLockGeneric.java
@@ -25,6 +25,7 @@
 
 import static com.android.settings.password.ChooseLockPassword.ChooseLockPasswordFragment.RESULT_FINISHED;
 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_CALLER_APP_NAME;
+import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_DEVICE_PASSWORD_REQUIREMENT_ONLY;
 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_IS_CALLING_APP_ADMIN;
 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY;
 
@@ -162,6 +163,8 @@
 
         /**
          * From intent extra {@link ChooseLockSettingsHelper#EXTRA_KEY_REQUESTED_MIN_COMPLEXITY}.
+         * Only contains complexity requested by calling app, not complexity enforced by device
+         * admins.
          */
         @PasswordComplexity private int mRequestedMinComplexity;
 
@@ -178,6 +181,8 @@
         protected boolean mForFace = false;
         protected boolean mForBiometrics = false;
 
+        private boolean mOnlyEnforceDevicePasswordRequirement = false;
+
         @Override
         public int getMetricsCategory() {
             return SettingsEnums.CHOOSE_LOCK_GENERIC;
@@ -221,20 +226,11 @@
             mForBiometrics = intent.getBooleanExtra(
                     ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, false);
 
-            final int complexityFromIntent = intent
-                    .getIntExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_NONE);
-            final int complexityFromAdmin = mLockPatternUtils.getRequestedPasswordComplexity(
-                    mUserId);
-            mRequestedMinComplexity = Math.max(complexityFromIntent, complexityFromAdmin);
-            final boolean isComplexityProvidedByAdmin = (complexityFromAdmin > complexityFromIntent)
-                    && mRequestedMinComplexity > PASSWORD_COMPLEXITY_NONE;
+            mRequestedMinComplexity = intent.getIntExtra(
+                    EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_NONE);
+            mOnlyEnforceDevicePasswordRequirement = intent.getBooleanExtra(
+                    ChooseLockSettingsHelper.EXTRA_KEY_DEVICE_PASSWORD_REQUIREMENT_ONLY, false);
 
-            // If the complexity is provided by the admin, do not get the caller app's name.
-            // If the app requires, for example, low complexity, and the admin requires high
-            // complexity, it does not make sense to show a footer telling the user it's the app
-            // requesting a particular complexity because the admin-set complexity will override it.
-            mCallerAppName = isComplexityProvidedByAdmin ? null :
-                    intent.getStringExtra(EXTRA_KEY_CALLER_APP_NAME);
             mIsCallingAppAdmin = intent
                     .getBooleanExtra(EXTRA_KEY_IS_CALLING_APP_ADMIN, /* defValue= */ false);
             mForChangeCredRequiredForBoot = arguments != null && arguments.getBoolean(
@@ -268,7 +264,22 @@
                     arguments,
                     intent.getExtras()).getIdentifier();
             mController = new ChooseLockGenericController(
-                    getContext(), mUserId, mRequestedMinComplexity, mLockPatternUtils);
+                    getContext(), mUserId, mRequestedMinComplexity,
+                    mOnlyEnforceDevicePasswordRequirement,
+                    mLockPatternUtils);
+
+            final int aggregatedComplexity = mController.getAggregatedPasswordComplexity();
+            final boolean isComplexityProvidedByAdmin =
+                    aggregatedComplexity > mRequestedMinComplexity
+                    && aggregatedComplexity > PASSWORD_COMPLEXITY_NONE;
+
+            // If the complexity is provided by the admin, do not get the caller app's name.
+            // If the app requires, for example, low complexity, and the admin requires high
+            // complexity, it does not make sense to show a footer telling the user it's the app
+            // requesting a particular complexity because the admin-set complexity will override it.
+            mCallerAppName = isComplexityProvidedByAdmin ? null :
+                    intent.getStringExtra(EXTRA_KEY_CALLER_APP_NAME);
+
             if (ACTION_SET_NEW_PASSWORD.equals(chooseLockAction)
                     && UserManager.get(activity).isManagedProfile(mUserId)
                     && mLockPatternUtils.isSeparateProfileChallengeEnabled(mUserId)) {
@@ -356,6 +367,8 @@
                 chooseLockGenericIntent.putExtra(CONFIRM_CREDENTIALS, !mPasswordConfirmed);
                 chooseLockGenericIntent.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY,
                         mRequestedMinComplexity);
+                chooseLockGenericIntent.putExtra(EXTRA_KEY_DEVICE_PASSWORD_REQUIREMENT_ONLY,
+                        mOnlyEnforceDevicePasswordRequirement);
                 chooseLockGenericIntent.putExtra(EXTRA_KEY_CALLER_APP_NAME, mCallerAppName);
                 if (mUserPassword != null) {
                     chooseLockGenericIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD,
@@ -557,7 +570,7 @@
 
         private String getFooterString() {
             @StringRes int stringId;
-            switch (mRequestedMinComplexity) {
+            switch (mController.getAggregatedPasswordComplexity()) {
                 case PASSWORD_COMPLEXITY_HIGH:
                     stringId = R.string.unlock_footer_high_complexity_requested;
                     break;
@@ -678,7 +691,9 @@
                 boolean hideDisabled) {
             final PreferenceScreen entries = getPreferenceScreen();
 
-            int adminEnforcedQuality = mDpm.getPasswordQuality(null, mUserId);
+            int adminEnforcedQuality = LockPatternUtils.credentialTypeToPasswordQuality(
+                    mLockPatternUtils.getRequestedPasswordMetrics(
+                            mUserId, mOnlyEnforceDevicePasswordRequirement).credType);
             EnforcedAdmin enforcedAdmin =
                     RestrictedLockUtilsInternal.checkIfPasswordQualityIsSet(getActivity(),
                             mUserId);
@@ -753,8 +768,10 @@
         protected Intent getLockPasswordIntent(int quality) {
             ChooseLockPassword.IntentBuilder builder =
                     new ChooseLockPassword.IntentBuilder(getContext())
-                            .setPasswordQuality(quality)
-                            .setRequestedMinComplexity(mRequestedMinComplexity)
+                            .setPasswordType(quality)
+                            .setPasswordRequirement(
+                                    mController.getAggregatedPasswordComplexity(),
+                                    mController.getAggregatedPasswordMetrics())
                             .setForFingerprint(mForFingerprint)
                             .setForFace(mForFace)
                             .setForBiometrics(mForBiometrics)
diff --git a/src/com/android/settings/password/ChooseLockGenericController.java b/src/com/android/settings/password/ChooseLockGenericController.java
index 1bfdac9..88b35f9 100644
--- a/src/com/android/settings/password/ChooseLockGenericController.java
+++ b/src/com/android/settings/password/ChooseLockGenericController.java
@@ -18,7 +18,6 @@
 
 import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;
 
-import android.app.admin.DevicePolicyManager;
 import android.app.admin.DevicePolicyManager.PasswordComplexity;
 import android.app.admin.PasswordMetrics;
 import android.content.Context;
@@ -42,8 +41,8 @@
     private final Context mContext;
     private final int mUserId;
     @PasswordComplexity private final int mRequestedMinComplexity;
+    private final boolean mDevicePasswordRequirementOnly;
     private ManagedLockPasswordProvider mManagedPasswordProvider;
-    private DevicePolicyManager mDpm;
     private final LockPatternUtils mLockPatternUtils;
 
     public ChooseLockGenericController(Context context, int userId) {
@@ -51,6 +50,7 @@
                 context,
                 userId,
                 PASSWORD_COMPLEXITY_NONE,
+                /* mOnlyEnforceDevicePasswordRequirement */ false,
                 new LockPatternUtils(context));
     }
 
@@ -59,12 +59,14 @@
      *                               when determining the available screen lock types
      */
     public ChooseLockGenericController(Context context, int userId,
-            @PasswordComplexity int requestedMinComplexity, LockPatternUtils lockPatternUtils) {
+            @PasswordComplexity int requestedMinComplexity,
+            boolean devicePasswordRequirementOnly,
+            LockPatternUtils lockPatternUtils) {
         this(
                 context,
                 userId,
                 requestedMinComplexity,
-                context.getSystemService(DevicePolicyManager.class),
+                devicePasswordRequirementOnly,
                 ManagedLockPasswordProvider.get(context, userId),
                 lockPatternUtils);
     }
@@ -74,28 +76,29 @@
             Context context,
             int userId,
             @PasswordComplexity int requestedMinComplexity,
-            DevicePolicyManager dpm,
+            boolean devicePasswordRequirementOnly,
             ManagedLockPasswordProvider managedLockPasswordProvider,
             LockPatternUtils lockPatternUtils) {
         mContext = context;
         mUserId = userId;
         mRequestedMinComplexity = requestedMinComplexity;
+        mDevicePasswordRequirementOnly = devicePasswordRequirementOnly;
         mManagedPasswordProvider = managedLockPasswordProvider;
-        mDpm = dpm;
         mLockPatternUtils = lockPatternUtils;
     }
 
     /**
-     * Returns the highest quality among the specified {@code quality}, the quality required by
-     * {@link DevicePolicyManager#getPasswordQuality}, and the quality required by min password
-     * complexity.
+     * Returns the highest quality among the specified {@code quality}, the password requiremnet
+     * set by device admins (legacy password quality metrics and password complexity), and the
+     * min password complexity requested by the calling app.
      */
     public int upgradeQuality(int quality) {
         // Compare specified quality and dpm quality
         // TODO(b/142781408): convert from quality to credential type once PIN is supported.
-        int dpmUpgradedQuality = Math.max(quality, mDpm.getPasswordQuality(null, mUserId));
+        int dpmUpgradedQuality = Math.max(quality, LockPatternUtils.credentialTypeToPasswordQuality(
+                getAggregatedPasswordMetrics().credType));
         return Math.max(dpmUpgradedQuality,
-                PasswordMetrics.complexityLevelToMinQuality(mRequestedMinComplexity));
+                PasswordMetrics.complexityLevelToMinQuality(getAggregatedPasswordComplexity()));
     }
 
     /**
@@ -193,4 +196,15 @@
         }
         return locks;
     }
+
+    public PasswordMetrics getAggregatedPasswordMetrics() {
+        return mLockPatternUtils.getRequestedPasswordMetrics(mUserId,
+                mDevicePasswordRequirementOnly);
+    }
+
+    public int getAggregatedPasswordComplexity() {
+        return Math.max(mRequestedMinComplexity,
+                mLockPatternUtils.getRequestedPasswordComplexity(
+                        mUserId, mDevicePasswordRequirementOnly));
+    }
 }
diff --git a/src/com/android/settings/password/ChooseLockPassword.java b/src/com/android/settings/password/ChooseLockPassword.java
index f5e23fa..35d624b 100644
--- a/src/com/android/settings/password/ChooseLockPassword.java
+++ b/src/com/android/settings/password/ChooseLockPassword.java
@@ -19,6 +19,7 @@
 import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
 
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
 import static com.android.internal.widget.PasswordValidationError.CONTAINS_INVALID_CHARACTERS;
 import static com.android.internal.widget.PasswordValidationError.CONTAINS_SEQUENCE;
 import static com.android.internal.widget.PasswordValidationError.NOT_ENOUGH_DIGITS;
@@ -31,7 +32,6 @@
 import static com.android.internal.widget.PasswordValidationError.RECENTLY_USED;
 import static com.android.internal.widget.PasswordValidationError.TOO_LONG;
 import static com.android.internal.widget.PasswordValidationError.TOO_SHORT;
-import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY;
 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_UNIFICATION_PROFILE_CREDENTIAL;
 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_UNIFICATION_PROFILE_ID;
 
@@ -96,6 +96,9 @@
 public class ChooseLockPassword extends SettingsActivity {
     private static final String TAG = "ChooseLockPassword";
 
+    static final String EXTRA_KEY_MIN_METRICS = "min_metrics";
+    static final String EXTRA_KEY_MIN_COMPLEXITY = "min_complexity";
+
     @Override
     public Intent getIntent() {
         Intent modIntent = new Intent(super.getIntent());
@@ -119,8 +122,13 @@
             mIntent.putExtra(EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, false);
         }
 
-        public IntentBuilder setPasswordQuality(int quality) {
-            mIntent.putExtra(LockPatternUtils.PASSWORD_TYPE_KEY, quality);
+        /**
+         * Sets the intended credential type i.e. whether it's numeric PIN or general password
+         * @param passwordType password type represented by one of the {@code PASSWORD_QUALITY_}
+         *   constants.
+         */
+        public IntentBuilder setPasswordType(int passwordType) {
+            mIntent.putExtra(LockPatternUtils.PASSWORD_TYPE_KEY, passwordType);
             return this;
         }
 
@@ -156,8 +164,11 @@
             return this;
         }
 
-        public IntentBuilder setRequestedMinComplexity(@PasswordComplexity int level) {
-            mIntent.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, level);
+        /** Sets the minimum password requirement in terms of complexity and metrics */
+        public IntentBuilder setPasswordRequirement(@PasswordComplexity int level,
+                PasswordMetrics metrics) {
+            mIntent.putExtra(EXTRA_KEY_MIN_COMPLEXITY, level);
+            mIntent.putExtra(EXTRA_KEY_MIN_METRICS, metrics);
             return this;
         }
 
@@ -240,7 +251,7 @@
 
         private LockPatternUtils mLockPatternUtils;
         private SaveAndFinishWorker mSaveAndFinishWorker;
-        private int mRequestedQuality = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
+        private int mPasswordType = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
         protected Stage mUiStage = Stage.Introduction;
         private PasswordRequirementAdapter mPasswordRequirementAdapter;
         private GlifLayout mLayout;
@@ -410,19 +421,22 @@
             mForFace = intent.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, false);
             mForBiometrics = intent.getBooleanExtra(
                     ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, false);
-            mMinComplexity = intent.getIntExtra(
-                    EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_NONE);
 
-            mRequestedQuality = intent.getIntExtra(
+            mPasswordType = intent.getIntExtra(
                     LockPatternUtils.PASSWORD_TYPE_KEY, PASSWORD_QUALITY_NUMERIC);
             mUnificationProfileId = intent.getIntExtra(
                     EXTRA_KEY_UNIFICATION_PROFILE_ID, UserHandle.USER_NULL);
 
-            mMinMetrics = mLockPatternUtils.getRequestedPasswordMetrics(mUserId);
+            mMinComplexity = intent.getIntExtra(EXTRA_KEY_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_NONE);
+            mMinMetrics = intent.getParcelableExtra(EXTRA_KEY_MIN_METRICS);
+            if (mMinMetrics == null) mMinMetrics = new PasswordMetrics(CREDENTIAL_TYPE_NONE);
             // If we are to unify a work challenge at the end of the credential enrollment, manually
             // merge any password policy from that profile here, so we are enrolling a compliant
             // password. This is because once unified, the profile's password policy will
             // be enforced on the new credential.
+            //TODO: Move this logic to ChooseLockGeneric; let ChooseLockGeneric be the only place
+            //where password requirement mixing happens. ChooseLockPassword simply enforces what's
+            //set via IntentBuilder.setPasswordRequirement()
             if (mUnificationProfileId != UserHandle.USER_NULL) {
                 mMinMetrics.maxWith(
                         mLockPatternUtils.getRequestedPasswordMetrics(mUnificationProfileId));
@@ -494,9 +508,9 @@
                 mLayout.setIcon(getActivity().getDrawable(R.drawable.ic_lock));
             }
 
-            mIsAlphaMode = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == mRequestedQuality
-                    || DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == mRequestedQuality
-                    || DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == mRequestedQuality;
+            mIsAlphaMode = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == mPasswordType
+                    || DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == mPasswordType
+                    || DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == mPasswordType;
 
             setupPasswordRequirementsView(view);
 
diff --git a/src/com/android/settings/password/ChooseLockSettingsHelper.java b/src/com/android/settings/password/ChooseLockSettingsHelper.java
index 1e1f59f..13d3912 100644
--- a/src/com/android/settings/password/ChooseLockSettingsHelper.java
+++ b/src/com/android/settings/password/ChooseLockSettingsHelper.java
@@ -99,6 +99,12 @@
      */
     public static final String EXTRA_KEY_ALLOW_ANY_USER = "allow_any_user";
 
+    /**
+     *
+     */
+    public static final String EXTRA_KEY_DEVICE_PASSWORD_REQUIREMENT_ONLY =
+            "device_password_requirement_only";
+
     @VisibleForTesting @NonNull LockPatternUtils mLockPatternUtils;
     @NonNull private final Activity mActivity;
     @Nullable private final Fragment mFragment;
diff --git a/src/com/android/settings/password/SetNewPasswordActivity.java b/src/com/android/settings/password/SetNewPasswordActivity.java
index 19f2941..bd7b14d 100644
--- a/src/com/android/settings/password/SetNewPasswordActivity.java
+++ b/src/com/android/settings/password/SetNewPasswordActivity.java
@@ -19,10 +19,12 @@
 import static android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY;
 import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PARENT_PROFILE_PASSWORD;
 import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PASSWORD;
+import static android.app.admin.DevicePolicyManager.EXTRA_DEVICE_PASSWORD_REQUIREMENT_ONLY;
 import static android.app.admin.DevicePolicyManager.EXTRA_PASSWORD_COMPLEXITY;
 import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;
 
 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_CALLER_APP_NAME;
+import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_DEVICE_PASSWORD_REQUIREMENT_ONLY;
 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_IS_CALLING_APP_ADMIN;
 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY;
 
@@ -62,6 +64,8 @@
      */
     private @PasswordComplexity int mRequestedMinComplexity = PASSWORD_COMPLEXITY_NONE;
 
+    private boolean mDevicePasswordRequirementOnly = false;
+
     /**
      * Label of the app which launches this activity.
      *
@@ -72,27 +76,27 @@
     @Override
     protected void onCreate(Bundle savedState) {
         super.onCreate(savedState);
+        final Intent intent = getIntent();
 
-        mNewPasswordAction = getIntent().getAction();
+        mNewPasswordAction = intent.getAction();
         if (!ACTION_SET_NEW_PASSWORD.equals(mNewPasswordAction)
                 && !ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(mNewPasswordAction)) {
             Log.e(TAG, "Unexpected action to launch this activity");
             finish();
             return;
         }
-
         logSetNewPasswordIntent();
 
         final IBinder activityToken = getActivityToken();
         mCallerAppName = (String) PasswordUtils.getCallingAppLabel(this, activityToken);
         if (ACTION_SET_NEW_PASSWORD.equals(mNewPasswordAction)
-                && getIntent().hasExtra(EXTRA_PASSWORD_COMPLEXITY)) {
+                && intent.hasExtra(EXTRA_PASSWORD_COMPLEXITY)) {
             final boolean hasPermission = PasswordUtils.isCallingAppPermitted(
                     this, activityToken, REQUEST_PASSWORD_COMPLEXITY);
             if (hasPermission) {
                 mRequestedMinComplexity =
-                        PasswordMetrics.sanitizeComplexityLevel(getIntent()
-                                .getIntExtra(EXTRA_PASSWORD_COMPLEXITY, PASSWORD_COMPLEXITY_NONE));
+                        PasswordMetrics.sanitizeComplexityLevel(intent.getIntExtra(
+                                EXTRA_PASSWORD_COMPLEXITY, PASSWORD_COMPLEXITY_NONE));
             } else {
                 PasswordUtils.crashCallingApplication(activityToken,
                         "Must have permission "
@@ -102,9 +106,14 @@
                 return;
             }
         }
-
+        if (ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(mNewPasswordAction)) {
+            mDevicePasswordRequirementOnly = intent.getBooleanExtra(
+                    EXTRA_DEVICE_PASSWORD_REQUIREMENT_ONLY, false);
+            Log.i(TAG, String.format("DEVICE_PASSWORD_REQUIREMENT_ONLY: %b",
+                    mDevicePasswordRequirementOnly));
+        }
         mSetNewPasswordController = SetNewPasswordController.create(
-                this, this, getIntent(), getActivityToken());
+                this, this, intent, activityToken);
         mSetNewPasswordController.dispatchSetNewPasswordIntent();
     }
 
@@ -124,6 +133,7 @@
         if (isCallingAppAdmin()) {
             intent.putExtra(EXTRA_KEY_IS_CALLING_APP_ADMIN, true);
         }
+        intent.putExtra(EXTRA_KEY_DEVICE_PASSWORD_REQUIREMENT_ONLY, mDevicePasswordRequirementOnly);
         startActivity(intent);
         finish();
     }
diff --git a/src/com/android/settings/security/CredentialManagementAppPreferenceController.java b/src/com/android/settings/security/CredentialManagementAppPreferenceController.java
index 107b8f2..ae25714 100644
--- a/src/com/android/settings/security/CredentialManagementAppPreferenceController.java
+++ b/src/com/android/settings/security/CredentialManagementAppPreferenceController.java
@@ -28,6 +28,7 @@
 
 import androidx.preference.Preference;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
 import com.android.settings.core.BasePreferenceController;
 
@@ -72,7 +73,8 @@
         });
     }
 
-    private void displayPreference(Preference preference) {
+    @VisibleForTesting
+    void displayPreference(Preference preference) {
         if (mHasCredentialManagerPackage) {
             preference.setEnabled(true);
             try {
diff --git a/tests/robotests/src/com/android/settings/accessibility/AudioAdjustmentFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/AudioAdjustmentFragmentTest.java
new file mode 100644
index 0000000..814736d
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/AudioAdjustmentFragmentTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.R;
+import com.android.settings.testutils.XmlTestUtils;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+import java.util.List;
+
+/** Tests for {@link AudioAdjustmentFragment}. */
+@RunWith(RobolectricTestRunner.class)
+public class AudioAdjustmentFragmentTest {
+
+    private Context mContext = ApplicationProvider.getApplicationContext();
+
+    @Test
+    public void getNonIndexableKeys_existInXmlLayout() {
+        final List<String> niks = AudioAdjustmentFragment.SEARCH_INDEX_DATA_PROVIDER
+                .getNonIndexableKeys(mContext);
+        final List<String> keys =
+                XmlTestUtils.getKeysFromPreferenceXml(mContext,
+                        R.xml.accessibility_audio_adjustment);
+
+        assertThat(keys).containsAtLeastElementsIn(niks);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockGenericControllerTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockGenericControllerTest.java
index 5067de6..02b89cb 100644
--- a/tests/robotests/src/com/android/settings/password/ChooseLockGenericControllerTest.java
+++ b/tests/robotests/src/com/android/settings/password/ChooseLockGenericControllerTest.java
@@ -26,14 +26,13 @@
 
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.when;
 import static org.robolectric.RuntimeEnvironment.application;
 
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.DevicePolicyManager.PasswordComplexity;
-import android.content.ComponentName;
+import android.app.admin.PasswordPolicy;
 
 import com.android.internal.widget.LockPatternUtils;
 import com.android.settings.R;
@@ -61,9 +60,6 @@
     private ManagedLockPasswordProvider mManagedLockPasswordProvider;
 
     @Mock
-    private DevicePolicyManager mDevicePolicyManager;
-
-    @Mock
     private LockPatternUtils mLockPatternUtils;
 
     @Before
@@ -71,6 +67,7 @@
         MockitoAnnotations.initMocks(this);
 
         when(mLockPatternUtils.hasSecureLockScreen()).thenReturn(true);
+        setDevicePolicyPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
         mController = createController(PASSWORD_COMPLEXITY_NONE);
         SettingsShadowResources.overrideResource(R.bool.config_hide_none_security_option, false);
         SettingsShadowResources.overrideResource(R.bool.config_hide_swipe_security_option, false);
@@ -206,9 +203,7 @@
 
     @Test
     public void upgradeQuality_noDpmRequirement_shouldReturnQuality() {
-        doReturn(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED)
-                .when(mDevicePolicyManager)
-                .getPasswordQuality(nullable(ComponentName.class), anyInt());
+        setDevicePolicyPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
 
         final int upgradedQuality =
             mController.upgradeQuality(DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC);
@@ -218,9 +213,7 @@
 
     @Test
     public void upgradeQuality_dpmRequirement_shouldReturnRequiredQuality() {
-        doReturn(DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC)
-                .when(mDevicePolicyManager)
-                .getPasswordQuality(nullable(ComponentName.class), anyInt());
+        setDevicePolicyPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC);
 
         final int upgradedQuality =
             mController.upgradeQuality(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
@@ -230,8 +223,7 @@
 
     @Test
     public void upgradeQuality_complexityHigh_minQualityNumericComplex() {
-        when(mDevicePolicyManager.getPasswordQuality(nullable(ComponentName.class), anyInt()))
-                .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
+        setDevicePolicyPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
         ChooseLockGenericController controller = createController(PASSWORD_COMPLEXITY_HIGH);
 
         assertThat(controller.upgradeQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED))
@@ -240,8 +232,7 @@
 
     @Test
     public void upgradeQuality_complexityMedium_minQualityNumericComplex() {
-        when(mDevicePolicyManager.getPasswordQuality(nullable(ComponentName.class), anyInt()))
-                .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
+        setDevicePolicyPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
         ChooseLockGenericController controller = createController(PASSWORD_COMPLEXITY_MEDIUM);
 
         assertThat(controller.upgradeQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED))
@@ -250,21 +241,28 @@
 
     @Test
     public void upgradeQuality_complexityLow_minQualitySomething() {
-        when(mDevicePolicyManager.getPasswordQuality(nullable(ComponentName.class), anyInt()))
-                .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
+        setDevicePolicyPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
         ChooseLockGenericController controller = createController(PASSWORD_COMPLEXITY_LOW);
 
         assertThat(controller.upgradeQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED))
                 .isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
     }
 
+    private void setDevicePolicyPasswordQuality(int quality) {
+        PasswordPolicy policy = new PasswordPolicy();
+        policy.quality = quality;
+
+        when(mLockPatternUtils.getRequestedPasswordMetrics(anyInt(), anyBoolean()))
+                .thenReturn(policy.getMinMetrics());
+    }
+
     private ChooseLockGenericController createController(
             @PasswordComplexity int minPasswordComplexity) {
         return new ChooseLockGenericController(
                 application,
                 0 /* userId */,
                 minPasswordComplexity,
-                mDevicePolicyManager,
+                false,
                 mManagedLockPasswordProvider,
                 mLockPatternUtils);
     }
diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java
index 6097980..03ce25a 100644
--- a/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java
+++ b/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java
@@ -21,10 +21,14 @@
 import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_LOW;
 import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_MEDIUM;
 import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
 
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
 import static com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment.KEY_LOCK_SETTINGS_FOOTER;
 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_CALLER_APP_NAME;
+import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_DEVICE_PASSWORD_REQUIREMENT_ONLY;
 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_IS_CALLING_APP_ADMIN;
 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY;
 
@@ -35,6 +39,8 @@
 
 import android.app.Activity;
 import android.app.admin.DevicePolicyManager;
+import android.app.admin.PasswordMetrics;
+import android.app.admin.PasswordPolicy;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
@@ -301,8 +307,8 @@
         assertThat(result).isTrue();
         Intent actualIntent = shadowOf(mActivity).getNextStartedActivityForResult().intent;
         assertThat(actualIntent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isTrue();
-        assertThat(actualIntent.getIntExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_NONE))
-                .isEqualTo(PASSWORD_COMPLEXITY_HIGH);
+        assertThat(actualIntent.getIntExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY,
+                PASSWORD_COMPLEXITY_NONE)).isEqualTo(PASSWORD_COMPLEXITY_HIGH);
         assertThat(actualIntent.hasExtra(EXTRA_KEY_CALLER_APP_NAME)).isTrue();
         assertThat(actualIntent.getStringExtra(EXTRA_KEY_CALLER_APP_NAME))
                 .isEqualTo("app name");
@@ -322,8 +328,8 @@
         assertThat(result).isTrue();
         Intent actualIntent = shadowOf(mActivity).getNextStartedActivityForResult().intent;
         assertThat(actualIntent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isTrue();
-        assertThat(actualIntent.getIntExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_NONE))
-                .isEqualTo(PASSWORD_COMPLEXITY_HIGH);
+        assertThat(actualIntent.getIntExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY,
+                PASSWORD_COMPLEXITY_NONE)).isEqualTo(PASSWORD_COMPLEXITY_HIGH);
         assertThat(actualIntent.hasExtra(EXTRA_KEY_CALLER_APP_NAME)).isTrue();
         assertThat(actualIntent.getStringExtra(EXTRA_KEY_CALLER_APP_NAME))
                 .isEqualTo("app name");
@@ -391,7 +397,7 @@
         assertThat(footer.getTitle()).isEqualTo(null);
 
         Intent intent = mFragment.getLockPasswordIntent(PASSWORD_QUALITY_COMPLEX);
-        assertThat(intent.getIntExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY,
+        assertThat(intent.getIntExtra(ChooseLockPassword.EXTRA_KEY_MIN_COMPLEXITY,
                 PASSWORD_COMPLEXITY_NONE)).isEqualTo(PASSWORD_COMPLEXITY_HIGH);
     }
 
@@ -411,7 +417,7 @@
         assertThat(footer.getTitle()).isEqualTo(null);
 
         Intent passwordIntent = mFragment.getLockPasswordIntent(PASSWORD_QUALITY_COMPLEX);
-        assertThat(passwordIntent.getIntExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY,
+        assertThat(passwordIntent.getIntExtra(ChooseLockPassword.EXTRA_KEY_MIN_COMPLEXITY,
                 PASSWORD_COMPLEXITY_NONE)).isEqualTo(PASSWORD_COMPLEXITY_HIGH);
     }
 
@@ -433,10 +439,66 @@
         assertThat(footer.getTitle()).isEqualTo(expectedTitle);
 
         Intent passwordIntent = mFragment.getLockPasswordIntent(PASSWORD_QUALITY_COMPLEX);
-        assertThat(passwordIntent.getIntExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY,
+        assertThat(passwordIntent.getIntExtra(ChooseLockPassword.EXTRA_KEY_MIN_COMPLEXITY,
                 PASSWORD_COMPLEXITY_NONE)).isEqualTo(PASSWORD_COMPLEXITY_HIGH);
     }
 
+    @Test
+    public void getLockPasswordIntent_DevicePasswordRequirementOnly_PasswordComplexityPassedOn() {
+        ShadowLockPatternUtils.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_LOW);
+        ShadowLockPatternUtils.setRequiredProfilePasswordComplexity(PASSWORD_COMPLEXITY_HIGH);
+
+        Intent intent = new Intent()
+                .putExtra(EXTRA_KEY_DEVICE_PASSWORD_REQUIREMENT_ONLY, true);
+        initActivity(intent);
+
+        Intent passwordIntent = mFragment.getLockPasswordIntent(PASSWORD_QUALITY_ALPHABETIC);
+        assertThat(passwordIntent.getIntExtra(ChooseLockPassword.EXTRA_KEY_MIN_COMPLEXITY,
+                PASSWORD_COMPLEXITY_NONE)).isEqualTo(PASSWORD_COMPLEXITY_LOW);
+        assertThat(passwordIntent.<PasswordMetrics>getParcelableExtra(
+                ChooseLockPassword.EXTRA_KEY_MIN_METRICS)).isEqualTo(
+                new PasswordMetrics(CREDENTIAL_TYPE_NONE));
+    }
+
+    @Test
+    public void getLockPasswordIntent_DevicePasswordRequirementOnly_PasswordQualityPassedOn() {
+        PasswordPolicy policy = new PasswordPolicy();
+        policy.quality = PASSWORD_QUALITY_SOMETHING;
+        ShadowLockPatternUtils.setRequestedPasswordMetrics(policy.getMinMetrics());
+        PasswordPolicy profilePolicy = new PasswordPolicy();
+        profilePolicy.quality = PASSWORD_QUALITY_ALPHABETIC;
+        ShadowLockPatternUtils.setRequestedProfilePasswordMetrics(profilePolicy.getMinMetrics());
+
+        Intent intent = new Intent()
+                .putExtra(EXTRA_KEY_DEVICE_PASSWORD_REQUIREMENT_ONLY, true);
+        initActivity(intent);
+
+        Intent passwordIntent = mFragment.getLockPasswordIntent(PASSWORD_QUALITY_ALPHABETIC);
+        assertThat(passwordIntent.getIntExtra(ChooseLockPassword.EXTRA_KEY_MIN_COMPLEXITY,
+                PASSWORD_COMPLEXITY_NONE)).isEqualTo(PASSWORD_COMPLEXITY_NONE);
+        assertThat(passwordIntent.<PasswordMetrics>getParcelableExtra(
+                ChooseLockPassword.EXTRA_KEY_MIN_METRICS)).isEqualTo(policy.getMinMetrics());
+    }
+
+    @Test
+    public void getLockPasswordIntent_DevicePasswordRequirementOnly_ComplexityAndQualityPassedOn() {
+        ShadowLockPatternUtils.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_LOW);
+        PasswordPolicy policy = new PasswordPolicy();
+        policy.quality = PASSWORD_QUALITY_ALPHABETIC;
+        ShadowLockPatternUtils.setRequestedProfilePasswordMetrics(policy.getMinMetrics());
+
+        Intent intent = new Intent()
+                .putExtra(EXTRA_KEY_DEVICE_PASSWORD_REQUIREMENT_ONLY, true);
+        initActivity(intent);
+
+        Intent passwordIntent = mFragment.getLockPasswordIntent(PASSWORD_QUALITY_ALPHABETIC);
+        assertThat(passwordIntent.getIntExtra(ChooseLockPassword.EXTRA_KEY_MIN_COMPLEXITY,
+                PASSWORD_COMPLEXITY_NONE)).isEqualTo(PASSWORD_COMPLEXITY_LOW);
+        assertThat(passwordIntent.<PasswordMetrics>getParcelableExtra(
+                ChooseLockPassword.EXTRA_KEY_MIN_METRICS)).isEqualTo(
+                        new PasswordMetrics(CREDENTIAL_TYPE_NONE));
+    }
+
     private void initActivity(@Nullable Intent intent) {
         if (intent == null) {
             intent = new Intent();
diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java
index 0ca6a3e..2233f1d 100644
--- a/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java
+++ b/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java
@@ -30,7 +30,6 @@
 
 import static com.android.internal.widget.LockPatternUtils.PASSWORD_TYPE_KEY;
 import static com.android.settings.password.ChooseLockGeneric.CONFIRM_CREDENTIALS;
-import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY;
 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_UNIFICATION_PROFILE_ID;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -40,6 +39,8 @@
 
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.DevicePolicyManager.PasswordComplexity;
+import android.app.admin.PasswordMetrics;
+import android.app.admin.PasswordPolicy;
 import android.content.Intent;
 import android.os.UserHandle;
 
@@ -93,7 +94,7 @@
     public void intentBuilder_setPassword_shouldAddExtras() {
         Intent intent = new IntentBuilder(application)
                 .setPassword(LockscreenCredential.createPassword("password"))
-                .setPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC)
+                .setPasswordType(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC)
                 .setUserId(123)
                 .build();
 
@@ -114,7 +115,7 @@
     public void intentBuilder_setRequestGatekeeperPassword_shouldAddExtras() {
         Intent intent = new IntentBuilder(application)
                 .setRequestGatekeeperPasswordHandle(true)
-                .setPasswordQuality(PASSWORD_QUALITY_ALPHANUMERIC)
+                .setPasswordType(PASSWORD_QUALITY_ALPHANUMERIC)
                 .setUserId(123)
                 .build();
 
@@ -131,11 +132,12 @@
     @Test
     public void intentBuilder_setMinComplexityMedium_hasMinComplexityExtraMedium() {
         Intent intent = new IntentBuilder(application)
-                .setRequestedMinComplexity(PASSWORD_COMPLEXITY_MEDIUM)
+                .setPasswordRequirement(PASSWORD_COMPLEXITY_MEDIUM, null)
                 .build();
 
-        assertThat(intent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isTrue();
-        assertThat(intent.getIntExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_NONE))
+        assertThat(intent.hasExtra(ChooseLockPassword.EXTRA_KEY_MIN_COMPLEXITY)).isTrue();
+        assertThat(intent.getIntExtra(
+                ChooseLockPassword.EXTRA_KEY_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_NONE))
                 .isEqualTo(PASSWORD_COMPLEXITY_MEDIUM);
     }
 
@@ -143,7 +145,7 @@
     public void intentBuilder_setMinComplexityNotCalled() {
         Intent intent = new IntentBuilder(application).build();
 
-        assertThat(intent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isFalse();
+        assertThat(intent.hasExtra(ChooseLockPassword.EXTRA_KEY_MIN_COMPLEXITY)).isFalse();
     }
 
     @Test
@@ -163,10 +165,12 @@
 
     @Test
     public void processAndValidatePasswordRequirements_noMinPasswordComplexity() {
-        mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_ALPHABETIC);
-        mShadowDpm.setPasswordMinimumLength(10);
+        PasswordPolicy policy = new PasswordPolicy();
+        policy.quality = PASSWORD_QUALITY_ALPHABETIC;
+        policy.length = 10;
 
         assertPasswordValidationResult(
+                /* minMetrics */ policy.getMinMetrics(),
                 /* minComplexity= */ PASSWORD_COMPLEXITY_NONE,
                 /* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
                 /* userEnteredPassword= */ LockscreenCredential.createNone(),
@@ -176,9 +180,11 @@
 
     @Test
     public void processAndValidatePasswordRequirements_minPasswordComplexityStricter_pin() {
-        mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_SOMETHING);
+        PasswordPolicy policy = new PasswordPolicy();
+        policy.quality = PASSWORD_QUALITY_SOMETHING;
 
         assertPasswordValidationResult(
+                /* minMetrics */ policy.getMinMetrics(),
                 /* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
                 /* passwordType= */ PASSWORD_QUALITY_NUMERIC,
                 /* userEnteredPassword= */ LockscreenCredential.createNone(),
@@ -188,9 +194,11 @@
     @Test
     @Ignore
     public void processAndValidatePasswordRequirements_minPasswordComplexityStricter_password() {
-        mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_SOMETHING);
+        PasswordPolicy policy = new PasswordPolicy();
+        policy.quality = PASSWORD_QUALITY_SOMETHING;
 
         assertPasswordValidationResult(
+                /* minMetrics */ policy.getMinMetrics(),
                 /* minComplexity= */ PASSWORD_COMPLEXITY_MEDIUM,
                 /* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
                 /* userEnteredPassword= */ LockscreenCredential.createNone(),
@@ -200,10 +208,12 @@
 
     @Test
     public void processAndValidatePasswordRequirements_dpmRestrictionsStricter_password() {
-        mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_ALPHANUMERIC);
-        mShadowDpm.setPasswordMinimumLength(9);
+        PasswordPolicy policy = new PasswordPolicy();
+        policy.quality = PASSWORD_QUALITY_ALPHANUMERIC;
+        policy.length = 9;
 
         assertPasswordValidationResult(
+                /* minMetrics */ policy.getMinMetrics(),
                 /* minComplexity= */ PASSWORD_COMPLEXITY_LOW,
                 /* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
                 /* userEnteredPassword= */ LockscreenCredential.createNone(),
@@ -214,10 +224,12 @@
 
     @Test
     public void processAndValidatePasswordRequirements_dpmLengthLonger_pin() {
-        mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_NUMERIC);
-        mShadowDpm.setPasswordMinimumLength(11);
+        PasswordPolicy policy = new PasswordPolicy();
+        policy.quality = PASSWORD_QUALITY_NUMERIC;
+        policy.length = 11;
 
         assertPasswordValidationResult(
+                /* minMetrics */ policy.getMinMetrics(),
                 /* minComplexity= */ PASSWORD_COMPLEXITY_MEDIUM,
                 /* passwordType= */ PASSWORD_QUALITY_NUMERIC,
                 /* userEnteredPassword= */ LockscreenCredential.createNone(),
@@ -226,10 +238,12 @@
 
     @Test
     public void processAndValidatePasswordRequirements_dpmQualityComplex() {
-        mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_COMPLEX);
-        mShadowDpm.setPasswordMinimumSymbols(2);
+        PasswordPolicy policy = new PasswordPolicy();
+        policy.quality = PASSWORD_QUALITY_COMPLEX;
+        policy.symbols = 2;
 
         assertPasswordValidationResult(
+                /* minMetrics */ policy.getMinMetrics(),
                 /* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
                 /* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
                 /* userEnteredPassword= */ LockscreenCredential.createNone(),
@@ -242,9 +256,11 @@
     @Test
     @Config(shadows = ShadowLockPatternUtils.class)
     public void processAndValidatePasswordRequirements_numericComplexNoMinComplexity_pinRequested() {
-        mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_NUMERIC_COMPLEX);
+        PasswordPolicy policy = new PasswordPolicy();
+        policy.quality = PASSWORD_QUALITY_NUMERIC_COMPLEX;
 
         assertPasswordValidationResult(
+                /* minMetrics */ policy.getMinMetrics(),
                 /* minComplexity= */ PASSWORD_COMPLEXITY_NONE,
                 /* passwordType= */ PASSWORD_QUALITY_NUMERIC,
                 /* userEnteredPassword= */ LockscreenCredential.createPassword("12345678"),
@@ -254,9 +270,11 @@
     @Test
     @Config(shadows = ShadowLockPatternUtils.class)
     public void processAndValidatePasswordRequirements_numericComplexNoMinComplexity_passwordRequested() {
-        mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_NUMERIC_COMPLEX);
+        PasswordPolicy policy = new PasswordPolicy();
+        policy.quality = PASSWORD_QUALITY_NUMERIC_COMPLEX;
 
         assertPasswordValidationResult(
+                /* minMetrics */ policy.getMinMetrics(),
                 /* minComplexity= */ PASSWORD_COMPLEXITY_NONE,
                 /* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
                 /* userEnteredPassword= */ LockscreenCredential.createPassword("12345678"),
@@ -266,9 +284,11 @@
     @Test
     @Config(shadows = ShadowLockPatternUtils.class)
     public void processAndValidatePasswordRequirements_numericComplexHighComplexity_pinRequested() {
-        mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_NUMERIC_COMPLEX);
+        PasswordPolicy policy = new PasswordPolicy();
+        policy.quality = PASSWORD_QUALITY_NUMERIC_COMPLEX;
 
         assertPasswordValidationResult(
+                /* minMetrics */ policy.getMinMetrics(),
                 /* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
                 /* passwordType= */ PASSWORD_QUALITY_NUMERIC,
                 /* userEnteredPassword= */ LockscreenCredential.createPassword("12345678"),
@@ -278,9 +298,11 @@
     @Test
     @Config(shadows = ShadowLockPatternUtils.class)
     public void processAndValidatePasswordRequirements_numericHighComplexity_pinRequested() {
-        mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_NUMERIC);
+        PasswordPolicy policy = new PasswordPolicy();
+        policy.quality = PASSWORD_QUALITY_NUMERIC_COMPLEX;
 
         assertPasswordValidationResult(
+                /* minMetrics */ policy.getMinMetrics(),
                 /* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
                 /* passwordType= */ PASSWORD_QUALITY_NUMERIC,
                 /* userEnteredPassword= */ LockscreenCredential.createPassword("12345678"),
@@ -290,9 +312,11 @@
     @Test
     @Config(shadows = ShadowLockPatternUtils.class)
     public void processAndValidatePasswordRequirements_numericComplexLowComplexity_passwordRequested() {
-        mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_NUMERIC_COMPLEX);
+        PasswordPolicy policy = new PasswordPolicy();
+        policy.quality = PASSWORD_QUALITY_NUMERIC_COMPLEX;
 
         assertPasswordValidationResult(
+                /* minMetrics */ policy.getMinMetrics(),
                 /* minComplexity= */ PASSWORD_COMPLEXITY_LOW,
                 /* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
                 /* userEnteredPassword= */ LockscreenCredential.createPassword("12345678"),
@@ -302,9 +326,11 @@
     @Test
     @Ignore
     public void processAndValidatePasswordRequirements_requirementsUpdateAccordingToMinComplexityAndUserInput_empty() {
-        mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED);
+        PasswordPolicy policy = new PasswordPolicy();
+        policy.quality = PASSWORD_QUALITY_UNSPECIFIED;
 
         assertPasswordValidationResult(
+                /* minMetrics */ policy.getMinMetrics(),
                 /* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
                 /* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
                 /* userEnteredPassword= */ LockscreenCredential.createNone(),
@@ -315,9 +341,11 @@
     @Test
     @Ignore
     public void processAndValidatePasswordRequirements_requirementsUpdateAccordingToMinComplexityAndUserInput_numeric() {
-        mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED);
+        PasswordPolicy policy = new PasswordPolicy();
+        policy.quality = PASSWORD_QUALITY_UNSPECIFIED;
 
         assertPasswordValidationResult(
+                /* minMetrics */ policy.getMinMetrics(),
                 /* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
                 /* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
                 /* userEnteredPassword= */ LockscreenCredential.createPassword("1"),
@@ -327,9 +355,11 @@
 
     @Test
     public void processAndValidatePasswordRequirements_requirementsUpdateAccordingToMinComplexityAndUserInput_alphabetic() {
-        mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED);
+        PasswordPolicy policy = new PasswordPolicy();
+        policy.quality = PASSWORD_QUALITY_UNSPECIFIED;
 
         assertPasswordValidationResult(
+                /* minMetrics */ policy.getMinMetrics(),
                 /* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
                 /* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
                 /* userEnteredPassword= */ LockscreenCredential.createPassword("b"),
@@ -338,9 +368,11 @@
 
     @Test
     public void processAndValidatePasswordRequirements_requirementsUpdateAccordingToMinComplexityAndUserInput_alphanumeric() {
-        mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED);
+        PasswordPolicy policy = new PasswordPolicy();
+        policy.quality = PASSWORD_QUALITY_UNSPECIFIED;
 
         assertPasswordValidationResult(
+                /* minMetrics */ policy.getMinMetrics(),
                 /* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
                 /* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
                 /* userEnteredPassword= */ LockscreenCredential.createPassword("b1"),
@@ -349,9 +381,11 @@
 
     @Test
     public void processAndValidatePasswordRequirements_defaultPinMinimumLength() {
-        mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED);
+        PasswordPolicy policy = new PasswordPolicy();
+        policy.quality = PASSWORD_QUALITY_UNSPECIFIED;
 
         assertPasswordValidationResult(
+                /* minMetrics */ policy.getMinMetrics(),
                 /* minComplexity= */ PASSWORD_COMPLEXITY_NONE,
                 /* passwordType= */ PASSWORD_QUALITY_NUMERIC,
                 /* userEnteredPassword= */ LockscreenCredential.createPassword("11"),
@@ -360,9 +394,11 @@
 
     @Test
     public void processAndValidatePasswordRequirements_maximumLength() {
-        mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED);
+        PasswordPolicy policy = new PasswordPolicy();
+        policy.quality = PASSWORD_QUALITY_UNSPECIFIED;
 
         assertPasswordValidationResult(
+                /* minMetrics */ policy.getMinMetrics(),
                 /* minComplexity= */ PASSWORD_COMPLEXITY_NONE,
                 /* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
                 LockscreenCredential.createPassword("01234567890123456789"),
@@ -386,6 +422,7 @@
         ShadowLockPatternUtils.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_LOW);
 
         assertPasswordValidationResult(
+                /* minMetrics */ null,
                 /* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
                 /* passwordType= */ PASSWORD_QUALITY_NUMERIC,
                 /* userEnteredPassword= */ LockscreenCredential.createNone(),
@@ -397,7 +434,7 @@
         ShadowLockPatternUtils.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_LOW);
         ShadowLockPatternUtils.setRequiredPasswordComplexity(123, PASSWORD_COMPLEXITY_HIGH);
 
-        Intent intent = createIntentForPasswordValidation(PASSWORD_COMPLEXITY_NONE,
+        Intent intent = createIntentForPasswordValidation(null, PASSWORD_COMPLEXITY_NONE,
                 PASSWORD_QUALITY_NUMERIC);
         intent.putExtra(EXTRA_KEY_UNIFICATION_PROFILE_ID, 123);
         assertPasswordValidationResultForIntent(LockscreenCredential.createNone(), intent,
@@ -423,10 +460,11 @@
         return Shadows.shadowOf(((GlifLayout) fragment.getView()).getIcon());
     }
 
-    private void assertPasswordValidationResult(@PasswordComplexity int minComplexity,
+    private void assertPasswordValidationResult(PasswordMetrics minMetrics,
+            @PasswordComplexity int minComplexity,
             int passwordType, LockscreenCredential userEnteredPassword,
             String... expectedValidationResult) {
-        Intent intent = createIntentForPasswordValidation(minComplexity, passwordType);
+        Intent intent = createIntentForPasswordValidation(minMetrics, minComplexity, passwordType);
         assertPasswordValidationResultForIntent(userEnteredPassword, intent,
                 expectedValidationResult);
     }
@@ -441,12 +479,14 @@
     }
 
     private Intent createIntentForPasswordValidation(
+            PasswordMetrics minMetrics,
             @PasswordComplexity int minComplexity,
             int passwordType) {
         Intent intent = new Intent();
         intent.putExtra(CONFIRM_CREDENTIALS, false);
         intent.putExtra(PASSWORD_TYPE_KEY, passwordType);
-        intent.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, minComplexity);
+        intent.putExtra(ChooseLockPassword.EXTRA_KEY_MIN_METRICS, minMetrics);
+        intent.putExtra(ChooseLockPassword.EXTRA_KEY_MIN_COMPLEXITY, minComplexity);
         return intent;
     }
 }
diff --git a/tests/robotests/src/com/android/settings/password/SetNewPasswordActivityTest.java b/tests/robotests/src/com/android/settings/password/SetNewPasswordActivityTest.java
index f25ef67..a5bc845 100644
--- a/tests/robotests/src/com/android/settings/password/SetNewPasswordActivityTest.java
+++ b/tests/robotests/src/com/android/settings/password/SetNewPasswordActivityTest.java
@@ -24,6 +24,7 @@
 import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;
 
 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_CALLER_APP_NAME;
+import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_DEVICE_PASSWORD_REQUIREMENT_ONLY;
 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_IS_CALLING_APP_ADMIN;
 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY;
 
@@ -300,6 +301,8 @@
         Intent actualIntent = getLaunchChooseLockIntent(shadowActivity);
         assertThat(actualIntent.getAction()).isEqualTo(ACTION_SET_NEW_PARENT_PROFILE_PASSWORD);
         assertThat(actualIntent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isFalse();
+        assertThat(actualIntent.getBooleanExtra(
+                EXTRA_KEY_DEVICE_PASSWORD_REQUIREMENT_ONLY, false)).isFalse();
         assertThat(actualIntent.hasExtra(EXTRA_KEY_CALLER_APP_NAME)).isTrue();
         assertThat(actualIntent.getStringExtra(EXTRA_KEY_CALLER_APP_NAME)).isEqualTo(APP_LABEL);
         verify(mockMetricsProvider).action(
@@ -309,6 +312,23 @@
                 PKG_NAME,
                 Integer.MIN_VALUE);
     }
+    @Test
+    @Config(shadows = {ShadowPasswordUtils.class})
+    public void launchChooseLock_setNewParentProfilePassword_DevicePasswordRequirementExtra() {
+        Settings.Global.putInt(RuntimeEnvironment.application.getContentResolver(),
+                Settings.Global.DEVICE_PROVISIONED, 1);
+
+        Intent intent = new Intent(ACTION_SET_NEW_PARENT_PROFILE_PASSWORD)
+                .putExtra(DevicePolicyManager.EXTRA_DEVICE_PASSWORD_REQUIREMENT_ONLY, true);
+        SetNewPasswordActivity activity =
+                Robolectric.buildActivity(SetNewPasswordActivity.class, intent).create().get();
+
+        ShadowActivity shadowActivity = Shadows.shadowOf(activity);
+        Intent actualIntent = getLaunchChooseLockIntent(shadowActivity);
+
+        assertThat(actualIntent.getBooleanExtra(
+                EXTRA_KEY_DEVICE_PASSWORD_REQUIREMENT_ONLY, false)).isTrue();
+    }
 
     @Test
     @Config(shadows = {ShadowPasswordUtils.class})
diff --git a/tests/robotests/src/com/android/settings/security/CredentialManagementAppControllerTest.java b/tests/robotests/src/com/android/settings/security/CredentialManagementAppControllerTest.java
index 36f056c..eb7165e 100644
--- a/tests/robotests/src/com/android/settings/security/CredentialManagementAppControllerTest.java
+++ b/tests/robotests/src/com/android/settings/security/CredentialManagementAppControllerTest.java
@@ -18,6 +18,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.verify;
+
 import android.content.Context;
 
 import androidx.preference.Preference;
@@ -26,27 +28,35 @@
 import com.android.settings.core.BasePreferenceController;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 
 @RunWith(RobolectricTestRunner.class)
 public class CredentialManagementAppControllerTest {
 
+    @Mock
+    private Preference mPreference;
+
     private Context mContext;
     private CredentialManagementAppPreferenceController mController;
-    private Preference mPreference;
 
     private static final String PREF_KEY_CREDENTIAL_MANAGEMENT_APP = "certificate_management_app";
 
     @Before
     public void setUp() {
+        MockitoAnnotations.initMocks(this);
         mContext = RuntimeEnvironment.application;
         mController = new CredentialManagementAppPreferenceController(
                 mContext, PREF_KEY_CREDENTIAL_MANAGEMENT_APP);
-        mPreference = new Preference(mContext);
+    }
+
+    @Test
+    public void getAvailable_shouldAlwaysReturnTrue() {
+        assertThat(mController.isAvailable()).isTrue();
     }
 
     @Test
@@ -56,12 +66,10 @@
     }
 
     @Test
-    @Ignore
-    public void updateState_noCredentialManagementApp_shouldDisablePreference() {
-        mController.updateState(mPreference);
+    public void displayPreference_noCredentialManagementApp_shouldDisablePreference() {
+        mController.displayPreference(mPreference);
 
-        assertThat(mPreference.isEnabled()).isEqualTo(false);
-        assertThat(mPreference.getSummary()).isEqualTo(
-                mContext.getText(R.string.no_certificate_management_app));
+        verify(mPreference).setEnabled(false);
+        verify(mPreference).setSummary(R.string.no_certificate_management_app);
     }
 }
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java
index 3a159b2..20547d7 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java
@@ -17,6 +17,7 @@
 package com.android.settings.testutils.shadow;
 
 import android.app.admin.DevicePolicyManager;
+import android.app.admin.PasswordMetrics;
 import android.content.ComponentName;
 import android.os.UserHandle;
 
@@ -36,11 +37,17 @@
 
     private static boolean sDeviceEncryptionEnabled;
     private static Map<Integer, Integer> sUserToComplexityMap = new HashMap<>();
+    private static Map<Integer, Integer> sUserToProfileComplexityMap = new HashMap<>();
+    private static Map<Integer, PasswordMetrics> sUserToMetricsMap = new HashMap<>();
+    private static Map<Integer, PasswordMetrics> sUserToProfileMetricsMap = new HashMap<>();
 
 
     @Resetter
     public static void reset() {
         sUserToComplexityMap.clear();
+        sUserToProfileComplexityMap.clear();
+        sUserToMetricsMap.clear();
+        sUserToProfileMetricsMap.clear();
         sDeviceEncryptionEnabled = false;
     }
 
@@ -91,15 +98,50 @@
 
     @Implementation
     public @DevicePolicyManager.PasswordComplexity int getRequestedPasswordComplexity(int userId) {
-        return sUserToComplexityMap.getOrDefault(userId,
-                DevicePolicyManager.PASSWORD_COMPLEXITY_NONE);
+        return getRequestedPasswordComplexity(userId, false);
     }
 
-    public static void setRequiredPasswordComplexity(int userId, int complexity) {
-        sUserToComplexityMap.put(userId, complexity);
+    @Implementation
+    public @DevicePolicyManager.PasswordComplexity int getRequestedPasswordComplexity(int userId,
+            boolean deviceWideOnly) {
+        int complexity = sUserToComplexityMap.getOrDefault(userId,
+                DevicePolicyManager.PASSWORD_COMPLEXITY_NONE);
+        if (!deviceWideOnly) {
+            complexity = Math.max(complexity, sUserToProfileComplexityMap.getOrDefault(userId,
+                    DevicePolicyManager.PASSWORD_COMPLEXITY_NONE));
+        }
+        return complexity;
+    }
+
+    public static void setRequiredPasswordComplexity(int userHandle, int complexity) {
+        sUserToComplexityMap.put(userHandle, complexity);
     }
 
     public static void setRequiredPasswordComplexity(int complexity) {
-        setRequiredPasswordComplexity(UserHandle.myUserId(), complexity);
+        sUserToComplexityMap.put(UserHandle.myUserId(), complexity);
     }
+
+    public static void setRequiredProfilePasswordComplexity(int complexity) {
+        sUserToProfileComplexityMap.put(UserHandle.myUserId(), complexity);
+    }
+
+    @Implementation
+    public PasswordMetrics getRequestedPasswordMetrics(int userId, boolean deviceWideOnly) {
+        PasswordMetrics metrics = sUserToMetricsMap.getOrDefault(userId,
+                new PasswordMetrics(LockPatternUtils.CREDENTIAL_TYPE_NONE));
+        if (!deviceWideOnly) {
+            metrics.maxWith(sUserToProfileMetricsMap.getOrDefault(userId,
+                    new PasswordMetrics(LockPatternUtils.CREDENTIAL_TYPE_NONE)));
+        }
+        return metrics;
+    }
+
+    public static void setRequestedPasswordMetrics(PasswordMetrics metrics) {
+        sUserToMetricsMap.put(UserHandle.myUserId(), metrics);
+    }
+
+    public static void setRequestedProfilePasswordMetrics(PasswordMetrics metrics) {
+        sUserToProfileMetricsMap.put(UserHandle.myUserId(), metrics);
+    }
+
 }