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

Commit 010116a1 authored by Rubin Xu's avatar Rubin Xu
Browse files

Introduce LockscreenCredential

Bug: 65239740
Test: make RunSettingsRoboTests ROBOTEST_FILTER=com.android.settings.password
Change-Id: Icb73d639291d6d2eda8015e18e93d0906f916bb2
parent 4c1bfdfe
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -727,7 +727,7 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList
        public void onPatternDetected(List<LockPatternView.Cell> pattern) {
            mLockPatternView.setEnabled(false);
            if (pattern.size() >= MIN_LENGTH_BEFORE_REPORT) {
                new DecryptTask().execute(LockPatternUtils.patternToString(pattern));
                new DecryptTask().execute(new String(LockPatternUtils.patternToByteArray(pattern)));
            } else {
                // Allow user to make as many of these as they want.
                fakeUnlockAttempt(mLockPatternView);
+10 −8
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;

import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockscreenCredential;
import com.android.settings.EncryptionInterstitial;
import com.android.settings.EventLogTags;
import com.android.settings.R;
@@ -151,7 +152,7 @@ public class ChooseLockGeneric extends SettingsActivity {
        private boolean mPasswordConfirmed = false;
        private boolean mWaitingForConfirmation = false;
        private boolean mForChangeCredRequiredForBoot = false;
        private byte[] mUserPassword;
        private LockscreenCredential mUserPassword;
        private LockPatternUtils mLockPatternUtils;
        private FingerprintManager mFingerprintManager;
        private FaceManager mFaceManager;
@@ -207,7 +208,7 @@ public class ChooseLockGeneric extends SettingsActivity {
                .getBooleanExtra(CONFIRM_CREDENTIALS, true);
            if (getActivity() instanceof ChooseLockGeneric.InternalActivity) {
                mPasswordConfirmed = !confirmCredentials;
                mUserPassword = getActivity().getIntent().getByteArrayExtra(
                mUserPassword = getActivity().getIntent().getParcelableExtra(
                        ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
            }

@@ -233,7 +234,7 @@ public class ChooseLockGeneric extends SettingsActivity {
                mPasswordConfirmed = savedInstanceState.getBoolean(PASSWORD_CONFIRMED);
                mWaitingForConfirmation = savedInstanceState.getBoolean(WAITING_FOR_CONFIRMATION);
                if (mUserPassword == null) {
                    mUserPassword = savedInstanceState.getByteArray(
                    mUserPassword = savedInstanceState.getParcelable(
                            ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
                }
            }
@@ -392,11 +393,11 @@ public class ChooseLockGeneric extends SettingsActivity {
            if (requestCode == CONFIRM_EXISTING_REQUEST && resultCode == Activity.RESULT_OK) {
                mPasswordConfirmed = true;
                mUserPassword = data != null
                    ? data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD)
                    ? data.getParcelableExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD)
                    : null;
                updatePreferencesOrFinish(false /* isRecreatingActivity */);
                if (mForChangeCredRequiredForBoot) {
                    if (!(mUserPassword == null || mUserPassword.length == 0)) {
                    if (mUserPassword != null && !mUserPassword.isNone()) {
                        maybeEnableEncryption(
                                mLockPatternUtils.getKeyguardStoredPasswordQuality(mUserId), false);
                    } else {
@@ -459,7 +460,7 @@ public class ChooseLockGeneric extends SettingsActivity {
            outState.putBoolean(PASSWORD_CONFIRMED, mPasswordConfirmed);
            outState.putBoolean(WAITING_FOR_CONFIRMATION, mWaitingForConfirmation);
            if (mUserPassword != null) {
                outState.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, mUserPassword);
                outState.putParcelable(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, mUserPassword);
            }
        }

@@ -682,7 +683,7 @@ public class ChooseLockGeneric extends SettingsActivity {
            setPreferenceSummary(ScreenLockType.MANAGED, R.string.secure_lock_encryption_warning);
        }

        protected Intent getLockManagedPasswordIntent(byte[] password) {
        protected Intent getLockManagedPasswordIntent(LockscreenCredential password) {
            return mManagedPasswordProvider.createIntent(false, password);
        }

@@ -759,7 +760,8 @@ public class ChooseLockGeneric extends SettingsActivity {
            if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
                // Clearing of user biometrics when screen lock is cleared is done at
                // LockSettingsService.removeBiometricsForUser().
                mChooseLockSettingsHelper.utils().clearLock(mUserPassword, mUserId);
                mChooseLockSettingsHelper.utils().setLockCredential(
                        LockscreenCredential.createNone(), mUserPassword, mUserId);
                mChooseLockSettingsHelper.utils().setLockScreenDisabled(disabled, mUserId);
                getActivity().setResult(Activity.RESULT_OK);
                finish();
+49 −41
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockPatternUtils.RequestThrottledException;
import com.android.internal.widget.LockscreenCredential;
import com.android.internal.widget.TextViewInputDisabler;
import com.android.settings.EncryptionInterstitial;
import com.android.settings.R;
@@ -124,7 +125,7 @@ public class ChooseLockPassword extends SettingsActivity {
            return this;
        }

        public IntentBuilder setPassword(byte[] password) {
        public IntentBuilder setPassword(LockscreenCredential password) {
            mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, password);
            return this;
        }
@@ -180,13 +181,13 @@ public class ChooseLockPassword extends SettingsActivity {

    public static class ChooseLockPasswordFragment extends InstrumentedFragment
            implements OnEditorActionListener, TextWatcher, SaveAndFinishWorker.Listener {
        private static final String KEY_FIRST_PIN = "first_pin";
        private static final String KEY_FIRST_PASSWORD = "first_password";
        private static final String KEY_UI_STAGE = "ui_stage";
        private static final String KEY_CURRENT_PASSWORD = "current_password";
        private static final String KEY_CURRENT_CREDENTIAL = "current_credential";
        private static final String FRAGMENT_TAG_SAVE_AND_FINISH = "save_and_finish_worker";

        private byte[] mCurrentPassword;
        private byte[] mChosenPassword;
        private LockscreenCredential mCurrentCredential;
        private LockscreenCredential mChosenPassword;
        private boolean mHasChallenge;
        private long mChallenge;
        private ImeAwareEditText mPasswordEntry;
@@ -215,7 +216,7 @@ public class ChooseLockPassword extends SettingsActivity {
        protected boolean mForFingerprint;
        protected boolean mForFace;

        private byte[] mFirstPin;
        private LockscreenCredential mFirstPassword;
        private RecyclerView mPasswordRestrictionView;
        protected boolean mIsAlphaMode;
        protected FooterButton mSkipOrClearButton;
@@ -394,13 +395,13 @@ public class ChooseLockPassword extends SettingsActivity {
                SaveAndFinishWorker w = new SaveAndFinishWorker();
                final boolean required = getActivity().getIntent().getBooleanExtra(
                        EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
                byte[] currentBytes = intent.getByteArrayExtra(
                LockscreenCredential currentCredential = intent.getParcelableExtra(
                        ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);

                w.setBlocking(true);
                w.setListener(this);
                w.start(mChooseLockSettingsHelper.utils(), required, false, 0,
                        currentBytes, currentBytes, mRequestedQuality, mUserId);
                        currentCredential, currentCredential, mUserId);
            }
            mTextChangedHandler = new TextChangedHandler();
        }
@@ -482,7 +483,7 @@ public class ChooseLockPassword extends SettingsActivity {
            Intent intent = getActivity().getIntent();
            final boolean confirmCredentials = intent.getBooleanExtra(
                    ChooseLockGeneric.CONFIRM_CREDENTIALS, true);
            mCurrentPassword = intent.getByteArrayExtra(
            mCurrentCredential = intent.getParcelableExtra(
                    ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
            mHasChallenge = intent.getBooleanExtra(
                    ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
@@ -497,15 +498,15 @@ public class ChooseLockPassword extends SettingsActivity {
            } else {

                // restore from previous state
                mFirstPin = savedInstanceState.getByteArray(KEY_FIRST_PIN);
                mFirstPassword = savedInstanceState.getParcelable(KEY_FIRST_PASSWORD);
                final String state = savedInstanceState.getString(KEY_UI_STAGE);
                if (state != null) {
                    mUiStage = Stage.valueOf(state);
                    updateStage(mUiStage);
                }

                if (mCurrentPassword == null) {
                    mCurrentPassword = savedInstanceState.getByteArray(KEY_CURRENT_PASSWORD);
                if (mCurrentCredential == null) {
                    mCurrentCredential = savedInstanceState.getParcelable(KEY_CURRENT_CREDENTIAL);
                }

                // Re-attach to the exiting worker if there is one.
@@ -563,8 +564,8 @@ public class ChooseLockPassword extends SettingsActivity {
        public void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
            outState.putString(KEY_UI_STAGE, mUiStage.name());
            outState.putByteArray(KEY_FIRST_PIN, mFirstPin);
            outState.putByteArray(KEY_CURRENT_PASSWORD, mCurrentPassword);
            outState.putParcelable(KEY_FIRST_PASSWORD, mFirstPassword);
            outState.putParcelable(KEY_CURRENT_CREDENTIAL, mCurrentCredential);
        }

        @Override
@@ -577,7 +578,7 @@ public class ChooseLockPassword extends SettingsActivity {
                        getActivity().setResult(RESULT_FINISHED);
                        getActivity().finish();
                    } else {
                        mCurrentPassword = data.getByteArrayExtra(
                        mCurrentCredential = data.getParcelableExtra(
                                ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
                    }
                    break;
@@ -722,7 +723,8 @@ public class ChooseLockPassword extends SettingsActivity {
         * @return the validation result.
         */
        @VisibleForTesting
        int validatePassword(byte[] password) {
        int validatePassword(LockscreenCredential credential) {
            final byte[] password = credential.getCredential();
            int errorCode = NO_ERROR;
            final PasswordMetrics metrics = PasswordMetrics.computeForPassword(password);
            mergeMinComplexityAndDpmRequirements(metrics.quality);
@@ -812,7 +814,8 @@ public class ChooseLockPassword extends SettingsActivity {
        private byte[] getPasswordHistoryHashFactor() {
            if (mPasswordHistoryHashFactor == null) {
                mPasswordHistoryHashFactor = mLockPatternUtils.getPasswordHistoryHashFactor(
                        mCurrentPassword, mUserId);
                        mCurrentCredential != null ? mCurrentCredential
                                : LockscreenCredential.createNone(), mUserId);
            }
            return mPasswordHistoryHashFactor;
        }
@@ -820,20 +823,22 @@ public class ChooseLockPassword extends SettingsActivity {
        public void handleNext() {
            if (mSaveAndFinishWorker != null) return;
            // TODO(b/120484642): This is a point of entry for passwords from the UI
            mChosenPassword = LockPatternUtils.charSequenceToByteArray(mPasswordEntry.getText());
            if (mChosenPassword == null || mChosenPassword.length == 0) {
            final Editable passwordText = mPasswordEntry.getText();
            if (TextUtils.isEmpty(passwordText)) {
                return;
            }
            mChosenPassword = mIsAlphaMode ? LockscreenCredential.createPassword(passwordText)
                    : LockscreenCredential.createPin(passwordText);
            if (mUiStage == Stage.Introduction) {
                if (validatePassword(mChosenPassword) == NO_ERROR) {
                    mFirstPin = mChosenPassword;
                    mFirstPassword = mChosenPassword;
                    mPasswordEntry.setText("");
                    updateStage(Stage.NeedToConfirm);
                } else {
                    Arrays.fill(mChosenPassword, (byte) 0);
                    mChosenPassword.zeroize();
                }
            } else if (mUiStage == Stage.NeedToConfirm) {
                if (Arrays.equals(mFirstPin, mChosenPassword)) {
                if (mChosenPassword.equals(mFirstPassword)) {
                    startSaveAndFinish();
                } else {
                    CharSequence tmp = mPasswordEntry.getText();
@@ -841,7 +846,7 @@ public class ChooseLockPassword extends SettingsActivity {
                        Selection.setSelection((Spannable) tmp, 0, tmp.length());
                    }
                    updateStage(Stage.ConfirmWrong);
                    Arrays.fill(mChosenPassword, (byte) 0);
                    mChosenPassword.zeroize();
                }
            }
        }
@@ -954,8 +959,11 @@ public class ChooseLockPassword extends SettingsActivity {
         */
        protected void updateUi() {
            final boolean canInput = mSaveAndFinishWorker == null;
            byte[] password = LockPatternUtils.charSequenceToByteArray(mPasswordEntry.getText());
            final int length = password.length;

            LockscreenCredential password = mIsAlphaMode
                    ? LockscreenCredential.createPasswordOrNone(mPasswordEntry.getText())
                    : LockscreenCredential.createPinOrNone(mPasswordEntry.getText());
            final int length = password.size();
            if (mUiStage == Stage.Introduction) {
                mPasswordRestrictionView.setVisibility(View.VISIBLE);
                final int errorCode = validatePassword(password);
@@ -981,7 +989,7 @@ public class ChooseLockPassword extends SettingsActivity {

            setNextText(mUiStage.buttonText);
            mPasswordEntryInputDisabler.setInputEnabled(canInput);
            Arrays.fill(password, (byte) 0);
            password.zeroize();
        }

        protected int toVisibility(boolean visibleOrGone) {
@@ -1033,7 +1041,7 @@ public class ChooseLockPassword extends SettingsActivity {
            final boolean required = getActivity().getIntent().getBooleanExtra(
                    EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
            mSaveAndFinishWorker.start(mLockPatternUtils, required, mHasChallenge, mChallenge,
                    mChosenPassword, mCurrentPassword, mRequestedQuality, mUserId);
                    mChosenPassword, mCurrentCredential, mUserId);
        }

        @Override
@@ -1041,13 +1049,13 @@ public class ChooseLockPassword extends SettingsActivity {
            getActivity().setResult(RESULT_FINISHED, resultData);

            if (mChosenPassword != null) {
                Arrays.fill(mChosenPassword, (byte) 0);
                mChosenPassword.zeroize();
            }
            if (mCurrentPassword != null) {
                Arrays.fill(mCurrentPassword, (byte) 0);
            if (mCurrentCredential != null) {
                mCurrentCredential.zeroize();
            }
            if (mFirstPin != null) {
                Arrays.fill(mFirstPin, (byte) 0);
            if (mFirstPassword != null) {
                mFirstPassword.zeroize();
            }

            mPasswordEntry.setText("");
@@ -1088,18 +1096,18 @@ public class ChooseLockPassword extends SettingsActivity {

    public static class SaveAndFinishWorker extends SaveChosenLockWorkerBase {

        private byte[] mChosenPassword;
        private byte[] mCurrentPassword;
        private int mRequestedQuality;
        private LockscreenCredential mChosenPassword;
        private LockscreenCredential mCurrentCredential;

        public void start(LockPatternUtils utils, boolean required,
                boolean hasChallenge, long challenge,
                byte[] chosenPassword, byte[] currentPassword, int requestedQuality, int userId) {
                LockscreenCredential chosenPassword, LockscreenCredential currentCredential,
                int userId) {
            prepare(utils, required, hasChallenge, challenge, userId);

            mChosenPassword = chosenPassword;
            mCurrentPassword = currentPassword;
            mRequestedQuality = requestedQuality;
            mCurrentCredential = currentCredential != null ? currentCredential
                    : LockscreenCredential.createNone();
            mUserId = userId;

            start();
@@ -1107,13 +1115,13 @@ public class ChooseLockPassword extends SettingsActivity {

        @Override
        protected Pair<Boolean, Intent> saveAndVerifyInBackground() {
            final boolean success = mUtils.saveLockPassword(
                    mChosenPassword, mCurrentPassword, mRequestedQuality, mUserId);
            final boolean success = mUtils.setLockCredential(
                    mChosenPassword, mCurrentCredential, mUserId);
            Intent result = null;
            if (success && mHasChallenge) {
                byte[] token;
                try {
                    token = mUtils.verifyPassword(mChosenPassword, mChallenge, mUserId);
                    token = mUtils.verifyCredential(mChosenPassword, mChallenge, mUserId);
                } catch (RequestThrottledException e) {
                    token = null;
                }
+41 −34

File changed.

Preview size limit exceeded, changes collapsed.

+20 −12
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.os.CountDownTimer;
import android.os.SystemClock;
import android.os.UserManager;
import android.os.storage.StorageManager;
import android.text.Editable;
import android.text.InputType;
import android.text.TextUtils;
import android.view.KeyEvent;
@@ -44,6 +45,7 @@ import androidx.fragment.app.Fragment;

import com.android.internal.widget.LockPatternChecker;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockscreenCredential;
import com.android.internal.widget.TextViewInputDisabler;
import com.android.settings.R;
import com.android.settings.widget.ImeAwareEditText;
@@ -332,10 +334,13 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
            }

            // TODO(b/120484642): This is a point of entry for passwords from the UI
            final byte[] pin = LockPatternUtils.charSequenceToByteArray(mPasswordEntry.getText());
            if (pin == null || pin.length == 0) {
            final Editable passwordText = mPasswordEntry.getText();
            if (TextUtils.isEmpty(passwordText)) {
                return;
            }
            final LockscreenCredential credential =
                    mIsAlpha ? LockscreenCredential.createPassword(passwordText)
                    : LockscreenCredential.createPin(passwordText);

            mPasswordEntryInputDisabler.setInputEnabled(false);
            final boolean verifyChallenge = getActivity().getIntent().getBooleanExtra(
@@ -344,11 +349,11 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
            Intent intent = new Intent();
            if (verifyChallenge)  {
                if (isInternalActivity()) {
                    startVerifyPassword(pin, intent);
                    startVerifyPassword(credential, intent);
                    return;
                }
            } else {
                startCheckPassword(pin, intent);
                startCheckPassword(credential, intent);
                return;
            }

@@ -359,7 +364,7 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
            return getActivity() instanceof ConfirmLockPassword.InternalActivity;
        }

        private void startVerifyPassword(final byte[] pin, final Intent intent) {
        private void startVerifyPassword(LockscreenCredential credential, final Intent intent) {
            long challenge = getActivity().getIntent().getLongExtra(
                    ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
            final int localEffectiveUserId = mEffectiveUserId;
@@ -383,29 +388,32 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
                        }
            };
            mPendingLockCheck = (localEffectiveUserId == localUserId)
                    ? LockPatternChecker.verifyPassword(
                            mLockPatternUtils, pin, challenge, localUserId, onVerifyCallback)
                    ? LockPatternChecker.verifyCredential(
                            mLockPatternUtils, credential, challenge, localUserId, onVerifyCallback)
                    : LockPatternChecker.verifyTiedProfileChallenge(
                            mLockPatternUtils, pin, false, challenge, localUserId,
                            mLockPatternUtils, credential, challenge, localUserId,
                            onVerifyCallback);
        }

        private void startCheckPassword(final byte[] pin, final Intent intent) {
        private void startCheckPassword(final LockscreenCredential credential,
                final Intent intent) {
            final int localEffectiveUserId = mEffectiveUserId;
            mPendingLockCheck = LockPatternChecker.checkPassword(
            mPendingLockCheck = LockPatternChecker.checkCredential(
                    mLockPatternUtils,
                    pin,
                    credential,
                    localEffectiveUserId,
                    new LockPatternChecker.OnCheckCallback() {
                        @Override
                        public void onChecked(boolean matched, int timeoutMs) {
                            mPendingLockCheck = null;
                            if (matched && isInternalActivity() && mReturnCredentials) {
                                // TODO: get rid of EXTRA_KEY_TYPE, since EXTRA_KEY_PASSWORD already
                                // distinguishes beteween PIN and password.
                                intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE,
                                                mIsAlpha ? StorageManager.CRYPT_TYPE_PASSWORD
                                                         : StorageManager.CRYPT_TYPE_PIN);
                                intent.putExtra(
                                        ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, pin);
                                        ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, credential);
                            }
                            mCredentialCheckResultTracker.setResult(matched, intent, timeoutMs,
                                    localEffectiveUserId);
Loading