Support EXTRA_DEVICE_PASSWORD_REQUIREMENT_ONLY
When set, only enforce password requirement explicitly set device-wide.
As part of the change, restructure the code such that ChooseLockGeneric
becomes the central place for aggregating password requirements from
different parties, while ChooseLockPassword only enforces whatever
password reuirement it is told (by ChooseLockGeneric via intent extras)
Bug: 169832516
Test: m RunSettingsRoboTests ROBOTEST_FILTER=com.android.settings.password
Change-Id: I0acbea4819c13d4a8444c7b06928baccead18837
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/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/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);
+ }
+
}