diff --git a/src/com/android/settings/biometrics/BiometricEnrollActivity.java b/src/com/android/settings/biometrics/BiometricEnrollActivity.java index 4179ea3d96d..4f2f4e6c2a3 100644 --- a/src/com/android/settings/biometrics/BiometricEnrollActivity.java +++ b/src/com/android/settings/biometrics/BiometricEnrollActivity.java @@ -104,9 +104,14 @@ public class BiometricEnrollActivity extends InstrumentedActivity { .getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN); final int userId = getIntent() .getIntExtra(Intent.EXTRA_USER_ID, UserHandle.USER_NULL); + final byte[] gkPw = getIntent().getByteArrayExtra( + ChooseLockSettingsHelper.EXTRA_KEY_GK_PW); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token); intent.putExtra(Intent.EXTRA_USER_ID, userId); + if (gkPw != null) { + intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW, gkPw); + } } startActivity(intent); diff --git a/src/com/android/settings/biometrics/BiometricEnrollBase.java b/src/com/android/settings/biometrics/BiometricEnrollBase.java index 0017117fc6b..b905e3e3d21 100644 --- a/src/com/android/settings/biometrics/BiometricEnrollBase.java +++ b/src/com/android/settings/biometrics/BiometricEnrollBase.java @@ -88,7 +88,13 @@ public abstract class BiometricEnrollBase extends InstrumentedActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - mToken = getIntent().getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN); + // Don't need to retrieve the HAT if it already exists. In some cases, the extras do not + // contain EXTRA_KEY_CHALLENGE_TOKEN but contain EXTRA_KEY_GK_PW, in which case enrollment + // classes may request a HAT to be created (as opposed to being passed in) + if (mToken == null) { + mToken = getIntent().getByteArrayExtra( + ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN); + } mFromSettingsSummary = getIntent().getBooleanExtra(EXTRA_FROM_SETTINGS_SUMMARY, false); if (savedInstanceState != null && mToken == null) { mLaunchedConfirmLock = savedInstanceState.getBoolean(EXTRA_KEY_LAUNCHED_CONFIRM); @@ -180,11 +186,11 @@ public abstract class BiometricEnrollBase extends InstrumentedActivity { return intent; } - protected void launchConfirmLock(int titleResId, long challenge) { + protected void launchConfirmLock(int titleResId) { final ChooseLockSettingsHelper.Builder builder = new ChooseLockSettingsHelper.Builder(this); builder.setRequestCode(CONFIRM_REQUEST) .setTitle(getString(titleResId)) - .setChallenge(challenge) + .setRequestGatekeeperPassword(true) .setForegroundOnly(true) .setReturnCredentials(true); diff --git a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java index 2e81974bee3..8634441e9bb 100644 --- a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java +++ b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java @@ -101,7 +101,7 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase /** * @return the challenge generated by the biometric hardware */ - protected abstract long getChallenge(); + protected abstract void getChallenge(GenerateChallengeCallback callback); /** * @return one of the ChooseLockSettingsHelper#EXTRA_KEY_FOR_* constants @@ -125,6 +125,10 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase */ public abstract void onClick(LinkSpan span); + protected interface GenerateChallengeCallback { + void onChallengeGenerated(long challenge); + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -160,11 +164,11 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase // No password registered, launch into enrollment wizard. mConfirmingCredentials = true; launchChooseLock(); - } else if (mToken == null) { + } else if (!BiometricUtils.containsGatekeeperPassword(getIntent()) && mToken == null) { // It's possible to have a token but mLaunchedConfirmLock == false, since // ChooseLockGeneric can pass us a token. mConfirmingCredentials = true; - launchConfirmLock(getConfirmLockTitleResId(), getChallenge()); + launchConfirmLock(getConfirmLockTitleResId()); } } } @@ -217,12 +221,10 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase private void launchChooseLock() { Intent intent = getChooseLockIntent(); - long challenge = getChallenge(); intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING); intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true); - intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true); - intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge); + intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, true); intent.putExtra(getExtraKeyForBiometric(), true); if (mUserId != UserHandle.USER_NULL) { intent.putExtra(Intent.EXTRA_USER_ID, mUserId); @@ -269,13 +271,15 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase return; } } else if (requestCode == CHOOSE_LOCK_GENERIC_REQUEST) { + mConfirmingCredentials = false; if (resultCode == RESULT_FINISHED) { updatePasswordQuality(); - mToken = data.getByteArrayExtra( - ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN); overridePendingTransition(R.anim.sud_slide_next_in, R.anim.sud_slide_next_out); - mConfirmingCredentials = false; - return; + getNextButton().setEnabled(false); + getChallenge((challenge -> { + mToken = BiometricUtils.requestGatekeeperHat(this, data, mUserId, challenge); + getNextButton().setEnabled(true); + })); } else { setResult(resultCode, data); finish(); @@ -283,8 +287,12 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase } else if (requestCode == CONFIRM_REQUEST) { mConfirmingCredentials = false; if (resultCode == RESULT_OK && data != null) { - mToken = data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN); overridePendingTransition(R.anim.sud_slide_next_in, R.anim.sud_slide_next_out); + getNextButton().setEnabled(false); + getChallenge((challenge -> { + mToken = BiometricUtils.requestGatekeeperHat(this, data, mUserId, challenge); + getNextButton().setEnabled(true); + })); } else { setResult(resultCode, data); finish(); diff --git a/src/com/android/settings/biometrics/BiometricUtils.java b/src/com/android/settings/biometrics/BiometricUtils.java new file mode 100644 index 00000000000..f33c3c2974b --- /dev/null +++ b/src/com/android/settings/biometrics/BiometricUtils.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.biometrics; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; + +import com.android.internal.widget.LockPatternUtils; +import com.android.settings.password.ChooseLockSettingsHelper; + +/** + * Common biometric utilities. + */ +public class BiometricUtils { + /** + * Given the result from confirming or choosing a credential, request Gatekeeper to generate + * a HardwareAuthToken with the Gatekeeper Password together with a biometric challenge. + * + * @param context Caller's context + * @param result The onActivityResult intent from ChooseLock* or ConfirmLock* + * @param userId User ID that the credential/biometric operation applies to + * @param challenge Unique biometric challenge from FingerprintManager/FaceManager + * @return + */ + public static byte[] requestGatekeeperHat(Context context, Intent result, int userId, + long challenge) { + final byte[] gkPassword = result.getByteArrayExtra( + ChooseLockSettingsHelper.EXTRA_KEY_GK_PW); + if (gkPassword == null) { + throw new IllegalStateException("Gatekeeper Password is null!!"); + } + + final LockPatternUtils utils = new LockPatternUtils(context); + return utils.verifyGatekeeperPassword(gkPassword, challenge, userId).getGatekeeperHAT(); + } + + public static boolean containsGatekeeperPassword(Intent data) { + if (data == null) { + return false; + } + return data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW) != null; + } +} diff --git a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java index 780fb2e88a5..3db51fec4c7 100644 --- a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java +++ b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java @@ -26,6 +26,7 @@ import android.widget.TextView; import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.biometrics.BiometricEnrollIntroduction; +import com.android.settings.biometrics.BiometricUtils; import com.android.settings.overlay.FeatureFactory; import com.android.settings.password.ChooseLockSettingsHelper; import com.android.settingslib.RestrictedLockUtilsInternal; @@ -38,7 +39,7 @@ import com.google.android.setupdesign.template.RequireScrollMixin; public class FaceEnrollIntroduction extends BiometricEnrollIntroduction { - private static final String TAG = "FaceIntro"; + private static final String TAG = "FaceEnrollIntroduction"; private FaceManager mFaceManager; private FaceFeatureProvider mFaceFeatureProvider; @@ -86,9 +87,7 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction { RequireScrollMixin.class); requireScrollMixin.requireScrollWithButton(this, agreeButton, R.string.security_settings_face_enroll_introduction_more, - button -> { - onNextButtonClick(button); - }); + this::onNextButtonClick); } final TextView footer2 = findViewById(R.id.face_enroll_introduction_footer_part_2); @@ -97,6 +96,18 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction { ? R.string.security_settings_face_enroll_introduction_footer_part_2 : R.string.security_settings_face_settings_footer_attention_not_supported; footer2.setText(footer2TextResource); + + // This path is an entry point for SetNewPasswordController, e.g. + // adb shell am start -a android.app.action.SET_NEW_PASSWORD + if (mToken == null && BiometricUtils.containsGatekeeperPassword(getIntent())) { + mFooterBarMixin.getPrimaryButton().setEnabled(false); + // We either block on generateChallenge, or need to gray out the "next" button until + // the challenge is ready. Let's just do this for now. + mFaceManager.generateChallenge(challenge -> { + mToken = BiometricUtils.requestGatekeeperHat(this, getIntent(), mUserId, challenge); + mFooterBarMixin.getPrimaryButton().setEnabled(true); + }); + } } @Override @@ -171,12 +182,13 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction { } @Override - protected long getChallenge() { + protected void getChallenge(GenerateChallengeCallback callback) { mFaceManager = Utils.getFaceManagerOrNull(this); if (mFaceManager == null) { - return 0; + callback.onChallengeGenerated(0L); + return; } - return mFaceManager.generateChallengeBlocking(); + mFaceManager.generateChallenge(callback::onChallengeGenerated); } @Override diff --git a/src/com/android/settings/biometrics/face/FaceSettings.java b/src/com/android/settings/biometrics/face/FaceSettings.java index 1c984286c48..976c6e3237d 100644 --- a/src/com/android/settings/biometrics/face/FaceSettings.java +++ b/src/com/android/settings/biometrics/face/FaceSettings.java @@ -37,6 +37,7 @@ import androidx.preference.Preference; import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.Utils; +import com.android.settings.biometrics.BiometricUtils; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.overlay.FeatureFactory; import com.android.settings.password.ChooseLockSettingsHelper; @@ -202,15 +203,11 @@ public class FaceSettings extends DashboardFragment { super.onResume(); if (mToken == null && !mConfirmingPassword) { - // Generate challenge in onResume instead of onCreate, since FaceSettings can be - // created while Keyguard is showing, in which case the resetLockout revokeChallenge - // will invalidate the too-early created challenge here. - final long challenge = mFaceManager.generateChallengeBlocking(); final ChooseLockSettingsHelper.Builder builder = new ChooseLockSettingsHelper.Builder(getActivity(), this); final boolean launched = builder.setRequestCode(CONFIRM_REQUEST) .setTitle(getString(R.string.security_settings_face_preference_title)) - .setChallenge(challenge) + .setRequestGatekeeperPassword(true) .setUserId(mUserId) .setForegroundOnly(true) .setReturnCredentials(true) @@ -238,18 +235,22 @@ public class FaceSettings extends DashboardFragment { @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); + + if (mToken == null && !BiometricUtils.containsGatekeeperPassword(data)) { + Log.e(TAG, "No credential"); + finish(); + } + if (requestCode == CONFIRM_REQUEST) { - mConfirmingPassword = false; if (resultCode == RESULT_FINISHED || resultCode == RESULT_OK) { // The pin/pattern/password was set. - if (data != null) { - mToken = data.getByteArrayExtra( - ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN); - if (mToken != null) { - mAttentionController.setToken(mToken); - mEnrollController.setToken(mToken); - } - } + mFaceManager.generateChallenge(challenge -> { + mToken = BiometricUtils.requestGatekeeperHat(getPrefContext(), data, mUserId, + challenge); + mAttentionController.setToken(mToken); + mEnrollController.setToken(mToken); + mConfirmingPassword = false; + }); } } else if (requestCode == ENROLL_REQUEST) { if (resultCode == RESULT_TIMEOUT) { @@ -257,11 +258,6 @@ public class FaceSettings extends DashboardFragment { finish(); } } - - if (mToken == null) { - // Didn't get an authentication, finishing - finish(); - } } @Override diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java index dbedb4a4ebd..8795f7f6f5b 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java @@ -28,6 +28,7 @@ import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.biometrics.BiometricEnrollBase; import com.android.settings.biometrics.BiometricEnrollSidecar.Listener; +import com.android.settings.biometrics.BiometricUtils; import com.android.settings.password.ChooseLockSettingsHelper; import com.google.android.setupcompat.template.FooterBarMixin; @@ -60,8 +61,24 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase { setHeaderText(R.string.security_settings_fingerprint_enroll_find_sensor_title); + // This is an entry point for SetNewPasswordController, e.g. + // adb shell am start -a android.app.action.SET_NEW_PASSWORD + if (mToken == null && BiometricUtils.containsGatekeeperPassword(getIntent())) { + final FingerprintManager fpm = getSystemService(FingerprintManager.class); + fpm.generateChallenge(challenge -> { + mToken = BiometricUtils.requestGatekeeperHat(this, getIntent(), mUserId, challenge); - startLookingForFingerprint(); // already confirmed, so start looking for fingerprint + // Put this into the intent. This is really just to work around the fact that the + // enrollment sidecar gets the HAT from the activity's intent, rather than having + // it passed in. + getIntent().putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken); + + startLookingForFingerprint(); + }); + } else if (mToken != null) { + // HAT passed in from somewhere else, such as FingerprintEnrollIntroduction + startLookingForFingerprint(); + } View animationView = findViewById(R.id.fingerprint_sensor_location_animation); if (animationView instanceof FingerprintFindSensorAnimation) { @@ -160,10 +177,13 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase { protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == CONFIRM_REQUEST) { if (resultCode == RESULT_OK && data != null) { + throw new IllegalStateException("Pretty sure this is dead code"); + /* mToken = data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN); overridePendingTransition(R.anim.sud_slide_next_in, R.anim.sud_slide_next_out); getIntent().putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken); startLookingForFingerprint(); + */ } else { finish(); } diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java index ccfb0f26155..0b5c7b0ff77 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java @@ -131,12 +131,13 @@ public class FingerprintEnrollIntroduction extends BiometricEnrollIntroduction { } @Override - protected long getChallenge() { + protected void getChallenge(GenerateChallengeCallback callback) { mFingerprintManager = Utils.getFingerprintManagerOrNull(this); if (mFingerprintManager == null) { - return 0; + callback.onChallengeGenerated(0L); + return; } - return mFingerprintManager.generateChallengeBlocking(); + mFingerprintManager.generateChallenge(callback::onChallengeGenerated); } @Override diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java index 1fa9a4717b6..a2d67f41d86 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java @@ -54,6 +54,7 @@ import com.android.settings.SettingsPreferenceFragment; import com.android.settings.SubSettings; import com.android.settings.Utils; import com.android.settings.biometrics.BiometricEnrollBase; +import com.android.settings.biometrics.BiometricUtils; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settings.password.ChooseLockGeneric; import com.android.settings.password.ChooseLockSettingsHelper; @@ -410,6 +411,8 @@ public class FingerprintSettings extends SubSettings { private void updateAddPreference() { if (getActivity() == null) return; // Activity went away + final Preference addPreference = findPreference(KEY_FINGERPRINT_ADD); + /* Disable preference if too many fingerprints added */ final int max = getContext().getResources().getInteger( com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser); @@ -419,9 +422,8 @@ public class FingerprintSettings extends SubSettings { final boolean removalInProgress = mRemovalSidecar.inProgress(); CharSequence maxSummary = tooMany ? getContext().getString(R.string.fingerprint_add_max, max) : ""; - Preference addPreference = findPreference(KEY_FINGERPRINT_ADD); addPreference.setSummary(maxSummary); - addPreference.setEnabled(!tooMany && !removalInProgress); + addPreference.setEnabled(!tooMany && !removalInProgress && mToken != null); } private void createFooterPreference(PreferenceGroup root) { @@ -565,15 +567,22 @@ public class FingerprintSettings extends SubSettings { @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); - if (requestCode == CHOOSE_LOCK_GENERIC_REQUEST - || requestCode == CONFIRM_REQUEST) { + if (requestCode == CONFIRM_REQUEST || requestCode == CHOOSE_LOCK_GENERIC_REQUEST) { mLaunchedConfirm = false; if (resultCode == RESULT_FINISHED || resultCode == RESULT_OK) { - // The lock pin/pattern/password was set. Start enrolling! - if (data != null) { - mToken = data.getByteArrayExtra( - ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN); + if (data != null && BiometricUtils.containsGatekeeperPassword(data)) { + mFingerprintManager.generateChallenge(challenge -> { + mToken = BiometricUtils.requestGatekeeperHat(getActivity(), data, + mUserId, challenge); + updateAddPreference(); + }); + } else { + Log.d(TAG, "Data null or GK PW missing"); + finish(); } + } else { + Log.d(TAG, "Password not confirmed"); + finish(); } } else if (requestCode == ADD_FINGERPRINT_REQUEST) { mEnrollClicked = false; @@ -583,11 +592,6 @@ public class FingerprintSettings extends SubSettings { activity.finish(); } } - - if (mToken == null) { - // Didn't get an authentication, finishing - getActivity().finish(); - } } @Override @@ -635,26 +639,26 @@ public class FingerprintSettings extends SubSettings { private void launchChooseOrConfirmLock() { final Intent intent = new Intent(); - final long challenge = mFingerprintManager.generateChallengeBlocking(); final ChooseLockSettingsHelper.Builder builder = new ChooseLockSettingsHelper.Builder(getActivity(), this); final boolean launched = builder.setRequestCode(CONFIRM_REQUEST) .setTitle(getString(R.string.security_settings_fingerprint_preference_title)) - .setChallenge(challenge) + .setRequestGatekeeperPassword(true) .setUserId(mUserId) .setForegroundOnly(true) .setReturnCredentials(true) .show(); if (!launched) { + // TODO: This should be cleaned up. ChooseLockGeneric should provide a way of + // specifying arguments/requests, instead of relying on callers setting extras. intent.setClassName(SETTINGS_PACKAGE_NAME, ChooseLockGeneric.class.getName()); intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING); intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true); - intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true); intent.putExtra(Intent.EXTRA_USER_ID, mUserId); - intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge); + intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, true); intent.putExtra(Intent.EXTRA_USER_ID, mUserId); startActivityForResult(intent, CHOOSE_LOCK_GENERIC_REQUEST); } diff --git a/src/com/android/settings/deviceinfo/StorageWizardMigrateConfirm.java b/src/com/android/settings/deviceinfo/StorageWizardMigrateConfirm.java index ec771266959..7d20aa715db 100644 --- a/src/com/android/settings/deviceinfo/StorageWizardMigrateConfirm.java +++ b/src/com/android/settings/deviceinfo/StorageWizardMigrateConfirm.java @@ -109,7 +109,7 @@ public class StorageWizardMigrateConfirm extends StorageWizardBase { .setDescription(description) .setUserId(user.id) .setAllowAnyUserId(true) - .setChallenge(0L) + .setForceVerifyPath(true) .show(); return; } diff --git a/src/com/android/settings/deviceinfo/StorageWizardMoveConfirm.java b/src/com/android/settings/deviceinfo/StorageWizardMoveConfirm.java index ef406ff3703..034eb079fe2 100644 --- a/src/com/android/settings/deviceinfo/StorageWizardMoveConfirm.java +++ b/src/com/android/settings/deviceinfo/StorageWizardMoveConfirm.java @@ -90,7 +90,7 @@ public class StorageWizardMoveConfirm extends StorageWizardBase { builder.setRequestCode(REQUEST_CREDENTIAL) .setDescription(description) .setUserId(user.id) - .setChallenge(0L) + .setForceVerifyPath(true) .setAllowAnyUserId(true) .show(); return; diff --git a/src/com/android/settings/password/ChooseLockGeneric.java b/src/com/android/settings/password/ChooseLockGeneric.java index 4d51591b56c..297a3945539 100644 --- a/src/com/android/settings/password/ChooseLockGeneric.java +++ b/src/com/android/settings/password/ChooseLockGeneric.java @@ -144,8 +144,7 @@ public class ChooseLockGeneric extends SettingsActivity { private LockPatternUtils mLockPatternUtils; private DevicePolicyManager mDpm; - private boolean mHasChallenge = false; - private long mChallenge; + private boolean mRequestGatekeeperPassword = false; private boolean mPasswordConfirmed = false; private boolean mWaitingForConfirmation = false; private boolean mForChangeCredRequiredForBoot = false; @@ -211,10 +210,8 @@ public class ChooseLockGeneric extends SettingsActivity { ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); } - mHasChallenge = intent.getBooleanExtra( - ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false); - mChallenge = intent.getLongExtra( - ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0); + mRequestGatekeeperPassword = intent.getBooleanExtra( + ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, false); mForFingerprint = intent.getBooleanExtra( ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false); mForFace = intent.getBooleanExtra( @@ -386,9 +383,12 @@ public class ChooseLockGeneric extends SettingsActivity { mForFingerprint); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, mForFace); + // If the caller requested Gatekeeper Password to be returned, we assume it came + // from biometric enrollment. This should be cleaned up, since requesting + // Gatekeeper Password should not imply it came from biometric setup/settings. startActivityForResult( intent, - mIsSetNewPassword && mHasChallenge + mIsSetNewPassword && mRequestGatekeeperPassword ? CHOOSE_LOCK_BEFORE_BIOMETRIC_REQUEST : ENABLE_ENCRYPTION_REQUEST); } else { @@ -438,6 +438,10 @@ public class ChooseLockGeneric extends SettingsActivity { && resultCode == BiometricEnrollBase.RESULT_FINISHED) { Intent intent = getBiometricEnrollIntent(getActivity()); if (data != null) { + // ChooseLockGeneric should have requested that the Gatekeeper Password be + // returned, so that biometric enrollment(s) can subsequently request Gatekeeper + // to create HardwareAuthToken(s) wrapping biometric-specific challenges. Send + // the extras (including the GK Password) to the enrollment activity. intent.putExtras(data.getExtras()); } // Forward the target user id to fingerprint setup page. @@ -722,10 +726,8 @@ public class ChooseLockGeneric extends SettingsActivity { .setRequestedMinComplexity(mRequestedMinComplexity) .setForFingerprint(mForFingerprint) .setForFace(mForFace) - .setUserId(mUserId); - if (mHasChallenge) { - builder.setChallenge(mChallenge); - } + .setUserId(mUserId) + .setRequestGatekeeperPassword(mRequestGatekeeperPassword); if (mUserPassword != null) { builder.setPassword(mUserPassword); } @@ -740,10 +742,8 @@ public class ChooseLockGeneric extends SettingsActivity { new ChooseLockPattern.IntentBuilder(getContext()) .setForFingerprint(mForFingerprint) .setForFace(mForFace) - .setUserId(mUserId); - if (mHasChallenge) { - builder.setChallenge(mChallenge); - } + .setUserId(mUserId) + .setRequestGatekeeperPassword(mRequestGatekeeperPassword); if (mUserPassword != null) { builder.setPattern(mUserPassword); } @@ -784,8 +784,13 @@ public class ChooseLockGeneric extends SettingsActivity { intent.putExtra(EXTRA_SHOW_OPTIONS_BUTTON, chooseLockSkipped); } intent.putExtra(EXTRA_CHOOSE_LOCK_GENERIC_EXTRAS, getIntent().getExtras()); + // If the caller requested Gatekeeper Password to be returned, we assume it came + // from biometric enrollment. onActivityResult will put the LockSettingsService + // into the extras and launch biometric enrollment. This should be cleaned up, + // since requesting Gatekeeper Password should not imply it came from biometric + // setup/settings. startActivityForResult(intent, - mIsSetNewPassword && mHasChallenge + mIsSetNewPassword && mRequestGatekeeperPassword ? CHOOSE_LOCK_BEFORE_BIOMETRIC_REQUEST : CHOOSE_LOCK_REQUEST); return; diff --git a/src/com/android/settings/password/ChooseLockPassword.java b/src/com/android/settings/password/ChooseLockPassword.java index a2ac3d5d130..9e4c5974f9c 100644 --- a/src/com/android/settings/password/ChooseLockPassword.java +++ b/src/com/android/settings/password/ChooseLockPassword.java @@ -77,6 +77,7 @@ import com.android.internal.widget.LockPatternUtils.RequestThrottledException; import com.android.internal.widget.LockscreenCredential; import com.android.internal.widget.PasswordValidationError; import com.android.internal.widget.TextViewInputDisabler; +import com.android.internal.widget.VerifyCredentialResponse; import com.android.settings.EncryptionInterstitial; import com.android.settings.R; import com.android.settings.SettingsActivity; @@ -117,7 +118,6 @@ public class ChooseLockPassword extends SettingsActivity { mIntent = new Intent(context, ChooseLockPassword.class); mIntent.putExtra(ChooseLockGeneric.CONFIRM_CREDENTIALS, false); mIntent.putExtra(EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, false); - mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false); } public IntentBuilder setPasswordQuality(int quality) { @@ -130,9 +130,9 @@ public class ChooseLockPassword extends SettingsActivity { return this; } - public IntentBuilder setChallenge(long challenge) { - mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true); - mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge); + public IntentBuilder setRequestGatekeeperPassword(boolean requestGatekeeperPassword) { + mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, + requestGatekeeperPassword); return this; } @@ -211,8 +211,7 @@ public class ChooseLockPassword extends SettingsActivity { private LockscreenCredential mCurrentCredential; private LockscreenCredential mChosenPassword; - private boolean mHasChallenge; - private long mChallenge; + private boolean mRequestGatekeeperPassword; private ImeAwareEditText mPasswordEntry; private TextViewInputDisabler mPasswordEntryInputDisabler; @@ -407,7 +406,8 @@ public class ChooseLockPassword extends SettingsActivity { w.setBlocking(true); w.setListener(this); - w.start(utils, required, false, 0, currentCredential, currentCredential, mUserId); + w.start(utils, required, false /* requestGatekeeperPassword */, currentCredential, + currentCredential, mUserId); } mTextChangedHandler = new TextChangedHandler(); } @@ -491,9 +491,8 @@ public class ChooseLockPassword extends SettingsActivity { ChooseLockGeneric.CONFIRM_CREDENTIALS, true); mCurrentCredential = intent.getParcelableExtra( ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); - mHasChallenge = intent.getBooleanExtra( - ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false); - mChallenge = intent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0); + mRequestGatekeeperPassword = intent.getBooleanExtra( + ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, false); if (savedInstanceState == null) { updateStage(Stage.Introduction); if (confirmCredentials) { @@ -502,6 +501,7 @@ public class ChooseLockPassword extends SettingsActivity { builder.setRequestCode(CONFIRM_EXISTING_REQUEST) .setTitle(getString(R.string.unlock_set_unlock_launch_picker_title)) .setReturnCredentials(true) + .setRequestGatekeeperPassword(mRequestGatekeeperPassword) .setUserId(mUserId) .show(); } @@ -885,7 +885,7 @@ public class ChooseLockPassword extends SettingsActivity { profileCredential); } } - mSaveAndFinishWorker.start(mLockPatternUtils, required, mHasChallenge, mChallenge, + mSaveAndFinishWorker.start(mLockPatternUtils, required, mRequestGatekeeperPassword, mChosenPassword, mCurrentCredential, mUserId); } @@ -945,10 +945,9 @@ public class ChooseLockPassword extends SettingsActivity { private LockscreenCredential mCurrentCredential; public void start(LockPatternUtils utils, boolean required, - boolean hasChallenge, long challenge, - LockscreenCredential chosenPassword, LockscreenCredential currentCredential, - int userId) { - prepare(utils, required, hasChallenge, challenge, userId); + boolean requestGatekeeperPassword, LockscreenCredential chosenPassword, + LockscreenCredential currentCredential, int userId) { + prepare(utils, required, requestGatekeeperPassword, userId); mChosenPassword = chosenPassword; mCurrentCredential = currentCredential != null ? currentCredential @@ -966,20 +965,21 @@ public class ChooseLockPassword extends SettingsActivity { unifyProfileCredentialIfRequested(); } Intent result = null; - if (success && mHasChallenge) { - byte[] token; - try { - token = mUtils.verifyCredential(mChosenPassword, mChallenge, mUserId); - } catch (RequestThrottledException e) { - token = null; - } + if (success && mRequestGatekeeperPassword) { + // If a Gatekeeper Password was requested, invoke the LockSettingsService code + // path to return a Gatekeeper Password based on the credential that the user + // chose. This should only be run if the credential was successfully set. + final VerifyCredentialResponse response = mUtils.verifyCredential(mChosenPassword, + mUserId, LockPatternUtils.VERIFY_FLAG_RETURN_GK_PW); - if (token == null) { - Log.e(TAG, "critical: no token returned for known good password."); + if (!response.isMatched() || response.getGatekeeperPw() == null) { + Log.e(TAG, "critical: bad response or missing GK PW for known good password: " + + response.toString()); } result = new Intent(); - result.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token); + result.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW, + response.getGatekeeperPw()); } return Pair.create(success, result); } diff --git a/src/com/android/settings/password/ChooseLockPattern.java b/src/com/android/settings/password/ChooseLockPattern.java index 2c2d7bbe11a..bac7450870b 100644 --- a/src/com/android/settings/password/ChooseLockPattern.java +++ b/src/com/android/settings/password/ChooseLockPattern.java @@ -42,11 +42,11 @@ 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.internal.widget.VerifyCredentialResponse; import com.android.settings.EncryptionInterstitial; import com.android.settings.R; import com.android.settings.SettingsActivity; @@ -54,7 +54,6 @@ import com.android.settings.SetupWizardUtils; import com.android.settings.Utils; import com.android.settings.core.InstrumentedFragment; import com.android.settings.notification.RedactionInterstitial; -import com.android.settings.password.ChooseLockPassword.IntentBuilder; import com.google.android.collect.Lists; import com.google.android.setupcompat.template.FooterBarMixin; @@ -106,7 +105,6 @@ public class ChooseLockPattern extends SettingsActivity { mIntent = new Intent(context, ChooseLockPattern.class); mIntent.putExtra(EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, false); mIntent.putExtra(ChooseLockGeneric.CONFIRM_CREDENTIALS, false); - mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false); } public IntentBuilder setUserId(int userId) { @@ -114,9 +112,9 @@ public class ChooseLockPattern extends SettingsActivity { return this; } - public IntentBuilder setChallenge(long challenge) { - mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true); - mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge); + public IntentBuilder setRequestGatekeeperPassword(boolean requestGatekeeperPassword) { + mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, + requestGatekeeperPassword); return this; } @@ -206,8 +204,7 @@ public class ChooseLockPattern extends SettingsActivity { private static final String FRAGMENT_TAG_SAVE_AND_FINISH = "save_and_finish_worker"; private LockscreenCredential mCurrentCredential; - private boolean mHasChallenge; - private long mChallenge; + private boolean mRequestGatekeeperPassword; protected TextView mTitleText; protected TextView mHeaderText; protected TextView mMessageText; @@ -483,7 +480,8 @@ public class ChooseLockPattern extends SettingsActivity { ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); w.setBlocking(true); w.setListener(this); - w.start(mLockPatternUtils, required, false, 0, current, current, mUserId); + w.start(mLockPatternUtils, required, false /* requestGatekeeperPassword */, current, + current, mUserId); } mForFingerprint = intent.getBooleanExtra( ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false); @@ -563,9 +561,8 @@ public class ChooseLockPattern extends SettingsActivity { Intent intent = getActivity().getIntent(); mCurrentCredential = intent.getParcelableExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); - mHasChallenge = intent.getBooleanExtra( - ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false); - mChallenge = intent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0); + mRequestGatekeeperPassword = intent.getBooleanExtra( + ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, false); if (savedInstanceState == null) { if (confirmCredentials) { @@ -578,6 +575,7 @@ public class ChooseLockPattern extends SettingsActivity { final boolean launched = builder.setRequestCode(CONFIRM_EXISTING_REQUEST) .setTitle(getString(R.string.unlock_set_unlock_launch_picker_title)) .setReturnCredentials(true) + .setRequestGatekeeperPassword(mRequestGatekeeperPassword) .setUserId(mUserId) .show(); @@ -858,7 +856,7 @@ public class ChooseLockPattern extends SettingsActivity { } } mSaveAndFinishWorker.start(mLockPatternUtils, required, - mHasChallenge, mChallenge, mChosenPattern, mCurrentCredential, mUserId); + mRequestGatekeeperPassword, mChosenPattern, mCurrentCredential, mUserId); } @Override @@ -888,10 +886,10 @@ public class ChooseLockPattern extends SettingsActivity { private LockscreenCredential mCurrentCredential; private boolean mLockVirgin; - public void start(LockPatternUtils utils, boolean credentialRequired, boolean hasChallenge, - long challenge, LockscreenCredential chosenPattern, + public void start(LockPatternUtils utils, boolean credentialRequired, + boolean requestGatekeeperPassword, LockscreenCredential chosenPattern, LockscreenCredential currentCredential, int userId) { - prepare(utils, credentialRequired, hasChallenge, challenge, userId); + prepare(utils, credentialRequired, requestGatekeeperPassword, userId); mCurrentCredential = currentCredential != null ? currentCredential : LockscreenCredential.createNone(); @@ -912,20 +910,21 @@ public class ChooseLockPattern extends SettingsActivity { unifyProfileCredentialIfRequested(); } Intent result = null; - if (success && mHasChallenge) { - byte[] token; - try { - token = mUtils.verifyCredential(mChosenPattern, mChallenge, userId); - } catch (RequestThrottledException e) { - token = null; - } + if (success && mRequestGatekeeperPassword) { + // If a Gatekeeper Password was requested, invoke the LockSettingsService code + // path to return a Gatekeeper Password based on the credential that the user + // chose. This should only be run if the credential was successfully set. + final VerifyCredentialResponse response = mUtils.verifyCredential(mChosenPattern, + userId, LockPatternUtils.VERIFY_FLAG_RETURN_GK_PW); - if (token == null) { - Log.e(TAG, "critical: no token returned for known good pattern"); + if (!response.isMatched() || response.getGatekeeperPw() == null) { + Log.e(TAG, "critical: bad response or missing GK HAT for known good pattern: " + + response.toString()); } result = new Intent(); - result.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token); + result.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW, + response.getGatekeeperPw()); } return Pair.create(success, result); } diff --git a/src/com/android/settings/password/ChooseLockSettingsHelper.java b/src/com/android/settings/password/ChooseLockSettingsHelper.java index 962294b100c..cd705c4615b 100644 --- a/src/com/android/settings/password/ChooseLockSettingsHelper.java +++ b/src/com/android/settings/password/ChooseLockSettingsHelper.java @@ -31,7 +31,9 @@ import android.util.Log; import androidx.annotation.VisibleForTesting; import androidx.fragment.app.Fragment; +import com.android.internal.widget.ICheckCredentialProgressCallback; import com.android.internal.widget.LockPatternUtils; +import com.android.internal.widget.LockscreenCredential; import com.android.settings.SetupWizardUtils; import com.android.settings.Utils; import com.android.settings.core.SubSettingLauncher; @@ -45,13 +47,19 @@ public final class ChooseLockSettingsHelper { public static final String EXTRA_KEY_TYPE = "type"; public static final String EXTRA_KEY_PASSWORD = "password"; public static final String EXTRA_KEY_RETURN_CREDENTIALS = "return_credentials"; - public static final String EXTRA_KEY_HAS_CHALLENGE = "has_challenge"; - public static final String EXTRA_KEY_CHALLENGE = "challenge"; + // Force the verifyCredential path instead of checkCredential path. This will be removed + // after b/161956762 is resolved. + public static final String EXTRA_KEY_FORCE_VERIFY = "force_verify"; + // Gatekeeper HardwareAuthToken public static final String EXTRA_KEY_CHALLENGE_TOKEN = "hw_auth_token"; public static final String EXTRA_KEY_FOR_FINGERPRINT = "for_fingerprint"; public static final String EXTRA_KEY_FOR_FACE = "for_face"; public static final String EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT = "for_cred_req_boot"; public static final String EXTRA_KEY_FOREGROUND_ONLY = "foreground_only"; + public static final String EXTRA_KEY_REQUEST_GK_PW = "request_gk_pw"; + // Gatekeeper password, which can subsequently be used to generate Gatekeeper + // HardwareAuthToken(s) via LockSettingsService#verifyGatekeeperPassword + public static final String EXTRA_KEY_GK_PW = "gk_pw"; /** * When EXTRA_KEY_UNIFICATION_PROFILE_CREDENTIAL and EXTRA_KEY_UNIFICATION_PROFILE_ID are @@ -117,8 +125,8 @@ public final class ChooseLockSettingsHelper { // ChooseLockSettingsHelper will determine the caller's userId if none provided. private int mUserId; private boolean mAllowAnyUserId; - // The challenge can be 0, which is different than "no challenge" - @Nullable Long mChallenge; + private boolean mForceVerifyPath; + boolean mRequestGatekeeperPassword; public Builder(@NonNull Activity activity) { mActivity = activity; @@ -174,8 +182,12 @@ public final class ChooseLockSettingsHelper { * @param returnCredentials if true, puts the following credentials into intent for * onActivityResult with the following keys: * {@link #EXTRA_KEY_TYPE}, {@link #EXTRA_KEY_PASSWORD}, - * {@link #EXTRA_KEY_CHALLENGE_TOKEN}. + * {@link #EXTRA_KEY_CHALLENGE_TOKEN}, {@link #EXTRA_KEY_GK_PW} * Note that if this is true, this can only be called internally. + * + * This should also generally be set if + * {@link #setRequestGatekeeperPassword(boolean)} (boolean)} is + * set. */ @NonNull public Builder setReturnCredentials(boolean returnCredentials) { mReturnCredentials = returnCredentials; @@ -220,14 +232,26 @@ public final class ChooseLockSettingsHelper { } /** - * @param challenge an opaque payload that will be wrapped in the Gatekeeper's payload - * if authentication is successful. Common use case is for the caller's - * secure layer (e.g. Trusted Execution Environment) to 1) verify that - * the Gatekeeper HAT's HMAC is valid, and 2) if so, perform an operation - * based on the challenge. + * @param forceVerifyPath Forces the VerifyCredential path instead of the CheckCredential + * path. This will be removed after b/161956762 is resolved. */ - @NonNull public Builder setChallenge(long challenge) { - mChallenge = challenge; + @NonNull public Builder setForceVerifyPath(boolean forceVerifyPath) { + mForceVerifyPath = forceVerifyPath; + return this; + } + + /** + * Requests that LockSettingsService return the Gatekeeper Password (instead of the + * Gatekeeper HAT). This allows us to use a single entry of the user's credential + * to create multiple Gatekeeper HATs containing distinct challenges via + * {@link LockPatternUtils#verifyGatekeeperPassword(byte[], long, int)}. + * + * Upon confirmation of the user's password, the Gatekeeper Password will be returned via + * onActivityResult with the key being {@link #EXTRA_KEY_GK_PW}. + * @param requestGatekeeperPassword + */ + @NonNull public Builder setRequestGatekeeperPassword(boolean requestGatekeeperPassword) { + mRequestGatekeeperPassword = requestGatekeeperPassword; return this; } @@ -242,10 +266,10 @@ public final class ChooseLockSettingsHelper { + " onActivityResult"); } - if (mChallenge != null && !mReturnCredentials) { + if (mRequestGatekeeperPassword && !mReturnCredentials) { // HAT containing the signed challenge will not be available to the caller. - Log.w(TAG, "Challenge set but not requesting ReturnCredentials. Are you sure this" - + " is what you want?"); + Log.w(TAG, "Requested gatekeeper password but not requesting ReturnCredentials. Are" + + " you sure this is what you want?"); } return new ChooseLockSettingsHelper(this, mActivity, mFragment); @@ -261,29 +285,29 @@ public final class ChooseLockSettingsHelper { * @return true if the confirmation activity is shown (e.g. user has a credential set up) */ public boolean launch() { - final long challenge = mBuilder.mChallenge != null ? mBuilder.mChallenge : 0L; return launchConfirmationActivity(mBuilder.mRequestCode, mBuilder.mTitle, mBuilder.mHeader, mBuilder.mDescription, mBuilder.mReturnCredentials, mBuilder.mExternal, - mBuilder.mChallenge != null, challenge, mBuilder.mUserId, - mBuilder.mAlternateButton, mBuilder.mAllowAnyUserId, mBuilder.mForegroundOnly); + mBuilder.mForceVerifyPath, mBuilder.mUserId, mBuilder.mAlternateButton, + mBuilder.mAllowAnyUserId, mBuilder.mForegroundOnly, + mBuilder.mRequestGatekeeperPassword); } private boolean launchConfirmationActivity(int request, @Nullable CharSequence title, @Nullable CharSequence header, @Nullable CharSequence description, - boolean returnCredentials, boolean external, boolean hasChallenge, - long challenge, int userId, @Nullable CharSequence alternateButton, - boolean allowAnyUser, boolean foregroundOnly) { + boolean returnCredentials, boolean external, boolean forceVerifyPath, + int userId, @Nullable CharSequence alternateButton, boolean allowAnyUser, + boolean foregroundOnly, boolean requestGatekeeperPassword) { final int effectiveUserId = UserManager.get(mActivity).getCredentialOwnerProfile(userId); boolean launched = false; switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(effectiveUserId)) { case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: launched = launchConfirmationActivity(request, title, header, description, - returnCredentials || hasChallenge + returnCredentials ? ConfirmLockPattern.InternalActivity.class : ConfirmLockPattern.class, returnCredentials, external, - hasChallenge, challenge, userId, alternateButton, allowAnyUser, - foregroundOnly); + forceVerifyPath, userId, alternateButton, allowAnyUser, + foregroundOnly, requestGatekeeperPassword); break; case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC: case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX: @@ -292,11 +316,11 @@ public final class ChooseLockSettingsHelper { case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX: case DevicePolicyManager.PASSWORD_QUALITY_MANAGED: launched = launchConfirmationActivity(request, title, header, description, - returnCredentials || hasChallenge + returnCredentials ? ConfirmLockPassword.InternalActivity.class : ConfirmLockPassword.class, returnCredentials, external, - hasChallenge, challenge, userId, alternateButton, allowAnyUser, - foregroundOnly); + forceVerifyPath, userId, alternateButton, allowAnyUser, + foregroundOnly, requestGatekeeperPassword); break; } return launched; @@ -304,9 +328,9 @@ public final class ChooseLockSettingsHelper { private boolean launchConfirmationActivity(int request, CharSequence title, CharSequence header, CharSequence message, Class activityClass, boolean returnCredentials, - boolean external, boolean hasChallenge, long challenge, - int userId, @Nullable CharSequence alternateButton, boolean allowAnyUser, - boolean foregroundOnly) { + boolean external, boolean forceVerifyPath, int userId, + @Nullable CharSequence alternateButton, boolean allowAnyUser, + boolean foregroundOnly, boolean requestGatekeeperPassword) { final Intent intent = new Intent(); intent.putExtra(ConfirmDeviceCredentialBaseFragment.TITLE_TEXT, title); intent.putExtra(ConfirmDeviceCredentialBaseFragment.HEADER_TEXT, header); @@ -317,12 +341,13 @@ public final class ChooseLockSettingsHelper { intent.putExtra(ConfirmDeviceCredentialBaseFragment.SHOW_WHEN_LOCKED, external); intent.putExtra(ConfirmDeviceCredentialBaseFragment.USE_FADE_ANIMATION, external); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_RETURN_CREDENTIALS, returnCredentials); - intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, hasChallenge); - intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge); + intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FORCE_VERIFY, forceVerifyPath); intent.putExtra(Intent.EXTRA_USER_ID, userId); intent.putExtra(KeyguardManager.EXTRA_ALTERNATE_BUTTON_LABEL, alternateButton); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOREGROUND_ONLY, foregroundOnly); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_ALLOW_ANY_USER, allowAnyUser); + intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, + requestGatekeeperPassword); intent.setClassName(SETTINGS_PACKAGE_NAME, activityClass.getName()); if (external) { diff --git a/src/com/android/settings/password/ChooseLockTypeDialogFragment.java b/src/com/android/settings/password/ChooseLockTypeDialogFragment.java index 8793471e206..d31524bf4dc 100644 --- a/src/com/android/settings/password/ChooseLockTypeDialogFragment.java +++ b/src/com/android/settings/password/ChooseLockTypeDialogFragment.java @@ -74,7 +74,7 @@ public class ChooseLockTypeDialogFragment extends InstrumentedDialogFragment // Copy the original extras into the new intent copyBooleanExtra(activityIntent, intent, - ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false); + ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, false); copyBooleanExtra(activityIntent, intent, ChooseLockGenericFragment.EXTRA_SHOW_OPTIONS_BUTTON, false); if (activityIntent.hasExtra( @@ -83,8 +83,6 @@ public class ChooseLockTypeDialogFragment extends InstrumentedDialogFragment ChooseLockGenericFragment.EXTRA_CHOOSE_LOCK_GENERIC_EXTRAS)); } intent.putExtra(LockPatternUtils.PASSWORD_TYPE_KEY, selectedLockType.defaultQuality); - intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, - activityIntent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0)); WizardManagerHelper.copyWizardManagerExtras(activityIntent, intent); activity.startActivity(intent); activity.finish(); diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java index 9a2f525eb0b..6a97dcd1b45 100644 --- a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java +++ b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java @@ -27,7 +27,6 @@ import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.hardware.biometrics.BiometricConstants; -import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricPrompt; import android.hardware.biometrics.BiometricPrompt.AuthenticationCallback; import android.hardware.biometrics.PromptInfo; @@ -81,18 +80,6 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity { return intent; } - public static Intent createIntent(CharSequence title, CharSequence details, long challenge) { - Intent intent = new Intent(); - intent.setClassName(SETTINGS_PACKAGE_NAME, - ConfirmDeviceCredentialActivity.class.getName()); - intent.putExtra(KeyguardManager.EXTRA_TITLE, title); - intent.putExtra(KeyguardManager.EXTRA_DESCRIPTION, details); - intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge); - intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true); - return intent; - } - - private BiometricManager mBiometricManager; private BiometricFragment mBiometricFragment; private DevicePolicyManager mDevicePolicyManager; private LockPatternUtils mLockPatternUtils; @@ -181,7 +168,6 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity { getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); getWindow().setStatusBarColor(Color.TRANSPARENT); - mBiometricManager = getSystemService(BiometricManager.class); mDevicePolicyManager = getSystemService(DevicePolicyManager.class); mUserManager = UserManager.get(this); mTrustManager = getSystemService(TrustManager.class); @@ -394,7 +380,7 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity { .setDescription(mDetails) .setExternal(true) .setUserId(mUserId) - .setChallenge(0L) + .setForceVerifyPath(true) .show(); } else if (mCredentialMode == CREDENTIAL_NORMAL) { final ChooseLockSettingsHelper.Builder builder = diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java b/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java index b5f512dfa99..ea4c992a5ac 100644 --- a/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java +++ b/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java @@ -71,6 +71,8 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr protected static final long CLEAR_WRONG_ATTEMPT_TIMEOUT_MS = 3000; protected boolean mReturnCredentials = false; + protected boolean mReturnGatekeeperPassword = false; + protected boolean mForceVerifyPath = false; protected Button mCancelButton; /** Button allowing managed profile password reset, null when is not shown. */ @Nullable protected Button mForgotButton; @@ -93,12 +95,18 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - mFrpAlternateButtonText = getActivity().getIntent().getCharSequenceExtra( + final Intent intent = getActivity().getIntent(); + mFrpAlternateButtonText = intent.getCharSequenceExtra( KeyguardManager.EXTRA_ALTERNATE_BUTTON_LABEL); - mReturnCredentials = getActivity().getIntent().getBooleanExtra( + mReturnCredentials = intent.getBooleanExtra( ChooseLockSettingsHelper.EXTRA_KEY_RETURN_CREDENTIALS, false); + + mReturnGatekeeperPassword = intent.getBooleanExtra( + ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, false); + mForceVerifyPath = intent.getBooleanExtra( + ChooseLockSettingsHelper.EXTRA_KEY_FORCE_VERIFY, false); + // Only take this argument into account if it belongs to the current profile. - Intent intent = getActivity().getIntent(); mUserId = Utils.getUserIdFromBundle(getActivity(), intent.getExtras(), isInternalActivity()); mFrp = (mUserId == LockPatternUtils.USER_FRP); diff --git a/src/com/android/settings/password/ConfirmLockPassword.java b/src/com/android/settings/password/ConfirmLockPassword.java index 8aa44e9780f..c90103210a9 100644 --- a/src/com/android/settings/password/ConfirmLockPassword.java +++ b/src/com/android/settings/password/ConfirmLockPassword.java @@ -380,13 +380,18 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity { : LockscreenCredential.createPin(passwordText); mPasswordEntryInputDisabler.setInputEnabled(false); - final boolean verifyChallenge = getActivity().getIntent().getBooleanExtra( - ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false); Intent intent = new Intent(); - if (verifyChallenge) { + // TODO(b/161956762): Sanitize this + if (mReturnGatekeeperPassword) { if (isInternalActivity()) { - startVerifyPassword(credential, intent); + startVerifyPassword(credential, intent, + LockPatternUtils.VERIFY_FLAG_RETURN_GK_PW); + return; + } + } else if (mForceVerifyPath) { + if (isInternalActivity()) { + startVerifyPassword(credential, intent, 0 /* flags */); return; } } else { @@ -401,35 +406,31 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity { return getActivity() instanceof ConfirmLockPassword.InternalActivity; } - private void startVerifyPassword(LockscreenCredential credential, final Intent intent) { - long challenge = getActivity().getIntent().getLongExtra( - ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0); + private void startVerifyPassword(LockscreenCredential credential, final Intent intent, + @LockPatternUtils.VerifyFlag int flags) { final int localEffectiveUserId = mEffectiveUserId; final int localUserId = mUserId; - final LockPatternChecker.OnVerifyCallback onVerifyCallback = - new LockPatternChecker.OnVerifyCallback() { - @Override - public void onVerified(byte[] token, int timeoutMs) { - mPendingLockCheck = null; - boolean matched = false; - if (token != null) { - matched = true; - if (mReturnCredentials) { - intent.putExtra( - ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, - token); - } - } - mCredentialCheckResultTracker.setResult(matched, intent, timeoutMs, - localEffectiveUserId); - } + final LockPatternChecker.OnVerifyCallback onVerifyCallback = (response, timeoutMs) -> { + mPendingLockCheck = null; + final boolean matched = response.isMatched(); + if (matched && mReturnCredentials) { + if ((flags & LockPatternUtils.VERIFY_FLAG_RETURN_GK_PW) != 0) { + intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW, + response.getGatekeeperPw()); + } else { + intent.putExtra( + ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, + response.getGatekeeperHAT()); + } + } + mCredentialCheckResultTracker.setResult(matched, intent, timeoutMs, + localEffectiveUserId); }; mPendingLockCheck = (localEffectiveUserId == localUserId) - ? LockPatternChecker.verifyCredential( - mLockPatternUtils, credential, challenge, localUserId, onVerifyCallback) - : LockPatternChecker.verifyTiedProfileChallenge( - mLockPatternUtils, credential, challenge, localUserId, - onVerifyCallback); + ? LockPatternChecker.verifyCredential(mLockPatternUtils, credential, + localUserId, flags, onVerifyCallback) + : LockPatternChecker.verifyTiedProfileChallenge(mLockPatternUtils, credential, + localUserId, flags, onVerifyCallback); } private void startCheckPassword(final LockscreenCredential credential, diff --git a/src/com/android/settings/password/ConfirmLockPattern.java b/src/com/android/settings/password/ConfirmLockPattern.java index 48014cba3c8..a8099526acd 100644 --- a/src/com/android/settings/password/ConfirmLockPattern.java +++ b/src/com/android/settings/password/ConfirmLockPattern.java @@ -422,14 +422,18 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity { mLockPatternView.setEnabled(false); - final boolean verifyChallenge = getActivity().getIntent().getBooleanExtra( - ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false); final LockscreenCredential credential = LockscreenCredential.createPattern(pattern); - //TODO: how to sanitize this? + // TODO(b/161956762): Sanitize this Intent intent = new Intent(); - if (verifyChallenge) { + if (mReturnGatekeeperPassword) { if (isInternalActivity()) { - startVerifyPattern(credential, intent); + startVerifyPattern(credential, intent, + LockPatternUtils.VERIFY_FLAG_RETURN_GK_PW); + return; + } + } else if (mForceVerifyPath) { + if (isInternalActivity()) { + startVerifyPattern(credential, intent, 0 /* flags */); return; } } else { @@ -445,36 +449,33 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity { } private void startVerifyPattern(final LockscreenCredential pattern, - final Intent intent) { + final Intent intent, @LockPatternUtils.VerifyFlag int flags) { final int localEffectiveUserId = mEffectiveUserId; final int localUserId = mUserId; - long challenge = getActivity().getIntent().getLongExtra( - ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0); final LockPatternChecker.OnVerifyCallback onVerifyCallback = - new LockPatternChecker.OnVerifyCallback() { - @Override - public void onVerified(byte[] token, int timeoutMs) { - mPendingLockCheck = null; - boolean matched = false; - if (token != null) { - matched = true; - if (mReturnCredentials) { - intent.putExtra( - ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, - token); - } + (response, timeoutMs) -> { + mPendingLockCheck = null; + final boolean matched = response.isMatched(); + if (matched && mReturnCredentials) { + if ((flags & LockPatternUtils.VERIFY_FLAG_RETURN_GK_PW) != 0) { + intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW, + response.getGatekeeperPw()); + } else { + intent.putExtra( + ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, + response.getGatekeeperHAT()); } - mCredentialCheckResultTracker.setResult(matched, intent, timeoutMs, - localEffectiveUserId); } - }; + mCredentialCheckResultTracker.setResult(matched, intent, timeoutMs, + localEffectiveUserId); + }; mPendingLockCheck = (localEffectiveUserId == localUserId) ? LockPatternChecker.verifyCredential( - mLockPatternUtils, pattern, challenge, localUserId, + mLockPatternUtils, pattern, localUserId, flags, onVerifyCallback) : LockPatternChecker.verifyTiedProfileChallenge( - mLockPatternUtils, pattern, - challenge, localUserId, onVerifyCallback); + mLockPatternUtils, pattern, localUserId, flags, + onVerifyCallback); } private void startCheckPattern(final LockscreenCredential pattern, diff --git a/src/com/android/settings/password/SaveChosenLockWorkerBase.java b/src/com/android/settings/password/SaveChosenLockWorkerBase.java index 26e4d5aa8ad..cea908b4a77 100644 --- a/src/com/android/settings/password/SaveChosenLockWorkerBase.java +++ b/src/com/android/settings/password/SaveChosenLockWorkerBase.java @@ -42,8 +42,7 @@ abstract class SaveChosenLockWorkerBase extends Fragment { private Intent mResultData; protected LockPatternUtils mUtils; - protected boolean mHasChallenge; - protected long mChallenge; + protected boolean mRequestGatekeeperPassword; protected boolean mWasSecureBefore; protected int mUserId; protected int mUnificationProfileId = UserHandle.USER_NULL; @@ -69,12 +68,10 @@ abstract class SaveChosenLockWorkerBase extends Fragment { } protected void prepare(LockPatternUtils utils, boolean credentialRequired, - boolean hasChallenge, long challenge, int userId) { + boolean requestGatekeeperPassword, int userId) { mUtils = utils; mUserId = userId; - - mHasChallenge = hasChallenge; - mChallenge = challenge; + mRequestGatekeeperPassword = requestGatekeeperPassword; // This will be a no-op for non managed profiles. mWasSecureBefore = mUtils.isSecure(mUserId); diff --git a/src/com/android/settings/password/SetNewPasswordController.java b/src/com/android/settings/password/SetNewPasswordController.java index 7f206a0b781..02d86b2239e 100644 --- a/src/com/android/settings/password/SetNewPasswordController.java +++ b/src/com/android/settings/password/SetNewPasswordController.java @@ -135,26 +135,22 @@ final class SetNewPasswordController { private Bundle getFingerprintChooseLockExtras() { Bundle chooseLockExtras = new Bundle(); - long challenge = mFingerprintManager.generateChallengeBlocking(); chooseLockExtras.putInt(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY, PASSWORD_QUALITY_SOMETHING); chooseLockExtras.putBoolean( ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true); - chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true); - chooseLockExtras.putLong(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge); + chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, true); chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true); return chooseLockExtras; } private Bundle getFaceChooseLockExtras() { Bundle chooseLockExtras = new Bundle(); - long challenge = mFaceManager.generateChallengeBlocking(); chooseLockExtras.putInt(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY, PASSWORD_QUALITY_SOMETHING); chooseLockExtras.putBoolean( ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true); - chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true); - chooseLockExtras.putLong(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge); + chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, true); chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, true); return chooseLockExtras; } diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java index 5ec6f41abbf..abeb667a964 100644 --- a/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java +++ b/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java @@ -92,8 +92,8 @@ public class ChooseLockPasswordTest { .setUserId(123) .build(); - assertThat(intent.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true)) - .named("EXTRA_KEY_HAS_CHALLENGE") + assertThat(intent.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_FORCE_VERIFY, false)) + .named("EXTRA_KEY_FORCE_VERIFY") .isFalse(); assertThat((LockscreenCredential) intent.getParcelableExtra( ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD)) @@ -108,19 +108,16 @@ public class ChooseLockPasswordTest { } @Test - public void intentBuilder_setChallenge_shouldAddExtras() { + public void intentBuilder_setRequestGatekeeperPassword_shouldAddExtras() { Intent intent = new IntentBuilder(application) - .setChallenge(12345L) + .setRequestGatekeeperPassword(true) .setPasswordQuality(PASSWORD_QUALITY_ALPHANUMERIC) .setUserId(123) .build(); - assertThat(intent.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false)) - .named("EXTRA_KEY_HAS_CHALLENGE") + assertThat(intent.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, false)) + .named("EXTRA_KEY_REQUEST_GK_PW") .isTrue(); - assertThat(intent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0L)) - .named("EXTRA_KEY_CHALLENGE") - .isEqualTo(12345L); assertThat(intent.getIntExtra(PASSWORD_TYPE_KEY, 0)) .named("PASSWORD_TYPE_KEY") .isEqualTo(PASSWORD_QUALITY_ALPHANUMERIC); diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java index 3f3dcd6d78c..f5f0e37da26 100644 --- a/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java +++ b/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java @@ -59,8 +59,8 @@ public class ChooseLockPatternTest { .build(); assertThat(intent - .getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true)) - .named("EXTRA_KEY_HAS_CHALLENGE") + .getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_FORCE_VERIFY, false)) + .named("EXTRA_KEY_FORCE_VERIFY") .isFalse(); assertThat((LockscreenCredential) intent .getParcelableExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD)) @@ -72,20 +72,16 @@ public class ChooseLockPatternTest { } @Test - public void intentBuilder_setChallenge_shouldAddExtras() { + public void intentBuilder_setRequestGatekeeperPassword_shouldAddExtras() { Intent intent = new IntentBuilder(application) - .setChallenge(12345L) + .setRequestGatekeeperPassword(true) .setUserId(123) .build(); assertThat(intent - .getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false)) - .named("EXTRA_KEY_HAS_CHALLENGE") + .getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, false)) + .named("EXTRA_KEY_REQUEST_GK_PW") .isTrue(); - assertThat(intent - .getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0L)) - .named("EXTRA_KEY_CHALLENGE") - .isEqualTo(12345L); assertThat(intent .getIntExtra(Intent.EXTRA_USER_ID, 0)) .named("EXTRA_USER_ID") diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockSettingsHelperTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockSettingsHelperTest.java index 978e4cd9433..d082bded9ab 100644 --- a/tests/robotests/src/com/android/settings/password/ChooseLockSettingsHelperTest.java +++ b/tests/robotests/src/com/android/settings/password/ChooseLockSettingsHelperTest.java @@ -36,7 +36,7 @@ import org.robolectric.shadows.ShadowActivity.IntentForResult; public class ChooseLockSettingsHelperTest { @Test - public void testLaunchConfirmationActivityWithExternalAndChallenge() { + public void testLaunchConfirmationActivityWithExternal() { final Activity activity = Robolectric.setupActivity(Activity.class); ChooseLockSettingsHelper.Builder builder = new ChooseLockSettingsHelper.Builder(activity); @@ -45,7 +45,6 @@ public class ChooseLockSettingsHelperTest { .setHeader("header") .setDescription("description") .setExternal(true) - .setChallenge(10000L) .setUserId(UserHandle.myUserId()); ChooseLockSettingsHelper helper = getChooseLockSettingsHelper(builder); helper.launch(); @@ -53,15 +52,10 @@ public class ChooseLockSettingsHelperTest { ShadowActivity shadowActivity = Shadows.shadowOf(activity); Intent startedIntent = shadowActivity.getNextStartedActivity(); - assertEquals(new ComponentName("com.android.settings", - ConfirmLockPattern.InternalActivity.class.getName()), + assertEquals(new ComponentName("com.android.settings", ConfirmLockPattern.class.getName()), startedIntent.getComponent()); assertFalse(startedIntent.getBooleanExtra( ChooseLockSettingsHelper.EXTRA_KEY_RETURN_CREDENTIALS, false)); - assertTrue(startedIntent.getBooleanExtra( - ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false)); - assertEquals(10000L, startedIntent.getLongExtra( - ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0L)); assertTrue((startedIntent.getFlags() & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0); assertFalse(startedIntent.getBooleanExtra( ConfirmDeviceCredentialBaseFragment.DARK_THEME, false)); @@ -72,7 +66,7 @@ public class ChooseLockSettingsHelperTest { } @Test - public void testLaunchConfirmationActivityInternalAndChallenge() { + public void testLaunchConfirmationActivityInternal() { final Activity activity = Robolectric.setupActivity(Activity.class); ChooseLockSettingsHelper.Builder builder = new ChooseLockSettingsHelper.Builder(activity); @@ -80,7 +74,8 @@ public class ChooseLockSettingsHelperTest { .setTitle("title") .setHeader("header") .setDescription("description") - .setChallenge(10000L) + .setForceVerifyPath(true) + .setReturnCredentials(true) .setUserId(UserHandle.myUserId()); ChooseLockSettingsHelper helper = getChooseLockSettingsHelper(builder); helper.launch(); @@ -91,12 +86,10 @@ public class ChooseLockSettingsHelperTest { assertEquals(new ComponentName("com.android.settings", ConfirmLockPattern.InternalActivity.class.getName()), startedIntent.getComponent()); - assertFalse(startedIntent.getBooleanExtra( - ChooseLockSettingsHelper.EXTRA_KEY_RETURN_CREDENTIALS, false)); assertTrue(startedIntent.getBooleanExtra( - ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false)); - assertEquals(10000L, startedIntent.getLongExtra( - ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0L)); + ChooseLockSettingsHelper.EXTRA_KEY_RETURN_CREDENTIALS, true)); + assertTrue(startedIntent.getBooleanExtra( + ChooseLockSettingsHelper.EXTRA_KEY_FORCE_VERIFY, true)); assertFalse((startedIntent.getFlags() & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0); assertFalse(startedIntent.getBooleanExtra( ConfirmDeviceCredentialBaseFragment.DARK_THEME, false)); diff --git a/tests/robotests/src/com/android/settings/password/SetNewPasswordControllerTest.java b/tests/robotests/src/com/android/settings/password/SetNewPasswordControllerTest.java index d3832a4f91d..ce117b7ad72 100644 --- a/tests/robotests/src/com/android/settings/password/SetNewPasswordControllerTest.java +++ b/tests/robotests/src/com/android/settings/password/SetNewPasswordControllerTest.java @@ -19,14 +19,11 @@ package com.android.settings.password; import static android.content.pm.PackageManager.FEATURE_FACE; import static android.content.pm.PackageManager.FEATURE_FINGERPRINT; -import static com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment - .HIDE_DISABLED_PREFS; -import static com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment - .MINIMUM_QUALITY_KEY; -import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE; +import static com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS; +import static com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY; import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE; import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT; -import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE; +import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW; import static com.google.common.truth.Truth.assertThat; @@ -57,8 +54,6 @@ import org.robolectric.RobolectricTestRunner; public final class SetNewPasswordControllerTest { private static final int CURRENT_USER_ID = 101; - private static final long FINGERPRINT_CHALLENGE = -9876512313131L; - private static final long FACE_CHALLENGE = 1352057789L; @Mock private PackageManager mPackageManager; @@ -79,11 +74,7 @@ public final class SetNewPasswordControllerTest { mSetNewPasswordController = new SetNewPasswordController( CURRENT_USER_ID, mPackageManager, mFingerprintManager, mFaceManager, mDevicePolicyManager, mUi); - - when(mFingerprintManager.generateChallengeBlocking()).thenReturn(FINGERPRINT_CHALLENGE); when(mPackageManager.hasSystemFeature(eq(FEATURE_FINGERPRINT))).thenReturn(true); - - when(mFaceManager.generateChallengeBlocking()).thenReturn(FACE_CHALLENGE); when(mPackageManager.hasSystemFeature(eq(FEATURE_FACE))).thenReturn(true); } @@ -278,12 +269,8 @@ public final class SetNewPasswordControllerTest { "All disabled preference should be removed.", actualBundle.getBoolean(HIDE_DISABLED_PREFS)); assertTrue( - "There must be a fingerprint challenge.", - actualBundle.getBoolean(EXTRA_KEY_HAS_CHALLENGE)); - assertEquals( - "The fingerprint challenge must come from the FingerprintManager", - FINGERPRINT_CHALLENGE, - actualBundle.getLong(EXTRA_KEY_CHALLENGE)); + "Fingerprint enroll must request Gatekeeper Password.", + actualBundle.getBoolean(EXTRA_KEY_REQUEST_GK_PW)); assertTrue( "The request must be a fingerprint set up request.", actualBundle.getBoolean(EXTRA_KEY_FOR_FINGERPRINT)); @@ -302,12 +289,8 @@ public final class SetNewPasswordControllerTest { "All disabled preference should be removed.", actualBundle.getBoolean(HIDE_DISABLED_PREFS)); assertTrue( - "There must be a face challenge.", - actualBundle.getBoolean(EXTRA_KEY_HAS_CHALLENGE)); - assertEquals( - "The face challenge must come from the FaceManager", - FACE_CHALLENGE, - actualBundle.getLong(EXTRA_KEY_CHALLENGE)); + "Face enroll must request Gatekeeper Password", + actualBundle.getBoolean(EXTRA_KEY_REQUEST_GK_PW)); assertTrue( "The request must be a face set up request.", actualBundle.getBoolean(EXTRA_KEY_FOR_FACE));