Introduce LockscreenCredential

Bug: 65239740
Test: make RunSettingsRoboTests ROBOTEST_FILTER=com.android.settings.password
Change-Id: Icb73d639291d6d2eda8015e18e93d0906f916bb2
This commit is contained in:
Rubin Xu
2019-09-11 17:36:37 +01:00
parent 4c1bfdfe73
commit 010116a173
13 changed files with 189 additions and 152 deletions

View File

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

View File

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

View File

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

View File

@@ -36,12 +36,14 @@ import android.widget.TextView;
import androidx.fragment.app.Fragment;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockPatternUtils.RequestThrottledException;
import com.android.internal.widget.LockPatternView;
import com.android.internal.widget.LockPatternView.Cell;
import com.android.internal.widget.LockPatternView.DisplayMode;
import com.android.internal.widget.LockscreenCredential;
import com.android.settings.EncryptionInterstitial;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
@@ -116,7 +118,7 @@ public class ChooseLockPattern extends SettingsActivity {
return this;
}
public IntentBuilder setPattern(byte[] pattern) {
public IntentBuilder setPattern(LockscreenCredential pattern) {
mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, pattern);
return this;
}
@@ -188,7 +190,7 @@ public class ChooseLockPattern extends SettingsActivity {
private static final String FRAGMENT_TAG_SAVE_AND_FINISH = "save_and_finish_worker";
private byte[] mCurrentPattern;
private LockscreenCredential mCurrentCredential;
private boolean mHasChallenge;
private long mChallenge;
protected TextView mTitleText;
@@ -198,7 +200,7 @@ public class ChooseLockPattern extends SettingsActivity {
protected TextView mFooterText;
protected FooterButton mSkipOrClearButton;
private FooterButton mNextButton;
protected List<LockPatternView.Cell> mChosenPattern = null;
@VisibleForTesting protected LockscreenCredential mChosenPattern;
private ColorStateList mDefaultHeaderColorList;
// ScrollView that contains title and header, only exist in land mode
@@ -225,7 +227,7 @@ public class ChooseLockPattern extends SettingsActivity {
getActivity().setResult(RESULT_FINISHED);
getActivity().finish();
} else {
mCurrentPattern = data.getByteArrayExtra(
mCurrentCredential = data.getParcelableExtra(
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
}
@@ -262,16 +264,19 @@ public class ChooseLockPattern extends SettingsActivity {
if (mUiStage == Stage.NeedToConfirm || mUiStage == Stage.ConfirmWrong) {
if (mChosenPattern == null) throw new IllegalStateException(
"null chosen pattern in stage 'need to confirm");
if (mChosenPattern.equals(pattern)) {
try (LockscreenCredential confirmPattern =
LockscreenCredential.createPattern(pattern)) {
if (mChosenPattern.equals(confirmPattern)) {
updateStage(Stage.ChoiceConfirmed);
} else {
updateStage(Stage.ConfirmWrong);
}
}
} else if (mUiStage == Stage.Introduction || mUiStage == Stage.ChoiceTooShort){
if (pattern.size() < LockPatternUtils.MIN_LOCK_PATTERN_SIZE) {
updateStage(Stage.ChoiceTooShort);
} else {
mChosenPattern = new ArrayList<LockPatternView.Cell>(pattern);
mChosenPattern = LockscreenCredential.createPattern(pattern);
updateStage(Stage.FirstChoiceValid);
}
} else {
@@ -458,12 +463,12 @@ public class ChooseLockPattern extends SettingsActivity {
SaveAndFinishWorker w = new SaveAndFinishWorker();
final boolean required = getActivity().getIntent().getBooleanExtra(
EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
byte[] current = intent.getByteArrayExtra(
LockscreenCredential current = intent.getParcelableExtra(
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
w.setBlocking(true);
w.setListener(this);
w.start(mChooseLockSettingsHelper.utils(), required,
false, 0, LockPatternUtils.byteArrayToPattern(current), current, mUserId);
false, 0, current, current, mUserId);
}
mForFingerprint = intent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
@@ -541,8 +546,8 @@ public class ChooseLockPattern extends SettingsActivity {
final boolean confirmCredentials = getActivity().getIntent()
.getBooleanExtra(ChooseLockGeneric.CONFIRM_CREDENTIALS, true);
Intent intent = getActivity().getIntent();
mCurrentPattern =
intent.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
mCurrentCredential =
intent.getParcelableExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
mHasChallenge = intent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
mChallenge = intent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
@@ -565,13 +570,10 @@ public class ChooseLockPattern extends SettingsActivity {
}
} else {
// restore from previous state
final byte[] pattern = savedInstanceState.getByteArray(KEY_PATTERN_CHOICE);
if (pattern != null) {
mChosenPattern = LockPatternUtils.byteArrayToPattern(pattern);
}
mChosenPattern = savedInstanceState.getParcelable(KEY_PATTERN_CHOICE);
if (mCurrentPattern == null) {
mCurrentPattern = savedInstanceState.getByteArray(KEY_CURRENT_PATTERN);
if (mCurrentCredential == null) {
mCurrentCredential = savedInstanceState.getParcelable(KEY_CURRENT_PATTERN);
}
updateStage(Stage.values()[savedInstanceState.getInt(KEY_UI_STAGE)]);
@@ -606,6 +608,7 @@ public class ChooseLockPattern extends SettingsActivity {
public void handleLeftButton() {
if (mUiStage.leftMode == LeftButtonMode.Retry) {
mChosenPattern.zeroize();
mChosenPattern = null;
mLockPatternView.clearPattern();
updateStage(Stage.Introduction);
@@ -667,12 +670,11 @@ public class ChooseLockPattern extends SettingsActivity {
outState.putInt(KEY_UI_STAGE, mUiStage.ordinal());
if (mChosenPattern != null) {
outState.putByteArray(KEY_PATTERN_CHOICE,
LockPatternUtils.patternToByteArray(mChosenPattern));
outState.putParcelable(KEY_PATTERN_CHOICE, mChosenPattern);
}
if (mCurrentPattern != null) {
outState.putByteArray(KEY_CURRENT_PATTERN, mCurrentPattern);
if (mCurrentCredential != null) {
outState.putParcelable(KEY_CURRENT_PATTERN, mCurrentCredential);
}
}
@@ -812,15 +814,18 @@ public class ChooseLockPattern extends SettingsActivity {
final boolean required = getActivity().getIntent().getBooleanExtra(
EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
mSaveAndFinishWorker.start(mChooseLockSettingsHelper.utils(), required,
mHasChallenge, mChallenge, mChosenPattern, mCurrentPattern, mUserId);
mHasChallenge, mChallenge, mChosenPattern, mCurrentCredential, mUserId);
}
@Override
public void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData) {
getActivity().setResult(RESULT_FINISHED, resultData);
if (mCurrentPattern != null) {
Arrays.fill(mCurrentPattern, (byte) 0);
if (mChosenPattern != null) {
mChosenPattern.zeroize();
}
if (mCurrentCredential != null) {
mCurrentCredential.zeroize();
}
if (!wasSecureBefore) {
@@ -835,16 +840,17 @@ public class ChooseLockPattern extends SettingsActivity {
public static class SaveAndFinishWorker extends SaveChosenLockWorkerBase {
private List<LockPatternView.Cell> mChosenPattern;
private byte[] mCurrentPattern;
private LockscreenCredential mChosenPattern;
private LockscreenCredential mCurrentCredential;
private boolean mLockVirgin;
public void start(LockPatternUtils utils, boolean credentialRequired,
boolean hasChallenge, long challenge,
List<LockPatternView.Cell> chosenPattern, byte[] currentPattern, int userId) {
public void start(LockPatternUtils utils, boolean credentialRequired, boolean hasChallenge,
long challenge, LockscreenCredential chosenPattern,
LockscreenCredential currentCredential, int userId) {
prepare(utils, credentialRequired, hasChallenge, challenge, userId);
mCurrentPattern = currentPattern;
mCurrentCredential = currentCredential != null ? currentCredential
: LockscreenCredential.createNone();
mChosenPattern = chosenPattern;
mUserId = userId;
@@ -856,12 +862,13 @@ public class ChooseLockPattern extends SettingsActivity {
@Override
protected Pair<Boolean, Intent> saveAndVerifyInBackground() {
final int userId = mUserId;
final boolean success = mUtils.saveLockPattern(mChosenPattern, mCurrentPattern, userId);
final boolean success = mUtils.setLockCredential(mChosenPattern, mCurrentCredential,
userId);
Intent result = null;
if (success && mHasChallenge) {
byte[] token;
try {
token = mUtils.verifyPattern(mChosenPattern, mChallenge, userId);
token = mUtils.verifyCredential(mChosenPattern, mChallenge, userId);
} catch (RequestThrottledException e) {
token = null;
}

View File

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

View File

@@ -37,6 +37,7 @@ import com.android.internal.widget.LockPatternChecker;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockPatternView;
import com.android.internal.widget.LockPatternView.Cell;
import com.android.internal.widget.LockscreenCredential;
import com.android.settings.R;
import com.android.settingslib.animation.AppearAnimationCreator;
import com.android.settingslib.animation.AppearAnimationUtils;
@@ -401,14 +402,16 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
final boolean verifyChallenge = getActivity().getIntent().getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
final LockscreenCredential credential = LockscreenCredential.createPattern(pattern);
//TODO: how to sanitize this?
Intent intent = new Intent();
if (verifyChallenge) {
if (isInternalActivity()) {
startVerifyPattern(pattern, intent);
startVerifyPattern(credential, intent);
return;
}
} else {
startCheckPattern(pattern, intent);
startCheckPattern(credential, intent);
return;
}
@@ -419,7 +422,7 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
return getActivity() instanceof ConfirmLockPattern.InternalActivity;
}
private void startVerifyPattern(final List<LockPatternView.Cell> pattern,
private void startVerifyPattern(final LockscreenCredential pattern,
final Intent intent) {
final int localEffectiveUserId = mEffectiveUserId;
final int localUserId = mUserId;
@@ -444,15 +447,15 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
}
};
mPendingLockCheck = (localEffectiveUserId == localUserId)
? LockPatternChecker.verifyPattern(
? LockPatternChecker.verifyCredential(
mLockPatternUtils, pattern, challenge, localUserId,
onVerifyCallback)
: LockPatternChecker.verifyTiedProfileChallenge(
mLockPatternUtils, LockPatternUtils.patternToByteArray(pattern),
true, challenge, localUserId, onVerifyCallback);
mLockPatternUtils, pattern,
challenge, localUserId, onVerifyCallback);
}
private void startCheckPattern(final List<LockPatternView.Cell> pattern,
private void startCheckPattern(final LockscreenCredential pattern,
final Intent intent) {
if (pattern.size() < LockPatternUtils.MIN_PATTERN_REGISTER_FAIL) {
// Pattern size is less than the minimum, do not count it as an fail attempt.
@@ -461,7 +464,7 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
}
final int localEffectiveUserId = mEffectiveUserId;
mPendingLockCheck = LockPatternChecker.checkPattern(
mPendingLockCheck = LockPatternChecker.checkCredential(
mLockPatternUtils,
pattern,
localEffectiveUserId,
@@ -473,7 +476,7 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE,
StorageManager.CRYPT_TYPE_PATTERN);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD,
LockPatternUtils.patternToByteArray(pattern));
pattern);
}
mCredentialCheckResultTracker.setResult(matched, intent, timeoutMs,
localEffectiveUserId);

View File

@@ -19,6 +19,8 @@ package com.android.settings.password;
import android.content.Context;
import android.content.Intent;
import com.android.internal.widget.LockscreenCredential;
/**
* Helper for handling managed passwords in security settings UI.
* It provides resources that should be shown in settings UI when lock password quality is set to
@@ -59,7 +61,7 @@ public class ManagedLockPasswordProvider {
* @param password Current lock password.
* @return Intent that should update lock password to a managed password.
*/
Intent createIntent(boolean requirePasswordToDecrypt, byte[] password) {
Intent createIntent(boolean requirePasswordToDecrypt, LockscreenCredential password) {
return null;
}
}

View File

@@ -37,6 +37,7 @@ import android.widget.Button;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.Preference;
import com.android.internal.widget.LockscreenCredential;
import com.android.settings.CryptKeeperConfirm;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
@@ -193,9 +194,10 @@ public class CryptKeeperSettings extends InstrumentedPreferenceFragment {
// confirmation prompt; otherwise, go back to the initial state.
if (resultCode == Activity.RESULT_OK && data != null) {
int type = data.getIntExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE, -1);
byte[] password = data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
if (!(password == null || password.length == 0)) {
showFinalConfirmation(type, password);
LockscreenCredential password = data.getParcelableExtra(
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
if (password != null && !password.isNone()) {
showFinalConfirmation(type, password.getCredential());
}
}
}

View File

@@ -32,6 +32,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.R;
import com.android.settings.Utils;
import com.android.settings.core.PreferenceControllerMixin;
@@ -70,8 +71,8 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr
private RestrictedSwitchPreference mUnifyProfile;
private byte[] mCurrentDevicePassword;
private byte[] mCurrentProfilePassword;
private LockscreenCredential mCurrentDevicePassword;
private LockscreenCredential mCurrentProfilePassword;
private boolean mKeepDeviceLock;
@Override
@@ -89,6 +90,8 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr
.getSecurityFeatureProvider()
.getLockPatternUtils(context);
mProfileUserId = Utils.getManagedProfileId(mUm, MY_USER_ID);
mCurrentDevicePassword = LockscreenCredential.createNone();
mCurrentProfilePassword = LockscreenCredential.createNone();
}
@Override
@@ -151,13 +154,13 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr
} else if (requestCode == UNIFY_LOCK_CONFIRM_DEVICE_REQUEST
&& resultCode == Activity.RESULT_OK) {
mCurrentDevicePassword =
data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
data.getParcelableExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
launchConfirmProfileLock();
return true;
} else if (requestCode == UNIFY_LOCK_CONFIRM_PROFILE_REQUEST
&& resultCode == Activity.RESULT_OK) {
mCurrentProfilePassword =
data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
data.getParcelableExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
unifyLocks();
return true;
}
@@ -221,17 +224,8 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr
}
private void unifyKeepingWorkLock() {
final int profileQuality =
mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileUserId);
// PASSWORD_QUALITY_SOMETHING means pattern, everything above means PIN/password.
if (profileQuality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) {
mLockPatternUtils.saveLockPattern(
LockPatternUtils.byteArrayToPattern(mCurrentProfilePassword),
mCurrentDevicePassword, MY_USER_ID);
} else {
mLockPatternUtils.saveLockPassword(
mCurrentProfilePassword, mCurrentDevicePassword, profileQuality, MY_USER_ID);
}
mLockPatternUtils.setLockCredential(
mCurrentProfilePassword, mCurrentDevicePassword, MY_USER_ID);
mLockPatternUtils.setSeparateProfileChallengeEnabled(mProfileUserId, false,
mCurrentProfilePassword);
final boolean profilePatternVisibility =

View File

@@ -41,6 +41,7 @@ import android.app.admin.DevicePolicyManager.PasswordComplexity;
import android.content.Intent;
import android.os.UserHandle;
import com.android.internal.widget.LockscreenCredential;
import com.android.settings.R;
import com.android.settings.password.ChooseLockPassword.ChooseLockPasswordFragment;
import com.android.settings.password.ChooseLockPassword.IntentBuilder;
@@ -87,7 +88,7 @@ public class ChooseLockPasswordTest {
@Test
public void intentBuilder_setPassword_shouldAddExtras() {
Intent intent = new IntentBuilder(application)
.setPassword("password".getBytes())
.setPassword(LockscreenCredential.createPassword("password"))
.setPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC)
.setUserId(123)
.build();
@@ -95,9 +96,10 @@ public class ChooseLockPasswordTest {
assertThat(intent.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true))
.named("EXTRA_KEY_HAS_CHALLENGE")
.isFalse();
assertThat(intent.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD))
assertThat((LockscreenCredential) intent.getParcelableExtra(
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD))
.named("EXTRA_KEY_PASSWORD")
.isEqualTo("password".getBytes());
.isEqualTo(LockscreenCredential.createPassword("password"));
assertThat(intent.getIntExtra(PASSWORD_TYPE_KEY, 0))
.named("PASSWORD_TYPE_KEY")
.isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
@@ -154,7 +156,7 @@ public class ChooseLockPasswordTest {
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_NONE,
/* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
/* userEnteredPassword= */ "",
/* userEnteredPassword= */ LockscreenCredential.createNone(),
"Must contain at least 1 letter",
"Must be at least 10 characters");
}
@@ -166,7 +168,7 @@ public class ChooseLockPasswordTest {
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
/* passwordType= */ PASSWORD_QUALITY_NUMERIC,
/* userEnteredPassword= */ "",
/* userEnteredPassword= */ LockscreenCredential.createNone(),
"PIN must be at least 8 digits");
}
@@ -177,7 +179,7 @@ public class ChooseLockPasswordTest {
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_MEDIUM,
/* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
/* userEnteredPassword= */ "",
/* userEnteredPassword= */ LockscreenCredential.createNone(),
"Must contain at least 1 letter",
"Must be at least 4 characters");
}
@@ -190,7 +192,7 @@ public class ChooseLockPasswordTest {
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_LOW,
/* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
/* userEnteredPassword= */ "",
/* userEnteredPassword= */ LockscreenCredential.createNone(),
"Must contain at least 1 letter",
"Must contain at least 1 numerical digit",
"Must be at least 9 characters");
@@ -204,7 +206,7 @@ public class ChooseLockPasswordTest {
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_MEDIUM,
/* passwordType= */ PASSWORD_QUALITY_NUMERIC,
/* userEnteredPassword= */ "",
/* userEnteredPassword= */ LockscreenCredential.createNone(),
"PIN must be at least 11 digits");
}
@@ -216,7 +218,7 @@ public class ChooseLockPasswordTest {
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
/* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
/* userEnteredPassword= */ "",
/* userEnteredPassword= */ LockscreenCredential.createNone(),
"Must contain at least 2 special symbols",
"Must be at least 6 characters");
}
@@ -229,7 +231,7 @@ public class ChooseLockPasswordTest {
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_NONE,
/* passwordType= */ PASSWORD_QUALITY_NUMERIC,
/* userEnteredPassword= */ "12345678",
/* userEnteredPassword= */ LockscreenCredential.createPassword("12345678"),
"Ascending, descending, or repeated sequence of digits isn't allowed");
}
@@ -241,7 +243,7 @@ public class ChooseLockPasswordTest {
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_NONE,
/* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
/* userEnteredPassword= */ "12345678",
/* userEnteredPassword= */ LockscreenCredential.createPassword("12345678"),
"Ascending, descending, or repeated sequence of digits isn't allowed");
}
@@ -253,7 +255,7 @@ public class ChooseLockPasswordTest {
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
/* passwordType= */ PASSWORD_QUALITY_NUMERIC,
/* userEnteredPassword= */ "12345678",
/* userEnteredPassword= */ LockscreenCredential.createPassword("12345678"),
"Ascending, descending, or repeated sequence of digits isn't allowed");
}
@@ -265,7 +267,7 @@ public class ChooseLockPasswordTest {
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
/* passwordType= */ PASSWORD_QUALITY_NUMERIC,
/* userEnteredPassword= */ "12345678",
/* userEnteredPassword= */ LockscreenCredential.createPassword("12345678"),
"Ascending, descending, or repeated sequence of digits isn't allowed");
}
@@ -277,7 +279,7 @@ public class ChooseLockPasswordTest {
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_LOW,
/* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
/* userEnteredPassword= */ "12345678",
/* userEnteredPassword= */ LockscreenCredential.createPassword("12345678"),
"Must contain at least 1 letter");
}
@@ -288,7 +290,7 @@ public class ChooseLockPasswordTest {
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
/* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
/* userEnteredPassword= */ "",
/* userEnteredPassword= */ LockscreenCredential.createNone(),
"Must contain at least 1 letter",
"Must be at least 6 characters");
}
@@ -300,7 +302,7 @@ public class ChooseLockPasswordTest {
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
/* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
/* userEnteredPassword= */ "1",
/* userEnteredPassword= */ LockscreenCredential.createPassword("1"),
"Must contain at least 1 letter",
"Must be at least 6 characters");
}
@@ -312,7 +314,7 @@ public class ChooseLockPasswordTest {
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
/* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
/* userEnteredPassword= */ "b",
/* userEnteredPassword= */ LockscreenCredential.createPassword("b"),
"Must be at least 6 characters");
}
@@ -323,7 +325,7 @@ public class ChooseLockPasswordTest {
assertPasswordValidationResult(
/* minComplexity= */ PASSWORD_COMPLEXITY_HIGH,
/* passwordType= */ PASSWORD_QUALITY_ALPHABETIC,
/* userEnteredPassword= */ "b1",
/* userEnteredPassword= */ LockscreenCredential.createPassword("b1"),
"Must be at least 6 characters");
}
@@ -359,16 +361,15 @@ public class ChooseLockPasswordTest {
}
private void assertPasswordValidationResult(@PasswordComplexity int minComplexity,
int passwordType, String userEnteredPassword, String... expectedValidationResult) {
int passwordType, LockscreenCredential userEnteredPassword,
String... expectedValidationResult) {
Intent intent = new Intent();
intent.putExtra(CONFIRM_CREDENTIALS, false);
intent.putExtra(PASSWORD_TYPE_KEY, passwordType);
intent.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, minComplexity);
ChooseLockPassword activity = buildChooseLockPasswordActivity(intent);
ChooseLockPasswordFragment fragment = getChooseLockPasswordFragment(activity);
byte[] userEnteredPasswordBytes = userEnteredPassword != null
? userEnteredPassword.getBytes() : null;
int validateResult = fragment.validatePassword(userEnteredPasswordBytes);
int validateResult = fragment.validatePassword(userEnteredPassword);
String[] messages = fragment.convertErrorCodeToMessages(validateResult);
assertThat(messages).asList().containsExactly((Object[]) expectedValidationResult);

View File

@@ -24,6 +24,8 @@ import android.content.Intent;
import android.os.UserHandle;
import android.view.View;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockscreenCredential;
import com.android.settings.R;
import com.android.settings.password.ChooseLockPattern.ChooseLockPatternFragment;
import com.android.settings.password.ChooseLockPattern.IntentBuilder;
@@ -52,7 +54,7 @@ public class ChooseLockPatternTest {
@Test
public void intentBuilder_setPattern_shouldAddExtras() {
Intent intent = new IntentBuilder(application)
.setPattern("pattern".getBytes())
.setPattern(createPattern("1234"))
.setUserId(123)
.build();
@@ -60,10 +62,10 @@ public class ChooseLockPatternTest {
.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true))
.named("EXTRA_KEY_HAS_CHALLENGE")
.isFalse();
assertThat(intent
.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD))
assertThat((LockscreenCredential) intent
.getParcelableExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD))
.named("EXTRA_KEY_PASSWORD")
.isEqualTo("pattern".getBytes());
.isEqualTo(createPattern("1234"));
assertThat(intent.getIntExtra(Intent.EXTRA_USER_ID, 0))
.named("EXTRA_USER_ID")
.isEqualTo(123);
@@ -120,4 +122,9 @@ public class ChooseLockPatternTest {
.build())
.setup().get();
}
private LockscreenCredential createPattern(String patternString) {
return LockscreenCredential.createPattern(LockPatternUtils.byteArrayToPattern(
patternString.getBytes()));
}
}

View File

@@ -20,6 +20,7 @@ import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockscreenCredential;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
@@ -66,7 +67,8 @@ public class ShadowLockPatternUtils {
}
@Implementation
protected byte[] getPasswordHistoryHashFactor(byte[] currentPassword, int userId) {
protected byte[] getPasswordHistoryHashFactor(LockscreenCredential currentPassword,
int userId) {
return null;
}

View File

@@ -43,6 +43,7 @@ import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
import androidx.test.runner.lifecycle.Stage;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockscreenCredential;
import org.junit.Before;
import org.junit.Rule;
@@ -150,7 +151,7 @@ public class ChooseLockGenericTest {
.putExtra(LockPatternUtils.PASSWORD_TYPE_KEY,
DevicePolicyManager.PASSWORD_QUALITY_NUMERIC)
.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD,
"12345")
LockscreenCredential.createPin("12345"))
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getInstrumentation().getContext().startActivity(newPasswordIntent);
mDevice.waitForIdle();