From 54b7df1b0453a75d8593be2584e05bf13178b72f Mon Sep 17 00:00:00 2001 From: Milton Wu Date: Tue, 11 Feb 2025 12:13:48 +0000 Subject: [PATCH] Support invoker in FingerprintSettings Support running invoker after ChallengeGenerated in FingerprintSettings. Bug: 384399941 Flag: EXEMPT support interface, flag only used in impl part Test: atest FingerprintSettingsFragmentTest Change-Id: I0c01ae163a492a31c07e00c0a93829c9bfc12b91 --- .../FingerprintFeatureProvider.java | 9 +++++ .../fingerprint/FingerprintSettings.java | 33 +++++++++++++++++++ .../feature/ChallengeGeneratedInvoker.kt | 27 +++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 src/com/android/settings/biometrics/fingerprint/feature/ChallengeGeneratedInvoker.kt diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintFeatureProvider.java b/src/com/android/settings/biometrics/fingerprint/FingerprintFeatureProvider.java index aa80fb369d1..a029c2c4d85 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintFeatureProvider.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintFeatureProvider.java @@ -23,10 +23,14 @@ import android.os.Bundle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.settings.biometrics.fingerprint.feature.ChallengeGeneratedInvoker; import com.android.settings.biometrics.fingerprint.feature.FingerprintExtPreferencesProvider; import com.android.settings.biometrics.fingerprint.feature.SfpsEnrollmentFeature; import com.android.settings.biometrics.fingerprint.feature.SfpsRestToUnlockFeature; +import java.util.Collections; +import java.util.List; + public interface FingerprintFeatureProvider { /** * Gets the feature implementation of SFPS enrollment. @@ -80,4 +84,9 @@ public interface FingerprintFeatureProvider { default FingerprintSettingsFeatureProvider getFingerprintSettingsFeatureProvider() { return FingerprintSettingsFeatureProvider.getInstance(); } + + @NonNull + default List getChallengeGeneratedInvokers() { + return Collections.emptyList(); + } } diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java index 9531f73ebd0..6773fdcf1ce 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java @@ -86,6 +86,7 @@ import com.android.settings.biometrics.BiometricEnrollBase; import com.android.settings.biometrics.BiometricUtils; import com.android.settings.biometrics.GatekeeperPasswordProvider; import com.android.settings.biometrics.IdentityCheckBiometricErrorDialog; +import com.android.settings.biometrics.fingerprint.feature.ChallengeGeneratedInvoker; import com.android.settings.biometrics.fingerprint.feature.FingerprintExtPreferencesProvider; import com.android.settings.biometrics.fingerprint.feature.PrimarySwitchIntentPreference; import com.android.settings.core.SettingsBaseActivity; @@ -267,6 +268,7 @@ public class FingerprintSettings extends SubSettings { private static final String KEY_HAS_FIRST_ENROLLED = "has_first_enrolled"; private static final String KEY_IS_ENROLLING = "is_enrolled"; private static final String KEY_IS_LAUNCHING_EXT_PREF = "is_launching_ext_pref"; + private static final String KEY_HAS_RUN_CHALLENGE_INVOKER = "has_run_challenge_invoker"; @VisibleForTesting static final String KEY_REQUIRE_SCREEN_ON_TO_AUTH = "security_settings_require_screen_on_to_auth"; @@ -334,6 +336,8 @@ public class FingerprintSettings extends SubSettings { @NonNull private String mLaunchedExtPrefKey = ""; /** key list for changing visibility */ @NonNull private final ArrayList mExtPrefKeys = new ArrayList<>(); + /** Use to make sure ChallengeGeneratedInvokers have been run */ + private boolean mHasRunChallengeInvoker = false; private long mChallenge; @@ -595,6 +599,8 @@ public class FingerprintSettings extends SubSettings { mIsEnrolling = savedInstanceState.getBoolean(KEY_IS_ENROLLING, mIsEnrolling); mLaunchedExtPrefKey = savedInstanceState.getString( KEY_IS_LAUNCHING_EXT_PREF, mLaunchedExtPrefKey); + mHasRunChallengeInvoker = savedInstanceState.getBoolean( + KEY_HAS_RUN_CHALLENGE_INVOKER, /* defaultValue= */ false); mHasFirstEnrolled = savedInstanceState.getBoolean(KEY_HAS_FIRST_ENROLLED, mHasFirstEnrolled); mBiometricsAuthenticationRequested = savedInstanceState.getBoolean( @@ -1113,6 +1119,7 @@ public class FingerprintSettings extends SubSettings { outState.putBoolean(KEY_IS_ENROLLING, mIsEnrolling); outState.putString(KEY_IS_LAUNCHING_EXT_PREF, mLaunchedExtPrefKey); outState.putBoolean(KEY_HAS_FIRST_ENROLLED, mHasFirstEnrolled); + outState.putBoolean(KEY_HAS_RUN_CHALLENGE_INVOKER, mHasRunChallengeInvoker); outState.putBoolean(KEY_BIOMETRICS_AUTHENTICATION_REQUESTED, mBiometricsAuthenticationRequested); } @@ -1265,6 +1272,7 @@ public class FingerprintSettings extends SubSettings { if (requestCode == CONFIRM_REQUEST || requestCode == CHOOSE_LOCK_GENERIC_REQUEST) { mLaunchedConfirm = false; if (resultCode == RESULT_FINISHED || resultCode == RESULT_OK) { + runChallengeGeneratedInvokers(); if (BiometricUtils.containsGatekeeperPasswordHandle(data)) { if (!mHasFirstEnrolled && !mIsEnrolling) { final Activity activity = getActivity(); @@ -1399,6 +1407,31 @@ public class FingerprintSettings extends SubSettings { } } + private void runChallengeGeneratedInvokers() { + if (mHasRunChallengeInvoker) { + return; + } + mHasRunChallengeInvoker = true; + + List invokers = FeatureFactory.getFeatureFactory() + .getFingerprintFeatureProvider().getChallengeGeneratedInvokers(); + Log.d(TAG, "Num of ChallengeGeneratedInvoker: " + invokers.size()); + for (ChallengeGeneratedInvoker invoker: invokers) { + Bundle bundle = getIntent().getBundleExtra(invoker.getIntentKeyForBundle()); + if (bundle == null) { + continue; + } + + long startTime = System.currentTimeMillis(); + boolean result = invoker.invoke(this, bundle); + Log.d(TAG, "Invoker for " + invoker.getIntentKeyForBundle() + " run " + + (System.currentTimeMillis() - startTime) + "ms, result: " + result); + + // We shall only have at most one invoker for each launching + return; + } + } + @Override public void onDestroy() { super.onDestroy(); diff --git a/src/com/android/settings/biometrics/fingerprint/feature/ChallengeGeneratedInvoker.kt b/src/com/android/settings/biometrics/fingerprint/feature/ChallengeGeneratedInvoker.kt new file mode 100644 index 00000000000..26ac6daf0a3 --- /dev/null +++ b/src/com/android/settings/biometrics/fingerprint/feature/ChallengeGeneratedInvoker.kt @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2025 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.fingerprint.feature + +import android.os.Bundle +import androidx.preference.PreferenceFragmentCompat + +interface ChallengeGeneratedInvoker { + + val intentKeyForBundle: String + + fun invoke(fragment: PreferenceFragmentCompat, bundle: Bundle): Boolean +}