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
diff --git a/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java b/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java
index 4260c7c..c449ff4 100644
--- a/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java
+++ b/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java
@@ -48,16 +48,15 @@
     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 @@
 
         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 @@
     }
 
     @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 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 @@
         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 @@
         if (mUserId != UserHandle.USER_NULL) {
             builder.setUserId(mUserId);
         }
+        mDoNotFinishActivity = true;
         final boolean launched = builder.show();
 
         if (!launched) {