From 1f0cd17e3e40827545c74040cb24b31ada65d0eb Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Wed, 28 Apr 2021 12:37:55 -0700 Subject: [PATCH] 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 --- .../combination/BiometricsSettingsBase.java | 69 +++++++++++-------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java b/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java index 4260c7c9130..c449ff4bfce 100644 --- a/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java +++ b/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java @@ -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) {