4/n: Remove challenge from choose/confirm, use new path

Biometric enrollment will not request a Gatekeeper HAT during
initial credential setup or credential confirmation anymore.
Instead, it is broken down into the following steps now.

Bug: 161765592

1) Request credential setup / confirmation to return a
   Gatekeeper Password
2) Biometric enrollment will generate a challenge
3) Biometric enrollment will request LockSettingsService to
   verify(GatekeeperPassword, challenge), and upon verification,
   the Gatekeeper HAT will be returned.

Since both LockSettingsService and Biometric enroll/settings
make use of biometric challenges, this allows us to make the
challenge ownership/lifecycle clear (vs. previously, where
LockSettingsService has no idea who the challenge belongs to).

Exempt-From-Owner-Approval:For files not owned by our team,
(StorageWizard), this change is just a method rename

Test: RunSettingsRoboTests

Run the following on face/fingerprint devices
Test: Remove credential
      adb shell am start -a android.app.action.SET_NEW_PASSWORD
      Set up credential + fingerprint
Test: Remove credential,
      adb shell am start -a android.settings.FINGERPRINT_SETTINGS
      This tests the ChooseLock* logic in FingerprintSettings
Test: Set up credential,
      adb shell am start -a android.settings.FINGERPRINT_SETTINGS
      This tests the ConfirmLock* logic in FingerprintSettings
Test: Remove device credential, enroll fingerprint/face. Succeeds.
      This tests the ChooseLock* returning SP path from
      BiometricEnrollIntro
Test: With credential and fingerprint/face enrolled, go to
      fingerprint/face settings and enroll. This tests the
      ConfirmLock* path in Fingerprint/FaceSettings
Test: Remove device credential, enroll credential-only, enroll
      fingerprint/face separately. Succeeds. This tests the
      ConfirmLock* returning SP path in BiometricEnrollIntro
Test: In SUW, set up credential, then biometric. This tests
      the ChooseLock* path in SUW
Test: In SUW, set up credential, go back, then set up biometric.
      This tests the ConfirmLock* path in SUW

Change-Id: Idf6fcb43f7497323d089eb9c37125294e7a7f5dc
This commit is contained in:
Kevin Chyn
2020-07-23 19:36:26 -07:00
parent e67a0afc41
commit 7b0867c6d3
25 changed files with 269 additions and 235 deletions

View File

@@ -104,9 +104,14 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN); .getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
final int userId = getIntent() final int userId = getIntent()
.getIntExtra(Intent.EXTRA_USER_ID, UserHandle.USER_NULL); .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(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
intent.putExtra(Intent.EXTRA_USER_ID, userId); intent.putExtra(Intent.EXTRA_USER_ID, userId);
if (gkPw != null) {
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW, gkPw);
}
} }
startActivity(intent); startActivity(intent);

View File

@@ -88,7 +88,13 @@ public abstract class BiometricEnrollBase extends InstrumentedActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(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); mFromSettingsSummary = getIntent().getBooleanExtra(EXTRA_FROM_SETTINGS_SUMMARY, false);
if (savedInstanceState != null && mToken == null) { if (savedInstanceState != null && mToken == null) {
mLaunchedConfirmLock = savedInstanceState.getBoolean(EXTRA_KEY_LAUNCHED_CONFIRM); mLaunchedConfirmLock = savedInstanceState.getBoolean(EXTRA_KEY_LAUNCHED_CONFIRM);
@@ -180,11 +186,11 @@ public abstract class BiometricEnrollBase extends InstrumentedActivity {
return intent; return intent;
} }
protected void launchConfirmLock(int titleResId, long challenge) { protected void launchConfirmLock(int titleResId) {
final ChooseLockSettingsHelper.Builder builder = new ChooseLockSettingsHelper.Builder(this); final ChooseLockSettingsHelper.Builder builder = new ChooseLockSettingsHelper.Builder(this);
builder.setRequestCode(CONFIRM_REQUEST) builder.setRequestCode(CONFIRM_REQUEST)
.setTitle(getString(titleResId)) .setTitle(getString(titleResId))
.setChallenge(challenge) .setRequestGatekeeperPassword(true)
.setForegroundOnly(true) .setForegroundOnly(true)
.setReturnCredentials(true); .setReturnCredentials(true);

View File

@@ -164,7 +164,7 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
// It's possible to have a token but mLaunchedConfirmLock == false, since // It's possible to have a token but mLaunchedConfirmLock == false, since
// ChooseLockGeneric can pass us a token. // ChooseLockGeneric can pass us a token.
mConfirmingCredentials = true; mConfirmingCredentials = true;
launchConfirmLock(getConfirmLockTitleResId(), getChallenge()); launchConfirmLock(getConfirmLockTitleResId());
} }
} }
} }
@@ -217,12 +217,10 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
private void launchChooseLock() { private void launchChooseLock() {
Intent intent = getChooseLockIntent(); Intent intent = getChooseLockIntent();
long challenge = getChallenge();
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY, intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING); DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true); intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, true);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge);
intent.putExtra(getExtraKeyForBiometric(), true); intent.putExtra(getExtraKeyForBiometric(), true);
if (mUserId != UserHandle.USER_NULL) { if (mUserId != UserHandle.USER_NULL) {
intent.putExtra(Intent.EXTRA_USER_ID, mUserId); intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
@@ -271,8 +269,7 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
} else if (requestCode == CHOOSE_LOCK_GENERIC_REQUEST) { } else if (requestCode == CHOOSE_LOCK_GENERIC_REQUEST) {
if (resultCode == RESULT_FINISHED) { if (resultCode == RESULT_FINISHED) {
updatePasswordQuality(); updatePasswordQuality();
mToken = data.getByteArrayExtra( mToken = BiometricUtils.requestGatekeeperHat(this, data, mUserId, getChallenge());
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
overridePendingTransition(R.anim.sud_slide_next_in, R.anim.sud_slide_next_out); overridePendingTransition(R.anim.sud_slide_next_in, R.anim.sud_slide_next_out);
mConfirmingCredentials = false; mConfirmingCredentials = false;
return; return;
@@ -283,7 +280,7 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
} else if (requestCode == CONFIRM_REQUEST) { } else if (requestCode == CONFIRM_REQUEST) {
mConfirmingCredentials = false; mConfirmingCredentials = false;
if (resultCode == RESULT_OK && data != null) { if (resultCode == RESULT_OK && data != null) {
mToken = data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN); mToken = BiometricUtils.requestGatekeeperHat(this, data, mUserId, getChallenge());
overridePendingTransition(R.anim.sud_slide_next_in, R.anim.sud_slide_next_out); overridePendingTransition(R.anim.sud_slide_next_in, R.anim.sud_slide_next_out);
} else { } else {
setResult(resultCode, data); setResult(resultCode, data);

View File

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

View File

@@ -26,6 +26,7 @@ import android.widget.TextView;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Utils; import com.android.settings.Utils;
import com.android.settings.biometrics.BiometricEnrollIntroduction; import com.android.settings.biometrics.BiometricEnrollIntroduction;
import com.android.settings.biometrics.BiometricUtils;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
import com.android.settings.password.ChooseLockSettingsHelper; import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.settingslib.RestrictedLockUtilsInternal;
@@ -38,16 +39,26 @@ import com.google.android.setupdesign.template.RequireScrollMixin;
public class FaceEnrollIntroduction extends BiometricEnrollIntroduction { public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
private static final String TAG = "FaceIntro"; private static final String TAG = "FaceEnrollIntroduction";
private FaceManager mFaceManager; private FaceManager mFaceManager;
private FaceFeatureProvider mFaceFeatureProvider; private FaceFeatureProvider mFaceFeatureProvider;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
mFaceManager = Utils.getFaceManagerOrNull(this);
// Check if the Gateekeper Password exists. If so, request for a Gatekeeper HAT to be
// created. This needs to be cleaned up, since currently it's not very clear which
// superclass is responsible for what. Doing the check here is the least risky way.
if (mToken == null && BiometricUtils.containsGatekeeperPassword(getIntent())) {
// 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.
final long challenge = mFaceManager.generateChallengeBlocking();
mToken = BiometricUtils.requestGatekeeperHat(this, getIntent(), mUserId, challenge);
}
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
mFaceManager = Utils.getFaceManagerOrNull(this);
mFaceFeatureProvider = FeatureFactory.getFactory(getApplicationContext()) mFaceFeatureProvider = FeatureFactory.getFactory(getApplicationContext())
.getFaceFeatureProvider(); .getFaceFeatureProvider();
@@ -86,9 +97,7 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
RequireScrollMixin.class); RequireScrollMixin.class);
requireScrollMixin.requireScrollWithButton(this, agreeButton, requireScrollMixin.requireScrollWithButton(this, agreeButton,
R.string.security_settings_face_enroll_introduction_more, R.string.security_settings_face_enroll_introduction_more,
button -> { this::onNextButtonClick);
onNextButtonClick(button);
});
} }
final TextView footer2 = findViewById(R.id.face_enroll_introduction_footer_part_2); final TextView footer2 = findViewById(R.id.face_enroll_introduction_footer_part_2);

View File

@@ -37,6 +37,7 @@ import androidx.preference.Preference;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settings.Utils; import com.android.settings.Utils;
import com.android.settings.biometrics.BiometricUtils;
import com.android.settings.dashboard.DashboardFragment; import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
import com.android.settings.password.ChooseLockSettingsHelper; import com.android.settings.password.ChooseLockSettingsHelper;
@@ -202,15 +203,11 @@ public class FaceSettings extends DashboardFragment {
super.onResume(); super.onResume();
if (mToken == null && !mConfirmingPassword) { 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 = final ChooseLockSettingsHelper.Builder builder =
new ChooseLockSettingsHelper.Builder(getActivity(), this); new ChooseLockSettingsHelper.Builder(getActivity(), this);
final boolean launched = builder.setRequestCode(CONFIRM_REQUEST) final boolean launched = builder.setRequestCode(CONFIRM_REQUEST)
.setTitle(getString(R.string.security_settings_face_preference_title)) .setTitle(getString(R.string.security_settings_face_preference_title))
.setChallenge(challenge) .setRequestGatekeeperPassword(true)
.setUserId(mUserId) .setUserId(mUserId)
.setForegroundOnly(true) .setForegroundOnly(true)
.setReturnCredentials(true) .setReturnCredentials(true)
@@ -238,18 +235,22 @@ public class FaceSettings extends DashboardFragment {
@Override @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
if (mToken == null && !BiometricUtils.containsGatekeeperPassword(data)) {
Log.e(TAG, "No credential");
finish();
}
if (requestCode == CONFIRM_REQUEST) { if (requestCode == CONFIRM_REQUEST) {
mConfirmingPassword = false;
if (resultCode == RESULT_FINISHED || resultCode == RESULT_OK) { if (resultCode == RESULT_FINISHED || resultCode == RESULT_OK) {
// The pin/pattern/password was set. // The pin/pattern/password was set.
if (data != null) { mFaceManager.generateChallenge(challenge -> {
mToken = data.getByteArrayExtra( mToken = BiometricUtils.requestGatekeeperHat(getPrefContext(), data, mUserId,
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN); challenge);
if (mToken != null) { mAttentionController.setToken(mToken);
mAttentionController.setToken(mToken); mEnrollController.setToken(mToken);
mEnrollController.setToken(mToken); mConfirmingPassword = false;
} });
}
} }
} else if (requestCode == ENROLL_REQUEST) { } else if (requestCode == ENROLL_REQUEST) {
if (resultCode == RESULT_TIMEOUT) { if (resultCode == RESULT_TIMEOUT) {
@@ -257,11 +258,6 @@ public class FaceSettings extends DashboardFragment {
finish(); finish();
} }
} }
if (mToken == null) {
// Didn't get an authentication, finishing
finish();
}
} }
@Override @Override

View File

@@ -28,6 +28,7 @@ import com.android.settings.R;
import com.android.settings.Utils; import com.android.settings.Utils;
import com.android.settings.biometrics.BiometricEnrollBase; import com.android.settings.biometrics.BiometricEnrollBase;
import com.android.settings.biometrics.BiometricEnrollSidecar.Listener; import com.android.settings.biometrics.BiometricEnrollSidecar.Listener;
import com.android.settings.biometrics.BiometricUtils;
import com.android.settings.password.ChooseLockSettingsHelper; import com.android.settings.password.ChooseLockSettingsHelper;
import com.google.android.setupcompat.template.FooterBarMixin; import com.google.android.setupcompat.template.FooterBarMixin;
@@ -60,6 +61,16 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase {
setHeaderText(R.string.security_settings_fingerprint_enroll_find_sensor_title); setHeaderText(R.string.security_settings_fingerprint_enroll_find_sensor_title);
if (mToken == null && BiometricUtils.containsGatekeeperPassword(getIntent())) {
final FingerprintManager fpm = getSystemService(FingerprintManager.class);
final long challenge = fpm.generateChallengeBlocking();
mToken = BiometricUtils.requestGatekeeperHat(this, getIntent(), mUserId, challenge);
// 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(); // already confirmed, so start looking for fingerprint startLookingForFingerprint(); // already confirmed, so start looking for fingerprint
@@ -160,10 +171,13 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase {
protected void onActivityResult(int requestCode, int resultCode, Intent data) { protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CONFIRM_REQUEST) { if (requestCode == CONFIRM_REQUEST) {
if (resultCode == RESULT_OK && data != null) { if (resultCode == RESULT_OK && data != null) {
throw new IllegalStateException("Pretty sure this is dead code");
/*
mToken = data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN); mToken = data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
overridePendingTransition(R.anim.sud_slide_next_in, R.anim.sud_slide_next_out); overridePendingTransition(R.anim.sud_slide_next_in, R.anim.sud_slide_next_out);
getIntent().putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken); getIntent().putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken);
startLookingForFingerprint(); startLookingForFingerprint();
*/
} else { } else {
finish(); finish();
} }

View File

@@ -54,6 +54,7 @@ import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.SubSettings; import com.android.settings.SubSettings;
import com.android.settings.Utils; import com.android.settings.Utils;
import com.android.settings.biometrics.BiometricEnrollBase; import com.android.settings.biometrics.BiometricEnrollBase;
import com.android.settings.biometrics.BiometricUtils;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.password.ChooseLockGeneric; import com.android.settings.password.ChooseLockGeneric;
import com.android.settings.password.ChooseLockSettingsHelper; import com.android.settings.password.ChooseLockSettingsHelper;
@@ -565,14 +566,13 @@ public class FingerprintSettings extends SubSettings {
@Override @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CHOOSE_LOCK_GENERIC_REQUEST if (requestCode == CONFIRM_REQUEST || requestCode == CHOOSE_LOCK_GENERIC_REQUEST) {
|| requestCode == CONFIRM_REQUEST) {
mLaunchedConfirm = false; mLaunchedConfirm = false;
if (resultCode == RESULT_FINISHED || resultCode == RESULT_OK) { if (resultCode == RESULT_FINISHED || resultCode == RESULT_OK) {
// The lock pin/pattern/password was set. Start enrolling!
if (data != null) { if (data != null) {
mToken = data.getByteArrayExtra( final long challenge = mFingerprintManager.generateChallengeBlocking();
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN); mToken = BiometricUtils.requestGatekeeperHat(getActivity(), data, mUserId,
challenge);
} }
} }
} else if (requestCode == ADD_FINGERPRINT_REQUEST) { } else if (requestCode == ADD_FINGERPRINT_REQUEST) {
@@ -635,26 +635,26 @@ public class FingerprintSettings extends SubSettings {
private void launchChooseOrConfirmLock() { private void launchChooseOrConfirmLock() {
final Intent intent = new Intent(); final Intent intent = new Intent();
final long challenge = mFingerprintManager.generateChallengeBlocking();
final ChooseLockSettingsHelper.Builder builder = final ChooseLockSettingsHelper.Builder builder =
new ChooseLockSettingsHelper.Builder(getActivity(), this); new ChooseLockSettingsHelper.Builder(getActivity(), this);
final boolean launched = builder.setRequestCode(CONFIRM_REQUEST) final boolean launched = builder.setRequestCode(CONFIRM_REQUEST)
.setTitle(getString(R.string.security_settings_fingerprint_preference_title)) .setTitle(getString(R.string.security_settings_fingerprint_preference_title))
.setChallenge(challenge) .setRequestGatekeeperPassword(true)
.setUserId(mUserId) .setUserId(mUserId)
.setForegroundOnly(true) .setForegroundOnly(true)
.setReturnCredentials(true) .setReturnCredentials(true)
.show(); .show();
if (!launched) { 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.setClassName(SETTINGS_PACKAGE_NAME, ChooseLockGeneric.class.getName());
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY, intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING); DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS,
true); true);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true);
intent.putExtra(Intent.EXTRA_USER_ID, mUserId); 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); intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
startActivityForResult(intent, CHOOSE_LOCK_GENERIC_REQUEST); startActivityForResult(intent, CHOOSE_LOCK_GENERIC_REQUEST);
} }

View File

@@ -109,7 +109,7 @@ public class StorageWizardMigrateConfirm extends StorageWizardBase {
.setDescription(description) .setDescription(description)
.setUserId(user.id) .setUserId(user.id)
.setAllowAnyUserId(true) .setAllowAnyUserId(true)
.setChallenge(0L) .setForceVerifyPath(true)
.show(); .show();
return; return;
} }

View File

@@ -90,7 +90,7 @@ public class StorageWizardMoveConfirm extends StorageWizardBase {
builder.setRequestCode(REQUEST_CREDENTIAL) builder.setRequestCode(REQUEST_CREDENTIAL)
.setDescription(description) .setDescription(description)
.setUserId(user.id) .setUserId(user.id)
.setChallenge(0L) .setForceVerifyPath(true)
.setAllowAnyUserId(true) .setAllowAnyUserId(true)
.show(); .show();
return; return;

View File

@@ -144,8 +144,7 @@ public class ChooseLockGeneric extends SettingsActivity {
private LockPatternUtils mLockPatternUtils; private LockPatternUtils mLockPatternUtils;
private DevicePolicyManager mDpm; private DevicePolicyManager mDpm;
private boolean mHasChallenge = false; private boolean mRequestGatekeeperPassword = false;
private long mChallenge;
private boolean mPasswordConfirmed = false; private boolean mPasswordConfirmed = false;
private boolean mWaitingForConfirmation = false; private boolean mWaitingForConfirmation = false;
private boolean mForChangeCredRequiredForBoot = false; private boolean mForChangeCredRequiredForBoot = false;
@@ -211,10 +210,8 @@ public class ChooseLockGeneric extends SettingsActivity {
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
} }
mHasChallenge = intent.getBooleanExtra( mRequestGatekeeperPassword = intent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false); ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, false);
mChallenge = intent.getLongExtra(
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
mForFingerprint = intent.getBooleanExtra( mForFingerprint = intent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false); ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
mForFace = intent.getBooleanExtra( mForFace = intent.getBooleanExtra(
@@ -386,9 +383,12 @@ public class ChooseLockGeneric extends SettingsActivity {
mForFingerprint); mForFingerprint);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE,
mForFace); 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( startActivityForResult(
intent, intent,
mIsSetNewPassword && mHasChallenge mIsSetNewPassword && mRequestGatekeeperPassword
? CHOOSE_LOCK_BEFORE_BIOMETRIC_REQUEST ? CHOOSE_LOCK_BEFORE_BIOMETRIC_REQUEST
: ENABLE_ENCRYPTION_REQUEST); : ENABLE_ENCRYPTION_REQUEST);
} else { } else {
@@ -438,6 +438,10 @@ public class ChooseLockGeneric extends SettingsActivity {
&& resultCode == BiometricEnrollBase.RESULT_FINISHED) { && resultCode == BiometricEnrollBase.RESULT_FINISHED) {
Intent intent = getBiometricEnrollIntent(getActivity()); Intent intent = getBiometricEnrollIntent(getActivity());
if (data != null) { 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()); intent.putExtras(data.getExtras());
} }
// Forward the target user id to fingerprint setup page. // Forward the target user id to fingerprint setup page.
@@ -722,10 +726,8 @@ public class ChooseLockGeneric extends SettingsActivity {
.setRequestedMinComplexity(mRequestedMinComplexity) .setRequestedMinComplexity(mRequestedMinComplexity)
.setForFingerprint(mForFingerprint) .setForFingerprint(mForFingerprint)
.setForFace(mForFace) .setForFace(mForFace)
.setUserId(mUserId); .setUserId(mUserId)
if (mHasChallenge) { .setRequestGatekeeperPassword(mRequestGatekeeperPassword);
builder.setChallenge(mChallenge);
}
if (mUserPassword != null) { if (mUserPassword != null) {
builder.setPassword(mUserPassword); builder.setPassword(mUserPassword);
} }
@@ -740,10 +742,8 @@ public class ChooseLockGeneric extends SettingsActivity {
new ChooseLockPattern.IntentBuilder(getContext()) new ChooseLockPattern.IntentBuilder(getContext())
.setForFingerprint(mForFingerprint) .setForFingerprint(mForFingerprint)
.setForFace(mForFace) .setForFace(mForFace)
.setUserId(mUserId); .setUserId(mUserId)
if (mHasChallenge) { .setRequestGatekeeperPassword(mRequestGatekeeperPassword);
builder.setChallenge(mChallenge);
}
if (mUserPassword != null) { if (mUserPassword != null) {
builder.setPattern(mUserPassword); builder.setPattern(mUserPassword);
} }
@@ -784,8 +784,13 @@ public class ChooseLockGeneric extends SettingsActivity {
intent.putExtra(EXTRA_SHOW_OPTIONS_BUTTON, chooseLockSkipped); intent.putExtra(EXTRA_SHOW_OPTIONS_BUTTON, chooseLockSkipped);
} }
intent.putExtra(EXTRA_CHOOSE_LOCK_GENERIC_EXTRAS, getIntent().getExtras()); 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, startActivityForResult(intent,
mIsSetNewPassword && mHasChallenge mIsSetNewPassword && mRequestGatekeeperPassword
? CHOOSE_LOCK_BEFORE_BIOMETRIC_REQUEST ? CHOOSE_LOCK_BEFORE_BIOMETRIC_REQUEST
: CHOOSE_LOCK_REQUEST); : CHOOSE_LOCK_REQUEST);
return; return;

View File

@@ -118,7 +118,6 @@ public class ChooseLockPassword extends SettingsActivity {
mIntent = new Intent(context, ChooseLockPassword.class); mIntent = new Intent(context, ChooseLockPassword.class);
mIntent.putExtra(ChooseLockGeneric.CONFIRM_CREDENTIALS, false); mIntent.putExtra(ChooseLockGeneric.CONFIRM_CREDENTIALS, false);
mIntent.putExtra(EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, false); mIntent.putExtra(EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, false);
mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
} }
public IntentBuilder setPasswordQuality(int quality) { public IntentBuilder setPasswordQuality(int quality) {
@@ -131,9 +130,9 @@ public class ChooseLockPassword extends SettingsActivity {
return this; return this;
} }
public IntentBuilder setChallenge(long challenge) { public IntentBuilder setRequestGatekeeperPassword(boolean requestGatekeeperPassword) {
mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true); mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW,
mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge); requestGatekeeperPassword);
return this; return this;
} }
@@ -212,8 +211,7 @@ public class ChooseLockPassword extends SettingsActivity {
private LockscreenCredential mCurrentCredential; private LockscreenCredential mCurrentCredential;
private LockscreenCredential mChosenPassword; private LockscreenCredential mChosenPassword;
private boolean mHasChallenge; private boolean mRequestGatekeeperPassword;
private long mChallenge;
private ImeAwareEditText mPasswordEntry; private ImeAwareEditText mPasswordEntry;
private TextViewInputDisabler mPasswordEntryInputDisabler; private TextViewInputDisabler mPasswordEntryInputDisabler;
@@ -408,7 +406,8 @@ public class ChooseLockPassword extends SettingsActivity {
w.setBlocking(true); w.setBlocking(true);
w.setListener(this); w.setListener(this);
w.start(utils, required, false, 0, currentCredential, currentCredential, mUserId); w.start(utils, required, false /* requestGatekeeperPassword */, currentCredential,
currentCredential, mUserId);
} }
mTextChangedHandler = new TextChangedHandler(); mTextChangedHandler = new TextChangedHandler();
} }
@@ -492,9 +491,8 @@ public class ChooseLockPassword extends SettingsActivity {
ChooseLockGeneric.CONFIRM_CREDENTIALS, true); ChooseLockGeneric.CONFIRM_CREDENTIALS, true);
mCurrentCredential = intent.getParcelableExtra( mCurrentCredential = intent.getParcelableExtra(
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
mHasChallenge = intent.getBooleanExtra( mRequestGatekeeperPassword = intent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false); ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, false);
mChallenge = intent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
if (savedInstanceState == null) { if (savedInstanceState == null) {
updateStage(Stage.Introduction); updateStage(Stage.Introduction);
if (confirmCredentials) { if (confirmCredentials) {
@@ -503,6 +501,7 @@ public class ChooseLockPassword extends SettingsActivity {
builder.setRequestCode(CONFIRM_EXISTING_REQUEST) builder.setRequestCode(CONFIRM_EXISTING_REQUEST)
.setTitle(getString(R.string.unlock_set_unlock_launch_picker_title)) .setTitle(getString(R.string.unlock_set_unlock_launch_picker_title))
.setReturnCredentials(true) .setReturnCredentials(true)
.setRequestGatekeeperPassword(mRequestGatekeeperPassword)
.setUserId(mUserId) .setUserId(mUserId)
.show(); .show();
} }
@@ -886,7 +885,7 @@ public class ChooseLockPassword extends SettingsActivity {
profileCredential); profileCredential);
} }
} }
mSaveAndFinishWorker.start(mLockPatternUtils, required, mHasChallenge, mChallenge, mSaveAndFinishWorker.start(mLockPatternUtils, required, mRequestGatekeeperPassword,
mChosenPassword, mCurrentCredential, mUserId); mChosenPassword, mCurrentCredential, mUserId);
} }
@@ -946,10 +945,9 @@ public class ChooseLockPassword extends SettingsActivity {
private LockscreenCredential mCurrentCredential; private LockscreenCredential mCurrentCredential;
public void start(LockPatternUtils utils, boolean required, public void start(LockPatternUtils utils, boolean required,
boolean hasChallenge, long challenge, boolean requestGatekeeperPassword, LockscreenCredential chosenPassword,
LockscreenCredential chosenPassword, LockscreenCredential currentCredential, LockscreenCredential currentCredential, int userId) {
int userId) { prepare(utils, required, requestGatekeeperPassword, userId);
prepare(utils, required, hasChallenge, challenge, userId);
mChosenPassword = chosenPassword; mChosenPassword = chosenPassword;
mCurrentCredential = currentCredential != null ? currentCredential mCurrentCredential = currentCredential != null ? currentCredential
@@ -967,17 +965,21 @@ public class ChooseLockPassword extends SettingsActivity {
unifyProfileCredentialIfRequested(); unifyProfileCredentialIfRequested();
} }
Intent result = null; Intent result = null;
if (success && mHasChallenge) { 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, final VerifyCredentialResponse response = mUtils.verifyCredential(mChosenPassword,
mChallenge, mUserId, 0 /* flags */); mUserId, LockPatternUtils.VERIFY_FLAG_RETURN_GK_PW);
if (!response.isMatched() || response.getGatekeeperHAT() == null) {
Log.e(TAG, "critical: bad response or missing GK HAT 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()); + response.toString());
} }
result = new Intent(); result = new Intent();
result.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, result.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW,
response.getGatekeeperHAT()); response.getGatekeeperPw());
} }
return Pair.create(success, result); return Pair.create(success, result);
} }

View File

@@ -42,7 +42,6 @@ import androidx.fragment.app.Fragment;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient; import com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient;
import com.android.internal.widget.LockPatternUtils; 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;
import com.android.internal.widget.LockPatternView.Cell; import com.android.internal.widget.LockPatternView.Cell;
import com.android.internal.widget.LockPatternView.DisplayMode; import com.android.internal.widget.LockPatternView.DisplayMode;
@@ -55,7 +54,6 @@ import com.android.settings.SetupWizardUtils;
import com.android.settings.Utils; import com.android.settings.Utils;
import com.android.settings.core.InstrumentedFragment; import com.android.settings.core.InstrumentedFragment;
import com.android.settings.notification.RedactionInterstitial; import com.android.settings.notification.RedactionInterstitial;
import com.android.settings.password.ChooseLockPassword.IntentBuilder;
import com.google.android.collect.Lists; import com.google.android.collect.Lists;
import com.google.android.setupcompat.template.FooterBarMixin; import com.google.android.setupcompat.template.FooterBarMixin;
@@ -107,7 +105,6 @@ public class ChooseLockPattern extends SettingsActivity {
mIntent = new Intent(context, ChooseLockPattern.class); mIntent = new Intent(context, ChooseLockPattern.class);
mIntent.putExtra(EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, false); mIntent.putExtra(EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, false);
mIntent.putExtra(ChooseLockGeneric.CONFIRM_CREDENTIALS, false); mIntent.putExtra(ChooseLockGeneric.CONFIRM_CREDENTIALS, false);
mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
} }
public IntentBuilder setUserId(int userId) { public IntentBuilder setUserId(int userId) {
@@ -115,9 +112,9 @@ public class ChooseLockPattern extends SettingsActivity {
return this; return this;
} }
public IntentBuilder setChallenge(long challenge) { public IntentBuilder setRequestGatekeeperPassword(boolean requestGatekeeperPassword) {
mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true); mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW,
mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge); requestGatekeeperPassword);
return this; return this;
} }
@@ -207,8 +204,7 @@ public class ChooseLockPattern extends SettingsActivity {
private static final String FRAGMENT_TAG_SAVE_AND_FINISH = "save_and_finish_worker"; private static final String FRAGMENT_TAG_SAVE_AND_FINISH = "save_and_finish_worker";
private LockscreenCredential mCurrentCredential; private LockscreenCredential mCurrentCredential;
private boolean mHasChallenge; private boolean mRequestGatekeeperPassword;
private long mChallenge;
protected TextView mTitleText; protected TextView mTitleText;
protected TextView mHeaderText; protected TextView mHeaderText;
protected TextView mMessageText; protected TextView mMessageText;
@@ -484,7 +480,8 @@ public class ChooseLockPattern extends SettingsActivity {
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
w.setBlocking(true); w.setBlocking(true);
w.setListener(this); w.setListener(this);
w.start(mLockPatternUtils, required, false, 0, current, current, mUserId); w.start(mLockPatternUtils, required, false /* requestGatekeeperPassword */, current,
current, mUserId);
} }
mForFingerprint = intent.getBooleanExtra( mForFingerprint = intent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false); ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
@@ -564,9 +561,8 @@ public class ChooseLockPattern extends SettingsActivity {
Intent intent = getActivity().getIntent(); Intent intent = getActivity().getIntent();
mCurrentCredential = mCurrentCredential =
intent.getParcelableExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); intent.getParcelableExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
mHasChallenge = intent.getBooleanExtra( mRequestGatekeeperPassword = intent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false); ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, false);
mChallenge = intent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
if (savedInstanceState == null) { if (savedInstanceState == null) {
if (confirmCredentials) { if (confirmCredentials) {
@@ -579,6 +575,7 @@ public class ChooseLockPattern extends SettingsActivity {
final boolean launched = builder.setRequestCode(CONFIRM_EXISTING_REQUEST) final boolean launched = builder.setRequestCode(CONFIRM_EXISTING_REQUEST)
.setTitle(getString(R.string.unlock_set_unlock_launch_picker_title)) .setTitle(getString(R.string.unlock_set_unlock_launch_picker_title))
.setReturnCredentials(true) .setReturnCredentials(true)
.setRequestGatekeeperPassword(mRequestGatekeeperPassword)
.setUserId(mUserId) .setUserId(mUserId)
.show(); .show();
@@ -859,7 +856,7 @@ public class ChooseLockPattern extends SettingsActivity {
} }
} }
mSaveAndFinishWorker.start(mLockPatternUtils, required, mSaveAndFinishWorker.start(mLockPatternUtils, required,
mHasChallenge, mChallenge, mChosenPattern, mCurrentCredential, mUserId); mRequestGatekeeperPassword, mChosenPattern, mCurrentCredential, mUserId);
} }
@Override @Override
@@ -889,10 +886,10 @@ public class ChooseLockPattern extends SettingsActivity {
private LockscreenCredential mCurrentCredential; private LockscreenCredential mCurrentCredential;
private boolean mLockVirgin; private boolean mLockVirgin;
public void start(LockPatternUtils utils, boolean credentialRequired, boolean hasChallenge, public void start(LockPatternUtils utils, boolean credentialRequired,
long challenge, LockscreenCredential chosenPattern, boolean requestGatekeeperPassword, LockscreenCredential chosenPattern,
LockscreenCredential currentCredential, int userId) { LockscreenCredential currentCredential, int userId) {
prepare(utils, credentialRequired, hasChallenge, challenge, userId); prepare(utils, credentialRequired, requestGatekeeperPassword, userId);
mCurrentCredential = currentCredential != null ? currentCredential mCurrentCredential = currentCredential != null ? currentCredential
: LockscreenCredential.createNone(); : LockscreenCredential.createNone();
@@ -913,18 +910,21 @@ public class ChooseLockPattern extends SettingsActivity {
unifyProfileCredentialIfRequested(); unifyProfileCredentialIfRequested();
} }
Intent result = null; Intent result = null;
if (success && mHasChallenge) { 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, final VerifyCredentialResponse response = mUtils.verifyCredential(mChosenPattern,
mChallenge, userId, 0 /* flags */); userId, LockPatternUtils.VERIFY_FLAG_RETURN_GK_PW);
if (!response.isMatched() || response.getGatekeeperHAT() == null) { if (!response.isMatched() || response.getGatekeeperPw() == null) {
Log.e(TAG, "critical: bad response or missing GK HAT for known good pattern: " Log.e(TAG, "critical: bad response or missing GK HAT for known good pattern: "
+ response.toString()); + response.toString());
} }
result = new Intent(); result = new Intent();
result.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, result.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW,
response.getGatekeeperHAT()); response.getGatekeeperPw());
} }
return Pair.create(success, result); return Pair.create(success, result);
} }

View File

@@ -31,7 +31,9 @@ import android.util.Log;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import com.android.internal.widget.ICheckCredentialProgressCallback;
import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockscreenCredential;
import com.android.settings.SetupWizardUtils; import com.android.settings.SetupWizardUtils;
import com.android.settings.Utils; import com.android.settings.Utils;
import com.android.settings.core.SubSettingLauncher; import com.android.settings.core.SubSettingLauncher;
@@ -45,8 +47,9 @@ public final class ChooseLockSettingsHelper {
public static final String EXTRA_KEY_TYPE = "type"; public static final String EXTRA_KEY_TYPE = "type";
public static final String EXTRA_KEY_PASSWORD = "password"; public static final String EXTRA_KEY_PASSWORD = "password";
public static final String EXTRA_KEY_RETURN_CREDENTIALS = "return_credentials"; public static final String EXTRA_KEY_RETURN_CREDENTIALS = "return_credentials";
public static final String EXTRA_KEY_HAS_CHALLENGE = "has_challenge"; // Force the verifyCredential path instead of checkCredential path. This will be removed
public static final String EXTRA_KEY_CHALLENGE = "challenge"; // after b/161956762 is resolved.
public static final String EXTRA_KEY_FORCE_VERIFY = "force_verify";
// Gatekeeper HardwareAuthToken // Gatekeeper HardwareAuthToken
public static final String EXTRA_KEY_CHALLENGE_TOKEN = "hw_auth_token"; 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_FINGERPRINT = "for_fingerprint";
@@ -122,8 +125,7 @@ public final class ChooseLockSettingsHelper {
// ChooseLockSettingsHelper will determine the caller's userId if none provided. // ChooseLockSettingsHelper will determine the caller's userId if none provided.
private int mUserId; private int mUserId;
private boolean mAllowAnyUserId; private boolean mAllowAnyUserId;
// The challenge can be 0, which is different than "no challenge" private boolean mForceVerifyPath;
@Nullable Long mChallenge;
boolean mRequestGatekeeperPassword; boolean mRequestGatekeeperPassword;
public Builder(@NonNull Activity activity) { public Builder(@NonNull Activity activity) {
@@ -182,6 +184,10 @@ public final class ChooseLockSettingsHelper {
* {@link #EXTRA_KEY_TYPE}, {@link #EXTRA_KEY_PASSWORD}, * {@link #EXTRA_KEY_TYPE}, {@link #EXTRA_KEY_PASSWORD},
* {@link #EXTRA_KEY_CHALLENGE_TOKEN}, {@link #EXTRA_KEY_GK_PW} * {@link #EXTRA_KEY_CHALLENGE_TOKEN}, {@link #EXTRA_KEY_GK_PW}
* Note that if this is true, this can only be called internally. * 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) { @NonNull public Builder setReturnCredentials(boolean returnCredentials) {
mReturnCredentials = returnCredentials; mReturnCredentials = returnCredentials;
@@ -226,14 +232,11 @@ public final class ChooseLockSettingsHelper {
} }
/** /**
* @param challenge an opaque payload that will be wrapped in the Gatekeeper's payload * @param forceVerifyPath Forces the VerifyCredential path instead of the CheckCredential
* if authentication is successful. Common use case is for the caller's * path. This will be removed after b/161956762 is resolved.
* 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.
*/ */
@NonNull public Builder setChallenge(long challenge) { @NonNull public Builder setForceVerifyPath(boolean forceVerifyPath) {
mChallenge = challenge; mForceVerifyPath = forceVerifyPath;
return this; return this;
} }
@@ -246,9 +249,6 @@ public final class ChooseLockSettingsHelper {
* Upon confirmation of the user's password, the Gatekeeper Password will be returned via * Upon confirmation of the user's password, the Gatekeeper Password will be returned via
* onActivityResult with the key being {@link #EXTRA_KEY_GK_PW}. * onActivityResult with the key being {@link #EXTRA_KEY_GK_PW}.
* @param requestGatekeeperPassword * @param requestGatekeeperPassword
*
* Note that invoking {@link #setChallenge(long)} will be treated as a no-op if Gatekeeper
* Password has been requested.
*/ */
@NonNull public Builder setRequestGatekeeperPassword(boolean requestGatekeeperPassword) { @NonNull public Builder setRequestGatekeeperPassword(boolean requestGatekeeperPassword) {
mRequestGatekeeperPassword = requestGatekeeperPassword; mRequestGatekeeperPassword = requestGatekeeperPassword;
@@ -266,10 +266,10 @@ public final class ChooseLockSettingsHelper {
+ " onActivityResult"); + " onActivityResult");
} }
if (mChallenge != null && !mReturnCredentials) { if (mRequestGatekeeperPassword && !mReturnCredentials) {
// HAT containing the signed challenge will not be available to the caller. // 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" Log.w(TAG, "Requested gatekeeper password but not requesting ReturnCredentials. Are"
+ " is what you want?"); + " you sure this is what you want?");
} }
return new ChooseLockSettingsHelper(this, mActivity, mFragment); return new ChooseLockSettingsHelper(this, mActivity, mFragment);
@@ -285,29 +285,28 @@ public final class ChooseLockSettingsHelper {
* @return true if the confirmation activity is shown (e.g. user has a credential set up) * @return true if the confirmation activity is shown (e.g. user has a credential set up)
*/ */
public boolean launch() { public boolean launch() {
final long challenge = mBuilder.mChallenge != null ? mBuilder.mChallenge : 0L;
return launchConfirmationActivity(mBuilder.mRequestCode, mBuilder.mTitle, mBuilder.mHeader, return launchConfirmationActivity(mBuilder.mRequestCode, mBuilder.mTitle, mBuilder.mHeader,
mBuilder.mDescription, mBuilder.mReturnCredentials, mBuilder.mExternal, mBuilder.mDescription, mBuilder.mReturnCredentials, mBuilder.mExternal,
mBuilder.mChallenge != null, challenge, mBuilder.mUserId, mBuilder.mForceVerifyPath, mBuilder.mUserId, mBuilder.mAlternateButton,
mBuilder.mAlternateButton, mBuilder.mAllowAnyUserId, mBuilder.mForegroundOnly, mBuilder.mAllowAnyUserId, mBuilder.mForegroundOnly,
mBuilder.mRequestGatekeeperPassword); mBuilder.mRequestGatekeeperPassword);
} }
private boolean launchConfirmationActivity(int request, @Nullable CharSequence title, private boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
@Nullable CharSequence header, @Nullable CharSequence description, @Nullable CharSequence header, @Nullable CharSequence description,
boolean returnCredentials, boolean external, boolean hasChallenge, boolean returnCredentials, boolean external, boolean forceVerifyPath,
long challenge, int userId, @Nullable CharSequence alternateButton, int userId, @Nullable CharSequence alternateButton, boolean allowAnyUser,
boolean allowAnyUser, boolean foregroundOnly, boolean requestGatekeeperPassword) { boolean foregroundOnly, boolean requestGatekeeperPassword) {
final int effectiveUserId = UserManager.get(mActivity).getCredentialOwnerProfile(userId); final int effectiveUserId = UserManager.get(mActivity).getCredentialOwnerProfile(userId);
boolean launched = false; boolean launched = false;
switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(effectiveUserId)) { switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(effectiveUserId)) {
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
launched = launchConfirmationActivity(request, title, header, description, launched = launchConfirmationActivity(request, title, header, description,
returnCredentials || hasChallenge returnCredentials
? ConfirmLockPattern.InternalActivity.class ? ConfirmLockPattern.InternalActivity.class
: ConfirmLockPattern.class, returnCredentials, external, : ConfirmLockPattern.class, returnCredentials, external,
hasChallenge, challenge, userId, alternateButton, allowAnyUser, forceVerifyPath, userId, alternateButton, allowAnyUser,
foregroundOnly, requestGatekeeperPassword); foregroundOnly, requestGatekeeperPassword);
break; break;
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC: case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
@@ -317,10 +316,10 @@ public final class ChooseLockSettingsHelper {
case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX: case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
case DevicePolicyManager.PASSWORD_QUALITY_MANAGED: case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
launched = launchConfirmationActivity(request, title, header, description, launched = launchConfirmationActivity(request, title, header, description,
returnCredentials || hasChallenge returnCredentials
? ConfirmLockPassword.InternalActivity.class ? ConfirmLockPassword.InternalActivity.class
: ConfirmLockPassword.class, returnCredentials, external, : ConfirmLockPassword.class, returnCredentials, external,
hasChallenge, challenge, userId, alternateButton, allowAnyUser, forceVerifyPath, userId, alternateButton, allowAnyUser,
foregroundOnly, requestGatekeeperPassword); foregroundOnly, requestGatekeeperPassword);
break; break;
} }
@@ -329,8 +328,8 @@ public final class ChooseLockSettingsHelper {
private boolean launchConfirmationActivity(int request, CharSequence title, CharSequence header, private boolean launchConfirmationActivity(int request, CharSequence title, CharSequence header,
CharSequence message, Class<?> activityClass, boolean returnCredentials, CharSequence message, Class<?> activityClass, boolean returnCredentials,
boolean external, boolean hasChallenge, long challenge, boolean external, boolean forceVerifyPath, int userId,
int userId, @Nullable CharSequence alternateButton, boolean allowAnyUser, @Nullable CharSequence alternateButton, boolean allowAnyUser,
boolean foregroundOnly, boolean requestGatekeeperPassword) { boolean foregroundOnly, boolean requestGatekeeperPassword) {
final Intent intent = new Intent(); final Intent intent = new Intent();
intent.putExtra(ConfirmDeviceCredentialBaseFragment.TITLE_TEXT, title); intent.putExtra(ConfirmDeviceCredentialBaseFragment.TITLE_TEXT, title);
@@ -342,8 +341,7 @@ public final class ChooseLockSettingsHelper {
intent.putExtra(ConfirmDeviceCredentialBaseFragment.SHOW_WHEN_LOCKED, external); intent.putExtra(ConfirmDeviceCredentialBaseFragment.SHOW_WHEN_LOCKED, external);
intent.putExtra(ConfirmDeviceCredentialBaseFragment.USE_FADE_ANIMATION, external); intent.putExtra(ConfirmDeviceCredentialBaseFragment.USE_FADE_ANIMATION, external);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_RETURN_CREDENTIALS, returnCredentials); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_RETURN_CREDENTIALS, returnCredentials);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, hasChallenge); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FORCE_VERIFY, forceVerifyPath);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge);
intent.putExtra(Intent.EXTRA_USER_ID, userId); intent.putExtra(Intent.EXTRA_USER_ID, userId);
intent.putExtra(KeyguardManager.EXTRA_ALTERNATE_BUTTON_LABEL, alternateButton); intent.putExtra(KeyguardManager.EXTRA_ALTERNATE_BUTTON_LABEL, alternateButton);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOREGROUND_ONLY, foregroundOnly); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOREGROUND_ONLY, foregroundOnly);

View File

@@ -74,7 +74,7 @@ public class ChooseLockTypeDialogFragment extends InstrumentedDialogFragment
// Copy the original extras into the new intent // Copy the original extras into the new intent
copyBooleanExtra(activityIntent, intent, copyBooleanExtra(activityIntent, intent,
ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false); ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, false);
copyBooleanExtra(activityIntent, intent, copyBooleanExtra(activityIntent, intent,
ChooseLockGenericFragment.EXTRA_SHOW_OPTIONS_BUTTON, false); ChooseLockGenericFragment.EXTRA_SHOW_OPTIONS_BUTTON, false);
if (activityIntent.hasExtra( if (activityIntent.hasExtra(
@@ -83,8 +83,6 @@ public class ChooseLockTypeDialogFragment extends InstrumentedDialogFragment
ChooseLockGenericFragment.EXTRA_CHOOSE_LOCK_GENERIC_EXTRAS)); ChooseLockGenericFragment.EXTRA_CHOOSE_LOCK_GENERIC_EXTRAS));
} }
intent.putExtra(LockPatternUtils.PASSWORD_TYPE_KEY, selectedLockType.defaultQuality); 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); WizardManagerHelper.copyWizardManagerExtras(activityIntent, intent);
activity.startActivity(intent); activity.startActivity(intent);
activity.finish(); activity.finish();

View File

@@ -27,7 +27,6 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Color; import android.graphics.Color;
import android.hardware.biometrics.BiometricConstants; import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricPrompt; import android.hardware.biometrics.BiometricPrompt;
import android.hardware.biometrics.BiometricPrompt.AuthenticationCallback; import android.hardware.biometrics.BiometricPrompt.AuthenticationCallback;
import android.hardware.biometrics.PromptInfo; import android.hardware.biometrics.PromptInfo;
@@ -81,18 +80,6 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
return intent; 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 BiometricFragment mBiometricFragment;
private DevicePolicyManager mDevicePolicyManager; private DevicePolicyManager mDevicePolicyManager;
private LockPatternUtils mLockPatternUtils; private LockPatternUtils mLockPatternUtils;
@@ -181,7 +168,6 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
getWindow().setStatusBarColor(Color.TRANSPARENT); getWindow().setStatusBarColor(Color.TRANSPARENT);
mBiometricManager = getSystemService(BiometricManager.class);
mDevicePolicyManager = getSystemService(DevicePolicyManager.class); mDevicePolicyManager = getSystemService(DevicePolicyManager.class);
mUserManager = UserManager.get(this); mUserManager = UserManager.get(this);
mTrustManager = getSystemService(TrustManager.class); mTrustManager = getSystemService(TrustManager.class);
@@ -394,7 +380,7 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
.setDescription(mDetails) .setDescription(mDetails)
.setExternal(true) .setExternal(true)
.setUserId(mUserId) .setUserId(mUserId)
.setChallenge(0L) .setForceVerifyPath(true)
.show(); .show();
} else if (mCredentialMode == CREDENTIAL_NORMAL) { } else if (mCredentialMode == CREDENTIAL_NORMAL) {
final ChooseLockSettingsHelper.Builder builder = final ChooseLockSettingsHelper.Builder builder =

View File

@@ -72,7 +72,7 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
protected boolean mReturnCredentials = false; protected boolean mReturnCredentials = false;
protected boolean mReturnGatekeeperPassword = false; protected boolean mReturnGatekeeperPassword = false;
protected boolean mVerifyChallenge = false; protected boolean mForceVerifyPath = false;
protected Button mCancelButton; protected Button mCancelButton;
/** Button allowing managed profile password reset, null when is not shown. */ /** Button allowing managed profile password reset, null when is not shown. */
@Nullable protected Button mForgotButton; @Nullable protected Button mForgotButton;
@@ -103,8 +103,8 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFr
mReturnGatekeeperPassword = intent.getBooleanExtra( mReturnGatekeeperPassword = intent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, false); ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, false);
mVerifyChallenge = intent.getBooleanExtra( mForceVerifyPath = intent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false); ChooseLockSettingsHelper.EXTRA_KEY_FORCE_VERIFY, false);
// Only take this argument into account if it belongs to the current profile. // Only take this argument into account if it belongs to the current profile.
mUserId = Utils.getUserIdFromBundle(getActivity(), intent.getExtras(), mUserId = Utils.getUserIdFromBundle(getActivity(), intent.getExtras(),

View File

@@ -49,7 +49,6 @@ import com.android.internal.widget.LockPatternChecker;
import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockscreenCredential; import com.android.internal.widget.LockscreenCredential;
import com.android.internal.widget.TextViewInputDisabler; import com.android.internal.widget.TextViewInputDisabler;
import com.android.internal.widget.VerifyCredentialResponse;
import com.android.settings.R; import com.android.settings.R;
import com.android.settingslib.animation.AppearAnimationUtils; import com.android.settingslib.animation.AppearAnimationUtils;
import com.android.settingslib.animation.DisappearAnimationUtils; import com.android.settingslib.animation.DisappearAnimationUtils;
@@ -390,7 +389,7 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
LockPatternUtils.VERIFY_FLAG_RETURN_GK_PW); LockPatternUtils.VERIFY_FLAG_RETURN_GK_PW);
return; return;
} }
} else if (mVerifyChallenge) { } else if (mForceVerifyPath) {
if (isInternalActivity()) { if (isInternalActivity()) {
startVerifyPassword(credential, intent, 0 /* flags */); startVerifyPassword(credential, intent, 0 /* flags */);
return; return;
@@ -409,8 +408,6 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
private void startVerifyPassword(LockscreenCredential credential, final Intent intent, private void startVerifyPassword(LockscreenCredential credential, final Intent intent,
@LockPatternUtils.VerifyFlag int flags) { @LockPatternUtils.VerifyFlag int flags) {
long challenge = getActivity().getIntent().getLongExtra(
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
final int localEffectiveUserId = mEffectiveUserId; final int localEffectiveUserId = mEffectiveUserId;
final int localUserId = mUserId; final int localUserId = mUserId;
final LockPatternChecker.OnVerifyCallback onVerifyCallback = (response, timeoutMs) -> { final LockPatternChecker.OnVerifyCallback onVerifyCallback = (response, timeoutMs) -> {
@@ -430,12 +427,10 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
localEffectiveUserId); localEffectiveUserId);
}; };
mPendingLockCheck = (localEffectiveUserId == localUserId) mPendingLockCheck = (localEffectiveUserId == localUserId)
? LockPatternChecker.verifyCredential( ? LockPatternChecker.verifyCredential(mLockPatternUtils, credential,
mLockPatternUtils, credential, challenge, localUserId, flags, localUserId, flags, onVerifyCallback)
onVerifyCallback) : LockPatternChecker.verifyTiedProfileChallenge(mLockPatternUtils, credential,
: LockPatternChecker.verifyTiedProfileChallenge( localUserId, flags, onVerifyCallback);
mLockPatternUtils, credential, challenge, localUserId, flags,
onVerifyCallback);
} }
private void startCheckPassword(final LockscreenCredential credential, private void startCheckPassword(final LockscreenCredential credential,

View File

@@ -40,7 +40,6 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockPatternView; import com.android.internal.widget.LockPatternView;
import com.android.internal.widget.LockPatternView.Cell; import com.android.internal.widget.LockPatternView.Cell;
import com.android.internal.widget.LockscreenCredential; import com.android.internal.widget.LockscreenCredential;
import com.android.internal.widget.VerifyCredentialResponse;
import com.android.settings.R; import com.android.settings.R;
import com.android.settingslib.animation.AppearAnimationCreator; import com.android.settingslib.animation.AppearAnimationCreator;
import com.android.settingslib.animation.AppearAnimationUtils; import com.android.settingslib.animation.AppearAnimationUtils;
@@ -432,7 +431,7 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
LockPatternUtils.VERIFY_FLAG_RETURN_GK_PW); LockPatternUtils.VERIFY_FLAG_RETURN_GK_PW);
return; return;
} }
} else if (mVerifyChallenge) { } else if (mForceVerifyPath) {
if (isInternalActivity()) { if (isInternalActivity()) {
startVerifyPattern(credential, intent, 0 /* flags */); startVerifyPattern(credential, intent, 0 /* flags */);
return; return;
@@ -453,8 +452,6 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
final Intent intent, @LockPatternUtils.VerifyFlag int flags) { final Intent intent, @LockPatternUtils.VerifyFlag int flags) {
final int localEffectiveUserId = mEffectiveUserId; final int localEffectiveUserId = mEffectiveUserId;
final int localUserId = mUserId; final int localUserId = mUserId;
long challenge = getActivity().getIntent().getLongExtra(
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
final LockPatternChecker.OnVerifyCallback onVerifyCallback = final LockPatternChecker.OnVerifyCallback onVerifyCallback =
(response, timeoutMs) -> { (response, timeoutMs) -> {
mPendingLockCheck = null; mPendingLockCheck = null;
@@ -474,10 +471,10 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
}; };
mPendingLockCheck = (localEffectiveUserId == localUserId) mPendingLockCheck = (localEffectiveUserId == localUserId)
? LockPatternChecker.verifyCredential( ? LockPatternChecker.verifyCredential(
mLockPatternUtils, pattern, challenge, localUserId, flags, mLockPatternUtils, pattern, localUserId, flags,
onVerifyCallback) onVerifyCallback)
: LockPatternChecker.verifyTiedProfileChallenge( : LockPatternChecker.verifyTiedProfileChallenge(
mLockPatternUtils, pattern, challenge, localUserId, flags, mLockPatternUtils, pattern, localUserId, flags,
onVerifyCallback); onVerifyCallback);
} }

View File

@@ -42,8 +42,7 @@ abstract class SaveChosenLockWorkerBase extends Fragment {
private Intent mResultData; private Intent mResultData;
protected LockPatternUtils mUtils; protected LockPatternUtils mUtils;
protected boolean mHasChallenge; protected boolean mRequestGatekeeperPassword;
protected long mChallenge;
protected boolean mWasSecureBefore; protected boolean mWasSecureBefore;
protected int mUserId; protected int mUserId;
protected int mUnificationProfileId = UserHandle.USER_NULL; protected int mUnificationProfileId = UserHandle.USER_NULL;
@@ -69,12 +68,10 @@ abstract class SaveChosenLockWorkerBase extends Fragment {
} }
protected void prepare(LockPatternUtils utils, boolean credentialRequired, protected void prepare(LockPatternUtils utils, boolean credentialRequired,
boolean hasChallenge, long challenge, int userId) { boolean requestGatekeeperPassword, int userId) {
mUtils = utils; mUtils = utils;
mUserId = userId; mUserId = userId;
mRequestGatekeeperPassword = requestGatekeeperPassword;
mHasChallenge = hasChallenge;
mChallenge = challenge;
// This will be a no-op for non managed profiles. // This will be a no-op for non managed profiles.
mWasSecureBefore = mUtils.isSecure(mUserId); mWasSecureBefore = mUtils.isSecure(mUserId);

View File

@@ -135,26 +135,22 @@ final class SetNewPasswordController {
private Bundle getFingerprintChooseLockExtras() { private Bundle getFingerprintChooseLockExtras() {
Bundle chooseLockExtras = new Bundle(); Bundle chooseLockExtras = new Bundle();
long challenge = mFingerprintManager.generateChallengeBlocking();
chooseLockExtras.putInt(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY, chooseLockExtras.putInt(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
PASSWORD_QUALITY_SOMETHING); PASSWORD_QUALITY_SOMETHING);
chooseLockExtras.putBoolean( chooseLockExtras.putBoolean(
ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true); ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true);
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true); chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, true);
chooseLockExtras.putLong(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge);
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true); chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true);
return chooseLockExtras; return chooseLockExtras;
} }
private Bundle getFaceChooseLockExtras() { private Bundle getFaceChooseLockExtras() {
Bundle chooseLockExtras = new Bundle(); Bundle chooseLockExtras = new Bundle();
long challenge = mFaceManager.generateChallengeBlocking();
chooseLockExtras.putInt(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY, chooseLockExtras.putInt(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
PASSWORD_QUALITY_SOMETHING); PASSWORD_QUALITY_SOMETHING);
chooseLockExtras.putBoolean( chooseLockExtras.putBoolean(
ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true); ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true);
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true); chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, true);
chooseLockExtras.putLong(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge);
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, true); chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, true);
return chooseLockExtras; return chooseLockExtras;
} }

View File

@@ -92,8 +92,8 @@ public class ChooseLockPasswordTest {
.setUserId(123) .setUserId(123)
.build(); .build();
assertThat(intent.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true)) assertThat(intent.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_FORCE_VERIFY, false))
.named("EXTRA_KEY_HAS_CHALLENGE") .named("EXTRA_KEY_FORCE_VERIFY")
.isFalse(); .isFalse();
assertThat((LockscreenCredential) intent.getParcelableExtra( assertThat((LockscreenCredential) intent.getParcelableExtra(
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD)) ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD))
@@ -108,19 +108,16 @@ public class ChooseLockPasswordTest {
} }
@Test @Test
public void intentBuilder_setChallenge_shouldAddExtras() { public void intentBuilder_setRequestGatekeeperPassword_shouldAddExtras() {
Intent intent = new IntentBuilder(application) Intent intent = new IntentBuilder(application)
.setChallenge(12345L) .setRequestGatekeeperPassword(true)
.setPasswordQuality(PASSWORD_QUALITY_ALPHANUMERIC) .setPasswordQuality(PASSWORD_QUALITY_ALPHANUMERIC)
.setUserId(123) .setUserId(123)
.build(); .build();
assertThat(intent.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false)) assertThat(intent.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, false))
.named("EXTRA_KEY_HAS_CHALLENGE") .named("EXTRA_KEY_REQUEST_GK_PW")
.isTrue(); .isTrue();
assertThat(intent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0L))
.named("EXTRA_KEY_CHALLENGE")
.isEqualTo(12345L);
assertThat(intent.getIntExtra(PASSWORD_TYPE_KEY, 0)) assertThat(intent.getIntExtra(PASSWORD_TYPE_KEY, 0))
.named("PASSWORD_TYPE_KEY") .named("PASSWORD_TYPE_KEY")
.isEqualTo(PASSWORD_QUALITY_ALPHANUMERIC); .isEqualTo(PASSWORD_QUALITY_ALPHANUMERIC);

View File

@@ -59,8 +59,8 @@ public class ChooseLockPatternTest {
.build(); .build();
assertThat(intent assertThat(intent
.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true)) .getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_FORCE_VERIFY, false))
.named("EXTRA_KEY_HAS_CHALLENGE") .named("EXTRA_KEY_FORCE_VERIFY")
.isFalse(); .isFalse();
assertThat((LockscreenCredential) intent assertThat((LockscreenCredential) intent
.getParcelableExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD)) .getParcelableExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD))
@@ -72,20 +72,16 @@ public class ChooseLockPatternTest {
} }
@Test @Test
public void intentBuilder_setChallenge_shouldAddExtras() { public void intentBuilder_setRequestGatekeeperPassword_shouldAddExtras() {
Intent intent = new IntentBuilder(application) Intent intent = new IntentBuilder(application)
.setChallenge(12345L) .setRequestGatekeeperPassword(true)
.setUserId(123) .setUserId(123)
.build(); .build();
assertThat(intent assertThat(intent
.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false)) .getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW, false))
.named("EXTRA_KEY_HAS_CHALLENGE") .named("EXTRA_KEY_REQUEST_GK_PW")
.isTrue(); .isTrue();
assertThat(intent
.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0L))
.named("EXTRA_KEY_CHALLENGE")
.isEqualTo(12345L);
assertThat(intent assertThat(intent
.getIntExtra(Intent.EXTRA_USER_ID, 0)) .getIntExtra(Intent.EXTRA_USER_ID, 0))
.named("EXTRA_USER_ID") .named("EXTRA_USER_ID")

View File

@@ -36,7 +36,7 @@ import org.robolectric.shadows.ShadowActivity.IntentForResult;
public class ChooseLockSettingsHelperTest { public class ChooseLockSettingsHelperTest {
@Test @Test
public void testLaunchConfirmationActivityWithExternalAndChallenge() { public void testLaunchConfirmationActivityWithExternal() {
final Activity activity = Robolectric.setupActivity(Activity.class); final Activity activity = Robolectric.setupActivity(Activity.class);
ChooseLockSettingsHelper.Builder builder = new ChooseLockSettingsHelper.Builder(activity); ChooseLockSettingsHelper.Builder builder = new ChooseLockSettingsHelper.Builder(activity);
@@ -45,7 +45,6 @@ public class ChooseLockSettingsHelperTest {
.setHeader("header") .setHeader("header")
.setDescription("description") .setDescription("description")
.setExternal(true) .setExternal(true)
.setChallenge(10000L)
.setUserId(UserHandle.myUserId()); .setUserId(UserHandle.myUserId());
ChooseLockSettingsHelper helper = getChooseLockSettingsHelper(builder); ChooseLockSettingsHelper helper = getChooseLockSettingsHelper(builder);
helper.launch(); helper.launch();
@@ -53,15 +52,10 @@ public class ChooseLockSettingsHelperTest {
ShadowActivity shadowActivity = Shadows.shadowOf(activity); ShadowActivity shadowActivity = Shadows.shadowOf(activity);
Intent startedIntent = shadowActivity.getNextStartedActivity(); Intent startedIntent = shadowActivity.getNextStartedActivity();
assertEquals(new ComponentName("com.android.settings", assertEquals(new ComponentName("com.android.settings", ConfirmLockPattern.class.getName()),
ConfirmLockPattern.InternalActivity.class.getName()),
startedIntent.getComponent()); startedIntent.getComponent());
assertFalse(startedIntent.getBooleanExtra( assertFalse(startedIntent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_RETURN_CREDENTIALS, false)); 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); assertTrue((startedIntent.getFlags() & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0);
assertFalse(startedIntent.getBooleanExtra( assertFalse(startedIntent.getBooleanExtra(
ConfirmDeviceCredentialBaseFragment.DARK_THEME, false)); ConfirmDeviceCredentialBaseFragment.DARK_THEME, false));
@@ -72,7 +66,7 @@ public class ChooseLockSettingsHelperTest {
} }
@Test @Test
public void testLaunchConfirmationActivityInternalAndChallenge() { public void testLaunchConfirmationActivityInternal() {
final Activity activity = Robolectric.setupActivity(Activity.class); final Activity activity = Robolectric.setupActivity(Activity.class);
ChooseLockSettingsHelper.Builder builder = new ChooseLockSettingsHelper.Builder(activity); ChooseLockSettingsHelper.Builder builder = new ChooseLockSettingsHelper.Builder(activity);
@@ -80,7 +74,8 @@ public class ChooseLockSettingsHelperTest {
.setTitle("title") .setTitle("title")
.setHeader("header") .setHeader("header")
.setDescription("description") .setDescription("description")
.setChallenge(10000L) .setForceVerifyPath(true)
.setReturnCredentials(true)
.setUserId(UserHandle.myUserId()); .setUserId(UserHandle.myUserId());
ChooseLockSettingsHelper helper = getChooseLockSettingsHelper(builder); ChooseLockSettingsHelper helper = getChooseLockSettingsHelper(builder);
helper.launch(); helper.launch();
@@ -91,12 +86,10 @@ public class ChooseLockSettingsHelperTest {
assertEquals(new ComponentName("com.android.settings", assertEquals(new ComponentName("com.android.settings",
ConfirmLockPattern.InternalActivity.class.getName()), ConfirmLockPattern.InternalActivity.class.getName()),
startedIntent.getComponent()); startedIntent.getComponent());
assertFalse(startedIntent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_RETURN_CREDENTIALS, false));
assertTrue(startedIntent.getBooleanExtra( assertTrue(startedIntent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false)); ChooseLockSettingsHelper.EXTRA_KEY_RETURN_CREDENTIALS, true));
assertEquals(10000L, startedIntent.getLongExtra( assertTrue(startedIntent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0L)); ChooseLockSettingsHelper.EXTRA_KEY_FORCE_VERIFY, true));
assertFalse((startedIntent.getFlags() & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0); assertFalse((startedIntent.getFlags() & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0);
assertFalse(startedIntent.getBooleanExtra( assertFalse(startedIntent.getBooleanExtra(
ConfirmDeviceCredentialBaseFragment.DARK_THEME, false)); ConfirmDeviceCredentialBaseFragment.DARK_THEME, false));

View File

@@ -19,14 +19,11 @@ package com.android.settings.password;
import static android.content.pm.PackageManager.FEATURE_FACE; import static android.content.pm.PackageManager.FEATURE_FACE;
import static android.content.pm.PackageManager.FEATURE_FINGERPRINT; import static android.content.pm.PackageManager.FEATURE_FINGERPRINT;
import static com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment import static com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS;
.HIDE_DISABLED_PREFS; import static com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY;
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.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE; 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_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; import static com.google.common.truth.Truth.assertThat;
@@ -278,12 +275,8 @@ public final class SetNewPasswordControllerTest {
"All disabled preference should be removed.", "All disabled preference should be removed.",
actualBundle.getBoolean(HIDE_DISABLED_PREFS)); actualBundle.getBoolean(HIDE_DISABLED_PREFS));
assertTrue( assertTrue(
"There must be a fingerprint challenge.", "Fingerprint enroll must request Gatekeeper Password.",
actualBundle.getBoolean(EXTRA_KEY_HAS_CHALLENGE)); actualBundle.getBoolean(EXTRA_KEY_REQUEST_GK_PW));
assertEquals(
"The fingerprint challenge must come from the FingerprintManager",
FINGERPRINT_CHALLENGE,
actualBundle.getLong(EXTRA_KEY_CHALLENGE));
assertTrue( assertTrue(
"The request must be a fingerprint set up request.", "The request must be a fingerprint set up request.",
actualBundle.getBoolean(EXTRA_KEY_FOR_FINGERPRINT)); actualBundle.getBoolean(EXTRA_KEY_FOR_FINGERPRINT));
@@ -302,12 +295,8 @@ public final class SetNewPasswordControllerTest {
"All disabled preference should be removed.", "All disabled preference should be removed.",
actualBundle.getBoolean(HIDE_DISABLED_PREFS)); actualBundle.getBoolean(HIDE_DISABLED_PREFS));
assertTrue( assertTrue(
"There must be a face challenge.", "Face enroll must request Gatekeeper Password",
actualBundle.getBoolean(EXTRA_KEY_HAS_CHALLENGE)); actualBundle.getBoolean(EXTRA_KEY_REQUEST_GK_PW));
assertEquals(
"The face challenge must come from the FaceManager",
FACE_CHALLENGE,
actualBundle.getLong(EXTRA_KEY_CHALLENGE));
assertTrue( assertTrue(
"The request must be a face set up request.", "The request must be a face set up request.",
actualBundle.getBoolean(EXTRA_KEY_FOR_FACE)); actualBundle.getBoolean(EXTRA_KEY_FOR_FACE));