Fix several challenge paths

1) Combined settings page should finish() when losing foreground
   (but not if fingerprint or face settings are launched from it)
2) Challenge should be generated when entering FaceSettings or
   FingerprintSettings each time. This allows us to leave the existing
   revokeChallenge paths in FaceSettings and FingerprintSettings.

Fixes: 186257202
Test: Manual

Change-Id: I1b6452f787279001a71628f220c01fcb86b88f3d
This commit is contained in:
Kevin Chyn
2021-04-28 12:37:55 -07:00
parent 290298d58d
commit 1f0cd17e3e

View File

@@ -48,16 +48,15 @@ public abstract class BiometricsSettingsBase extends DashboardFragment {
private static final int CHOOSE_LOCK_REQUEST = 2002;
private static final String SAVE_STATE_CONFIRM_CREDETIAL = "confirm_credential";
private static final String DO_NOT_FINISH_ACTIVITY = "do_not_finish_activity";
protected int mUserId;
protected long mFaceChallenge;
protected long mFingerprintChallenge;
protected int mFaceSensorId;
protected int mFingerprintSensorId;
protected long mGkPwHandle;
private boolean mConfirmCredential;
@Nullable private FaceManager mFaceManager;
@Nullable private FingerprintManager mFingerprintManager;
// Do not finish() if choosing/confirming credential, or showing fp/face settings
private boolean mDoNotFinishActivity;
@Override
public void onAttach(Context context) {
@@ -78,6 +77,7 @@ public abstract class BiometricsSettingsBase extends DashboardFragment {
if (savedInstanceState != null) {
mConfirmCredential = savedInstanceState.getBoolean(SAVE_STATE_CONFIRM_CREDETIAL);
mDoNotFinishActivity = savedInstanceState.getBoolean(DO_NOT_FINISH_ACTIVITY);
if (savedInstanceState.containsKey(
ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE)) {
mGkPwHandle = savedInstanceState.getLong(
@@ -92,31 +92,47 @@ public abstract class BiometricsSettingsBase extends DashboardFragment {
}
@Override
public void onDestroy() {
super.onDestroy();
if (getActivity().isFinishing()) {
mFaceManager.revokeChallenge(mFaceSensorId, mUserId, mFaceChallenge);
mFingerprintManager.revokeChallenge(mUserId, mFingerprintChallenge);
public void onResume() {
super.onResume();
if (!mConfirmCredential) {
mDoNotFinishActivity = false;
}
}
@Override
public void onStop() {
super.onStop();
if (!getActivity().isChangingConfigurations() && !mDoNotFinishActivity) {
BiometricUtils.removeGatekeeperPasswordHandle(getActivity(), mGkPwHandle);
getActivity().finish();
}
}
@Override
public boolean onPreferenceTreeClick(Preference preference) {
final String key = preference.getKey();
// Generate challenge (and request LSS to create a HAT) each time the preference is clicked,
// since FingerprintSettings and FaceSettings revoke the challenge when finishing.
if (getFacePreferenceKey().equals(key)) {
final byte[] token = BiometricUtils.requestGatekeeperHat(getActivity(), mGkPwHandle,
mUserId, mFaceChallenge);
final Bundle extras = preference.getExtras();
extras.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
extras.putInt(BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, mFaceSensorId);
extras.putLong(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, mFaceChallenge);
mDoNotFinishActivity = true;
mFaceManager.generateChallenge((sensorId, challenge) -> {
final byte[] token = BiometricUtils.requestGatekeeperHat(getActivity(), mGkPwHandle,
mUserId, challenge);
final Bundle extras = preference.getExtras();
extras.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
extras.putInt(BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, sensorId);
extras.putLong(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, challenge);
});
} else if (getFingerprintPreferenceKey().equals(key)) {
final byte[] token = BiometricUtils.requestGatekeeperHat(getActivity(), mGkPwHandle,
mUserId, mFingerprintChallenge);
final Bundle extras = preference.getExtras();
extras.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
extras.putLong(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, mFingerprintChallenge);
mDoNotFinishActivity = true;
mFingerprintManager.generateChallenge(mUserId, (sensorId, challenge) -> {
final byte[] token = BiometricUtils.requestGatekeeperHat(getActivity(), mGkPwHandle,
mUserId, challenge);
final Bundle extras = preference.getExtras();
extras.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
extras.putLong(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, challenge);
});
}
return super.onPreferenceTreeClick(preference);
}
@@ -125,6 +141,7 @@ public abstract class BiometricsSettingsBase extends DashboardFragment {
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(SAVE_STATE_CONFIRM_CREDETIAL, mConfirmCredential);
outState.putBoolean(DO_NOT_FINISH_ACTIVITY, mDoNotFinishActivity);
if (mGkPwHandle != 0L) {
outState.putLong(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, mGkPwHandle);
}
@@ -135,17 +152,10 @@ public abstract class BiometricsSettingsBase extends DashboardFragment {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CONFIRM_REQUEST || requestCode == CHOOSE_LOCK_REQUEST) {
mConfirmCredential = false;
mDoNotFinishActivity = false;
if (resultCode == RESULT_FINISHED || resultCode == RESULT_OK) {
if (data != null && BiometricUtils.containsGatekeeperPasswordHandle(data)) {
if (BiometricUtils.containsGatekeeperPasswordHandle(data)) {
mGkPwHandle = BiometricUtils.getGatekeeperPasswordHandle(data);
mFaceManager.generateChallenge((sensorId, challenge) -> {
mFaceSensorId = sensorId;
mFaceChallenge = challenge;
});
mFingerprintManager.generateChallenge(mUserId, (sensorId, challenge) -> {
mFingerprintSensorId = sensorId;
mFingerprintChallenge = challenge;
});
} else {
Log.d(getLogTag(), "Data null or GK PW missing.");
finish();
@@ -178,6 +188,7 @@ public abstract class BiometricsSettingsBase extends DashboardFragment {
if (mUserId != UserHandle.USER_NULL) {
builder.setUserId(mUserId);
}
mDoNotFinishActivity = true;
final boolean launched = builder.show();
if (!launched) {