Loading src/com/android/settings/password/ChooseLockGeneric.java +35 −18 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE; 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; Loading Loading @@ -162,6 +163,8 @@ public class ChooseLockGeneric extends SettingsActivity { /** * 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; Loading @@ -178,6 +181,8 @@ public class ChooseLockGeneric extends SettingsActivity { protected boolean mForFace = false; protected boolean mForBiometrics = false; private boolean mOnlyEnforceDevicePasswordRequirement = false; @Override public int getMetricsCategory() { return SettingsEnums.CHOOSE_LOCK_GENERIC; Loading Loading @@ -221,20 +226,11 @@ public class ChooseLockGeneric extends SettingsActivity { 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( Loading Loading @@ -268,7 +264,22 @@ public class ChooseLockGeneric extends SettingsActivity { 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)) { Loading Loading @@ -356,6 +367,8 @@ public class ChooseLockGeneric extends SettingsActivity { 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, Loading Loading @@ -557,7 +570,7 @@ public class ChooseLockGeneric extends SettingsActivity { private String getFooterString() { @StringRes int stringId; switch (mRequestedMinComplexity) { switch (mController.getAggregatedPasswordComplexity()) { case PASSWORD_COMPLEXITY_HIGH: stringId = R.string.unlock_footer_high_complexity_requested; break; Loading Loading @@ -678,7 +691,9 @@ public class ChooseLockGeneric extends SettingsActivity { 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); Loading Loading @@ -753,8 +768,10 @@ public class ChooseLockGeneric extends SettingsActivity { 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) Loading src/com/android/settings/password/ChooseLockGenericController.java +25 −11 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.settings.password; 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; Loading @@ -42,8 +41,8 @@ public class ChooseLockGenericController { 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) { Loading @@ -51,6 +50,7 @@ public class ChooseLockGenericController { context, userId, PASSWORD_COMPLEXITY_NONE, /* mOnlyEnforceDevicePasswordRequirement */ false, new LockPatternUtils(context)); } Loading @@ -59,12 +59,14 @@ public class ChooseLockGenericController { * 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); } Loading @@ -74,28 +76,29 @@ public class ChooseLockGenericController { 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())); } /** Loading Loading @@ -193,4 +196,15 @@ public class ChooseLockGenericController { } return locks; } public PasswordMetrics getAggregatedPasswordMetrics() { return mLockPatternUtils.getRequestedPasswordMetrics(mUserId, mDevicePasswordRequirementOnly); } public int getAggregatedPasswordComplexity() { return Math.max(mRequestedMinComplexity, mLockPatternUtils.getRequestedPasswordComplexity( mUserId, mDevicePasswordRequirementOnly)); } } src/com/android/settings/password/ChooseLockPassword.java +27 −13 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.settings.password; 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; Loading @@ -31,7 +32,6 @@ import static com.android.internal.widget.PasswordValidationError.NOT_ENOUGH_UPP 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; Loading Loading @@ -96,6 +96,9 @@ import java.util.List; 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()); Loading @@ -119,8 +122,13 @@ public class ChooseLockPassword extends SettingsActivity { 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; } Loading Loading @@ -156,8 +164,11 @@ public class ChooseLockPassword extends SettingsActivity { 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; } Loading Loading @@ -240,7 +251,7 @@ public class ChooseLockPassword extends SettingsActivity { 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; Loading Loading @@ -410,19 +421,22 @@ public class ChooseLockPassword extends SettingsActivity { 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)); Loading Loading @@ -494,9 +508,9 @@ public class ChooseLockPassword extends SettingsActivity { 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); Loading src/com/android/settings/password/ChooseLockSettingsHelper.java +6 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,12 @@ public final class ChooseLockSettingsHelper { */ 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; Loading src/com/android/settings/password/SetNewPasswordActivity.java +17 −7 Original line number Diff line number Diff line Loading @@ -19,10 +19,12 @@ package com.android.settings.password; 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; Loading Loading @@ -62,6 +64,8 @@ public class SetNewPasswordActivity extends Activity implements SetNewPasswordCo */ private @PasswordComplexity int mRequestedMinComplexity = PASSWORD_COMPLEXITY_NONE; private boolean mDevicePasswordRequirementOnly = false; /** * Label of the app which launches this activity. * Loading @@ -72,27 +76,27 @@ public class SetNewPasswordActivity extends Activity implements SetNewPasswordCo @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 " Loading @@ -102,9 +106,14 @@ public class SetNewPasswordActivity extends Activity implements SetNewPasswordCo 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(); } Loading @@ -124,6 +133,7 @@ public class SetNewPasswordActivity extends Activity implements SetNewPasswordCo if (isCallingAppAdmin()) { intent.putExtra(EXTRA_KEY_IS_CALLING_APP_ADMIN, true); } intent.putExtra(EXTRA_KEY_DEVICE_PASSWORD_REQUIREMENT_ONLY, mDevicePasswordRequirementOnly); startActivity(intent); finish(); } Loading Loading
src/com/android/settings/password/ChooseLockGeneric.java +35 −18 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE; 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; Loading Loading @@ -162,6 +163,8 @@ public class ChooseLockGeneric extends SettingsActivity { /** * 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; Loading @@ -178,6 +181,8 @@ public class ChooseLockGeneric extends SettingsActivity { protected boolean mForFace = false; protected boolean mForBiometrics = false; private boolean mOnlyEnforceDevicePasswordRequirement = false; @Override public int getMetricsCategory() { return SettingsEnums.CHOOSE_LOCK_GENERIC; Loading Loading @@ -221,20 +226,11 @@ public class ChooseLockGeneric extends SettingsActivity { 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( Loading Loading @@ -268,7 +264,22 @@ public class ChooseLockGeneric extends SettingsActivity { 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)) { Loading Loading @@ -356,6 +367,8 @@ public class ChooseLockGeneric extends SettingsActivity { 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, Loading Loading @@ -557,7 +570,7 @@ public class ChooseLockGeneric extends SettingsActivity { private String getFooterString() { @StringRes int stringId; switch (mRequestedMinComplexity) { switch (mController.getAggregatedPasswordComplexity()) { case PASSWORD_COMPLEXITY_HIGH: stringId = R.string.unlock_footer_high_complexity_requested; break; Loading Loading @@ -678,7 +691,9 @@ public class ChooseLockGeneric extends SettingsActivity { 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); Loading Loading @@ -753,8 +768,10 @@ public class ChooseLockGeneric extends SettingsActivity { 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) Loading
src/com/android/settings/password/ChooseLockGenericController.java +25 −11 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.settings.password; 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; Loading @@ -42,8 +41,8 @@ public class ChooseLockGenericController { 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) { Loading @@ -51,6 +50,7 @@ public class ChooseLockGenericController { context, userId, PASSWORD_COMPLEXITY_NONE, /* mOnlyEnforceDevicePasswordRequirement */ false, new LockPatternUtils(context)); } Loading @@ -59,12 +59,14 @@ public class ChooseLockGenericController { * 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); } Loading @@ -74,28 +76,29 @@ public class ChooseLockGenericController { 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())); } /** Loading Loading @@ -193,4 +196,15 @@ public class ChooseLockGenericController { } return locks; } public PasswordMetrics getAggregatedPasswordMetrics() { return mLockPatternUtils.getRequestedPasswordMetrics(mUserId, mDevicePasswordRequirementOnly); } public int getAggregatedPasswordComplexity() { return Math.max(mRequestedMinComplexity, mLockPatternUtils.getRequestedPasswordComplexity( mUserId, mDevicePasswordRequirementOnly)); } }
src/com/android/settings/password/ChooseLockPassword.java +27 −13 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.settings.password; 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; Loading @@ -31,7 +32,6 @@ import static com.android.internal.widget.PasswordValidationError.NOT_ENOUGH_UPP 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; Loading Loading @@ -96,6 +96,9 @@ import java.util.List; 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()); Loading @@ -119,8 +122,13 @@ public class ChooseLockPassword extends SettingsActivity { 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; } Loading Loading @@ -156,8 +164,11 @@ public class ChooseLockPassword extends SettingsActivity { 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; } Loading Loading @@ -240,7 +251,7 @@ public class ChooseLockPassword extends SettingsActivity { 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; Loading Loading @@ -410,19 +421,22 @@ public class ChooseLockPassword extends SettingsActivity { 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)); Loading Loading @@ -494,9 +508,9 @@ public class ChooseLockPassword extends SettingsActivity { 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); Loading
src/com/android/settings/password/ChooseLockSettingsHelper.java +6 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,12 @@ public final class ChooseLockSettingsHelper { */ 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; Loading
src/com/android/settings/password/SetNewPasswordActivity.java +17 −7 Original line number Diff line number Diff line Loading @@ -19,10 +19,12 @@ package com.android.settings.password; 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; Loading Loading @@ -62,6 +64,8 @@ public class SetNewPasswordActivity extends Activity implements SetNewPasswordCo */ private @PasswordComplexity int mRequestedMinComplexity = PASSWORD_COMPLEXITY_NONE; private boolean mDevicePasswordRequirementOnly = false; /** * Label of the app which launches this activity. * Loading @@ -72,27 +76,27 @@ public class SetNewPasswordActivity extends Activity implements SetNewPasswordCo @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 " Loading @@ -102,9 +106,14 @@ public class SetNewPasswordActivity extends Activity implements SetNewPasswordCo 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(); } Loading @@ -124,6 +133,7 @@ public class SetNewPasswordActivity extends Activity implements SetNewPasswordCo if (isCallingAppAdmin()) { intent.putExtra(EXTRA_KEY_IS_CALLING_APP_ADMIN, true); } intent.putExtra(EXTRA_KEY_DEVICE_PASSWORD_REQUIREMENT_ONLY, mDevicePasswordRequirementOnly); startActivity(intent); finish(); } Loading