Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f4e71b00 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Support EXTRA_DEVICE_PASSWORD_REQUIREMENT_ONLY"

parents 1c7eba66 ff1b5475
Loading
Loading
Loading
Loading
+35 −18
Original line number Diff line number Diff line
@@ -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;

@@ -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;

@@ -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;
@@ -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(
@@ -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)) {
@@ -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,
@@ -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;
@@ -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);
@@ -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)
+25 −11
Original line number Diff line number Diff line
@@ -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;
@@ -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) {
@@ -51,6 +50,7 @@ public class ChooseLockGenericController {
                context,
                userId,
                PASSWORD_COMPLEXITY_NONE,
                /* mOnlyEnforceDevicePasswordRequirement */ false,
                new LockPatternUtils(context));
    }

@@ -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);
    }
@@ -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()));
    }

    /**
@@ -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));
    }
}
+27 −13
Original line number Diff line number Diff line
@@ -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;
@@ -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;

@@ -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());
@@ -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;
        }

@@ -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;
        }

@@ -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;
@@ -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));
@@ -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);

+6 −0
Original line number Diff line number Diff line
@@ -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;
+17 −7
Original line number Diff line number Diff line
@@ -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;

@@ -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.
     *
@@ -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 "
@@ -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();
    }

@@ -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