From 667341c343f76e498e8a7bcc670acc60bda93742 Mon Sep 17 00:00:00 2001 From: Wu Ahan Date: Mon, 11 Sep 2023 04:54:42 +0000 Subject: [PATCH] Reland sfps enroll improvement feature with feature provider Prior cl, ag/24720067, was reverted due to platinum failed, this cl fixes the fails (NPE on UDFPS). Bug: 288155127 Bug: 305132251 Test: Manually check on Lynx and Felix Test: atest BiometricsE2eTests:FingerprintEnrollSuccessTest Test: abtd for platinum, see b/305048300#comment14 Change-Id: I90f4ea14853edf03abd8ffe0b7874894eb2d4f81 --- aconfig/Android.bp | 1 + ...iometrics_integration_declarations.aconfig | 9 ++ .../FingerprintEnrollEnrolling.java | 127 ++++++++++++------ .../FingerprintFeatureProvider.java | 27 ++++ .../FingerprintFeatureProviderImpl.java | 36 +++++ .../feature/SfpsEnrollmentFeature.java | 79 +++++++++++ .../feature/SfpsEnrollmentFeatureImpl.java | 91 +++++++++++++ .../settings/overlay/FeatureFactory.kt | 9 ++ .../settings/overlay/FeatureFactoryImpl.kt | 6 + .../testutils/FakeFeatureFactory.java | 8 ++ .../settings/testutils/FakeFeatureFactory.kt | 3 + .../testutils/FakeFeatureFactory.java | 8 ++ 12 files changed, 362 insertions(+), 42 deletions(-) create mode 100644 aconfig/settings_biometrics_integration_declarations.aconfig create mode 100644 src/com/android/settings/biometrics/fingerprint/FingerprintFeatureProvider.java create mode 100644 src/com/android/settings/biometrics/fingerprint/FingerprintFeatureProviderImpl.java create mode 100644 src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeature.java create mode 100644 src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeatureImpl.java diff --git a/aconfig/Android.bp b/aconfig/Android.bp index 6daa90cb1a7..7b571e0b89d 100644 --- a/aconfig/Android.bp +++ b/aconfig/Android.bp @@ -12,6 +12,7 @@ aconfig_declarations { "settings_experience_flag_declarations.aconfig", "settings_onboarding_experience_flag_declarations.aconfig", "settings_telephony_flag_declarations.aconfig", + "settings_biometrics_integration_declarations.aconfig", ], } diff --git a/aconfig/settings_biometrics_integration_declarations.aconfig b/aconfig/settings_biometrics_integration_declarations.aconfig new file mode 100644 index 00000000000..529e126e41c --- /dev/null +++ b/aconfig/settings_biometrics_integration_declarations.aconfig @@ -0,0 +1,9 @@ +package: "com.android.settings.flags" + +flag { + name: "sfps_enroll_refinement" + namespace: "biometrics_integration" + description: "This flag controls whether the sfps pause enrollment feature should be enabled" + bug: "288155127" +} + diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java index be2a948a87b..063d55d3100 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java @@ -68,10 +68,13 @@ import com.android.settings.R; import com.android.settings.biometrics.BiometricEnrollSidecar; import com.android.settings.biometrics.BiometricUtils; import com.android.settings.biometrics.BiometricsEnrollEnrolling; +import com.android.settings.biometrics.fingerprint.feature.SfpsEnrollmentFeature; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; +import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.display.DisplayDensityUtils; import com.airbnb.lottie.LottieAnimationView; +import com.airbnb.lottie.LottieComposition; import com.airbnb.lottie.LottieCompositionFactory; import com.airbnb.lottie.LottieProperty; import com.airbnb.lottie.model.KeyPath; @@ -84,6 +87,7 @@ import com.google.android.setupdesign.template.HeaderMixin; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.List; +import java.util.function.Function; /** * Activity which handles the actual enrolling for fingerprint. @@ -99,27 +103,22 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { private static final int PROGRESS_BAR_MAX = 10000; - private static final int STAGE_UNKNOWN = -1; + public static final int STAGE_UNKNOWN = -1; private static final int STAGE_CENTER = 0; private static final int STAGE_GUIDED = 1; private static final int STAGE_FINGERTIP = 2; private static final int STAGE_LEFT_EDGE = 3; private static final int STAGE_RIGHT_EDGE = 4; - @VisibleForTesting - protected static final int SFPS_STAGE_NO_ANIMATION = 0; + public static final int SFPS_STAGE_NO_ANIMATION = 0; - @VisibleForTesting - protected static final int SFPS_STAGE_CENTER = 1; + public static final int SFPS_STAGE_CENTER = 1; - @VisibleForTesting - protected static final int SFPS_STAGE_FINGERTIP = 2; + public static final int SFPS_STAGE_FINGERTIP = 2; - @VisibleForTesting - protected static final int SFPS_STAGE_LEFT_EDGE = 3; + public static final int SFPS_STAGE_LEFT_EDGE = 3; - @VisibleForTesting - protected static final int SFPS_STAGE_RIGHT_EDGE = 4; + public static final int SFPS_STAGE_RIGHT_EDGE = 4; @IntDef({STAGE_UNKNOWN, STAGE_CENTER, STAGE_GUIDED, STAGE_FINGERTIP, STAGE_LEFT_EDGE, STAGE_RIGHT_EDGE}) @@ -196,6 +195,9 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { private OrientationEventListener mOrientationEventListener; private int mPreviousRotation = 0; + @NonNull + private SfpsEnrollmentFeature mSfpsEnrollmentFeature = new EmptySfpsEnrollmentFeature(); + @VisibleForTesting protected boolean shouldShowLottie() { DisplayDensityUtils displayDensity = new DisplayDensityUtils(getApplicationContext()); @@ -244,6 +246,8 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { setContentView(layout); setDescriptionText(R.string.security_settings_udfps_enroll_start_message); } else if (mCanAssumeSfps) { + mSfpsEnrollmentFeature = FeatureFactory.getFeatureFactory() + .getFingerprintFeatureProvider().getSfpsEnrollmentFeature(); setContentView(R.layout.sfps_enroll_enrolling); setHelpAnimation(); } else { @@ -599,7 +603,8 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { } switch (getCurrentSfpsStage()) { case SFPS_STAGE_NO_ANIMATION: - setHeaderText(R.string.security_settings_fingerprint_enroll_repeat_title); + setHeaderText(mSfpsEnrollmentFeature + .getFeaturedStageHeaderResource(SFPS_STAGE_NO_ANIMATION)); if (!mHaveShownSfpsNoAnimationLottie && mIllustrationLottie != null) { mHaveShownSfpsNoAnimationLottie = true; mIllustrationLottie.setContentDescription( @@ -608,39 +613,48 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { 0 ) ); - configureEnrollmentStage(R.raw.sfps_lottie_no_animation); + configureEnrollmentStage(mSfpsEnrollmentFeature + .getSfpsEnrollLottiePerStage(SFPS_STAGE_NO_ANIMATION)); } break; case SFPS_STAGE_CENTER: - setHeaderText(R.string.security_settings_sfps_enroll_finger_center_title); + setHeaderText(mSfpsEnrollmentFeature + .getFeaturedStageHeaderResource(SFPS_STAGE_CENTER)); if (!mHaveShownSfpsCenterLottie && mIllustrationLottie != null) { mHaveShownSfpsCenterLottie = true; - configureEnrollmentStage(R.raw.sfps_lottie_pad_center); + configureEnrollmentStage(mSfpsEnrollmentFeature + .getSfpsEnrollLottiePerStage(SFPS_STAGE_CENTER)); } break; case SFPS_STAGE_FINGERTIP: - setHeaderText(R.string.security_settings_sfps_enroll_fingertip_title); + setHeaderText(mSfpsEnrollmentFeature + .getFeaturedStageHeaderResource(SFPS_STAGE_FINGERTIP)); if (!mHaveShownSfpsTipLottie && mIllustrationLottie != null) { mHaveShownSfpsTipLottie = true; - configureEnrollmentStage(R.raw.sfps_lottie_tip); + configureEnrollmentStage(mSfpsEnrollmentFeature + .getSfpsEnrollLottiePerStage(SFPS_STAGE_FINGERTIP)); } break; case SFPS_STAGE_LEFT_EDGE: - setHeaderText(R.string.security_settings_sfps_enroll_left_edge_title); + setHeaderText(mSfpsEnrollmentFeature + .getFeaturedStageHeaderResource(SFPS_STAGE_LEFT_EDGE)); if (!mHaveShownSfpsLeftEdgeLottie && mIllustrationLottie != null) { mHaveShownSfpsLeftEdgeLottie = true; - configureEnrollmentStage(R.raw.sfps_lottie_left_edge); + configureEnrollmentStage(mSfpsEnrollmentFeature + .getSfpsEnrollLottiePerStage(SFPS_STAGE_LEFT_EDGE)); } break; case SFPS_STAGE_RIGHT_EDGE: - setHeaderText(R.string.security_settings_sfps_enroll_right_edge_title); + setHeaderText(mSfpsEnrollmentFeature + .getFeaturedStageHeaderResource(SFPS_STAGE_RIGHT_EDGE)); if (!mHaveShownSfpsRightEdgeLottie && mIllustrationLottie != null) { mHaveShownSfpsRightEdgeLottie = true; - configureEnrollmentStage(R.raw.sfps_lottie_right_edge); + configureEnrollmentStage(mSfpsEnrollmentFeature + .getSfpsEnrollLottiePerStage(SFPS_STAGE_RIGHT_EDGE)); } break; @@ -665,11 +679,16 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { setDescriptionText(""); } LottieCompositionFactory.fromRawRes(this, lottie) - .addListener((c) -> { - mIllustrationLottie.setComposition(c); - mIllustrationLottie.setVisibility(View.VISIBLE); - mIllustrationLottie.playAnimation(); - }); + .addListener((c) -> onLottieComposition(mIllustrationLottie, c)); + } + + private void onLottieComposition(LottieAnimationView view, LottieComposition composition) { + if (view == null || composition == null) { + return; + } + view.setComposition(composition); + view.setVisibility(View.VISIBLE); + view.playAnimation(); } @EnrollStage @@ -699,17 +718,8 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { } final int progressSteps = mSidecar.getEnrollmentSteps() - mSidecar.getEnrollmentRemaining(); - if (progressSteps < getStageThresholdSteps(0)) { - return SFPS_STAGE_NO_ANIMATION; - } else if (progressSteps < getStageThresholdSteps(1)) { - return SFPS_STAGE_CENTER; - } else if (progressSteps < getStageThresholdSteps(2)) { - return SFPS_STAGE_FINGERTIP; - } else if (progressSteps < getStageThresholdSteps(3)) { - return SFPS_STAGE_LEFT_EDGE; - } else { - return SFPS_STAGE_RIGHT_EDGE; - } + return mSfpsEnrollmentFeature + .getCurrentSfpsEnrollStage(progressSteps, this::getStageThresholdSteps); } private boolean isStageHalfCompleted() { @@ -740,22 +750,31 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { Log.w(TAG, "getStageThresholdSteps: Enrollment not started yet"); return 1; } - return Math.round(mSidecar.getEnrollmentSteps() - * mFingerprintManager.getEnrollStageThreshold(index)); + final float threshold = mCanAssumeSfps + ? mSfpsEnrollmentFeature.getEnrollStageThreshold(this, index) + : mFingerprintManager.getEnrollStageThreshold(index); + return Math.round(mSidecar.getEnrollmentSteps() * threshold); } @Override public void onEnrollmentHelp(int helpMsgId, CharSequence helpString) { - if (!TextUtils.isEmpty(helpString)) { + final CharSequence featuredString = mCanAssumeSfps + ? mSfpsEnrollmentFeature.getFeaturedVendorString(this, helpMsgId, helpString) + : helpString; + + if (!TextUtils.isEmpty(featuredString)) { if (!(mCanAssumeUdfps || mCanAssumeSfps)) { mErrorText.removeCallbacks(mTouchAgainRunnable); } - showError(helpString); + showError(featuredString); if (mUdfpsEnrollHelper != null) mUdfpsEnrollHelper.onEnrollmentHelp(); } dismissTouchDialogIfSfps(); + if (mCanAssumeSfps) { + mSfpsEnrollmentFeature.handleOnEnrollmentHelp(helpMsgId, featuredString, () -> this); + } } @Override @@ -1170,4 +1189,28 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { return SettingsEnums.DIALOG_FINGERPRINT_ICON_TOUCH; } } -} \ No newline at end of file + + private static class EmptySfpsEnrollmentFeature implements SfpsEnrollmentFeature { + private final String exceptionStr = "Assume sfps but no SfpsEnrollmentFeature impl."; + + @Override + public int getCurrentSfpsEnrollStage(int progressSteps, Function mapper) { + throw new IllegalStateException(exceptionStr); + } + + @Override + public int getFeaturedStageHeaderResource(int stage) { + throw new IllegalStateException(exceptionStr); + } + + @Override + public int getSfpsEnrollLottiePerStage(int stage) { + throw new IllegalStateException(exceptionStr); + } + + @Override + public float getEnrollStageThreshold(@NonNull Context context, int index) { + throw new IllegalStateException(exceptionStr); + } + } +} diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintFeatureProvider.java b/src/com/android/settings/biometrics/fingerprint/FingerprintFeatureProvider.java new file mode 100644 index 00000000000..906f95a57a9 --- /dev/null +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintFeatureProvider.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2023 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; + +import com.android.settings.biometrics.fingerprint.feature.SfpsEnrollmentFeature; + +public interface FingerprintFeatureProvider { + /** + * Gets the feature implementation of SFPS enrollment. + * @return the feature implementation + */ + SfpsEnrollmentFeature getSfpsEnrollmentFeature(); +} diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintFeatureProviderImpl.java b/src/com/android/settings/biometrics/fingerprint/FingerprintFeatureProviderImpl.java new file mode 100644 index 00000000000..9745ca3fd7e --- /dev/null +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintFeatureProviderImpl.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2023 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; + +import androidx.annotation.Nullable; + +import com.android.settings.biometrics.fingerprint.feature.SfpsEnrollmentFeature; +import com.android.settings.biometrics.fingerprint.feature.SfpsEnrollmentFeatureImpl; + +public class FingerprintFeatureProviderImpl implements FingerprintFeatureProvider { + + @Nullable + private SfpsEnrollmentFeature mSfpsEnrollmentFeatureImpl = null; + + @Override + public SfpsEnrollmentFeature getSfpsEnrollmentFeature() { + if (mSfpsEnrollmentFeatureImpl == null) { + mSfpsEnrollmentFeatureImpl = new SfpsEnrollmentFeatureImpl(); + } + return mSfpsEnrollmentFeatureImpl; + } +} diff --git a/src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeature.java b/src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeature.java new file mode 100644 index 00000000000..a1a18e5652e --- /dev/null +++ b/src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeature.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2023 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.content.Context; + +import androidx.annotation.NonNull; + +import com.android.settings.biometrics.fingerprint.FingerprintEnrollEnrolling; + +import java.util.function.Function; +import java.util.function.Supplier; + +public interface SfpsEnrollmentFeature { + + /** + * Gets current SFPS enrollment stage. + * @param progressSteps current step of enrollment + * @param mapper a mapper to map each stage to its threshold + * @return current enrollment stage + */ + int getCurrentSfpsEnrollStage(int progressSteps, Function mapper); + + /** + * Gets the vendor string by feature. + * @param context Context + * @param id An integer identifying the error message + * @param msg A human-readable string that can be shown in UI + * @return A human-readable string of specific feature + */ + default CharSequence getFeaturedVendorString(Context context, int id, CharSequence msg) { + return msg; + } + + /** + * Gets the stage header string by feature. + * @param stage the specific stage + * @return the resource id of the header text of the specific stage + */ + int getFeaturedStageHeaderResource(int stage); + + /** + * Gets the enrollment lottie resource id per stage + * @param stage current enrollment stage + * @return enrollment lottie resource id + */ + int getSfpsEnrollLottiePerStage(int stage); + + /** + * Handles extra stuffs on receiving enrollment help. + * @param helpMsgId help message id + * @param helpString help message + * @param enrollingSupplier supplier of enrolling context + */ + default void handleOnEnrollmentHelp(int helpMsgId, CharSequence helpString, + Supplier enrollingSupplier) {} + + /** + * Gets the fingerprint enrollment threshold. + * @param context context + * @param index the enrollment stage index + * @return threshold + */ + float getEnrollStageThreshold(@NonNull Context context, int index); +} diff --git a/src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeatureImpl.java b/src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeatureImpl.java new file mode 100644 index 00000000000..5a975373c0c --- /dev/null +++ b/src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeatureImpl.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2023 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 static com.android.settings.biometrics.fingerprint.FingerprintEnrollEnrolling.SFPS_STAGE_CENTER; +import static com.android.settings.biometrics.fingerprint.FingerprintEnrollEnrolling.SFPS_STAGE_FINGERTIP; +import static com.android.settings.biometrics.fingerprint.FingerprintEnrollEnrolling.SFPS_STAGE_LEFT_EDGE; +import static com.android.settings.biometrics.fingerprint.FingerprintEnrollEnrolling.SFPS_STAGE_NO_ANIMATION; +import static com.android.settings.biometrics.fingerprint.FingerprintEnrollEnrolling.SFPS_STAGE_RIGHT_EDGE; +import static com.android.settings.biometrics.fingerprint.FingerprintEnrollEnrolling.STAGE_UNKNOWN; + +import android.content.Context; +import android.hardware.fingerprint.FingerprintManager; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.android.settings.R; + +import java.util.function.Function; + +public class SfpsEnrollmentFeatureImpl implements SfpsEnrollmentFeature { + + @Nullable + private FingerprintManager mFingerprintManager = null; + + @Override + public int getCurrentSfpsEnrollStage(int progressSteps, Function mapper) { + if (mapper == null) { + return STAGE_UNKNOWN; + } + if (progressSteps < mapper.apply(0)) { + return SFPS_STAGE_NO_ANIMATION; + } else if (progressSteps < mapper.apply(1)) { + return SFPS_STAGE_CENTER; + } else if (progressSteps < mapper.apply(2)) { + return SFPS_STAGE_FINGERTIP; + } else if (progressSteps < mapper.apply(3)) { + return SFPS_STAGE_LEFT_EDGE; + } else { + return SFPS_STAGE_RIGHT_EDGE; + } + } + + @Override + public int getFeaturedStageHeaderResource(int stage) { + return switch (stage) { + case SFPS_STAGE_NO_ANIMATION + -> R.string.security_settings_fingerprint_enroll_repeat_title; + case SFPS_STAGE_CENTER -> R.string.security_settings_sfps_enroll_finger_center_title; + case SFPS_STAGE_FINGERTIP -> R.string.security_settings_sfps_enroll_fingertip_title; + case SFPS_STAGE_LEFT_EDGE -> R.string.security_settings_sfps_enroll_left_edge_title; + case SFPS_STAGE_RIGHT_EDGE -> R.string.security_settings_sfps_enroll_right_edge_title; + default -> throw new IllegalArgumentException("Invalid stage: " + stage); + }; + } + + @Override + public int getSfpsEnrollLottiePerStage(int stage) { + return switch (stage) { + case SFPS_STAGE_NO_ANIMATION -> R.raw.sfps_lottie_no_animation; + case SFPS_STAGE_CENTER -> R.raw.sfps_lottie_pad_center; + case SFPS_STAGE_FINGERTIP -> R.raw.sfps_lottie_tip; + case SFPS_STAGE_LEFT_EDGE -> R.raw.sfps_lottie_left_edge; + case SFPS_STAGE_RIGHT_EDGE -> R.raw.sfps_lottie_right_edge; + default -> throw new IllegalArgumentException("Invalid stage: " + stage); + }; + } + + @Override + public float getEnrollStageThreshold(@NonNull Context context, int index) { + if (mFingerprintManager == null) { + mFingerprintManager = context.getSystemService(FingerprintManager.class); + } + return mFingerprintManager.getEnrollStageThreshold(index); + } +} diff --git a/src/com/android/settings/overlay/FeatureFactory.kt b/src/com/android/settings/overlay/FeatureFactory.kt index 7645076f288..ac689d91687 100644 --- a/src/com/android/settings/overlay/FeatureFactory.kt +++ b/src/com/android/settings/overlay/FeatureFactory.kt @@ -21,6 +21,7 @@ import com.android.settings.accessibility.AccessibilitySearchFeatureProvider import com.android.settings.accounts.AccountFeatureProvider import com.android.settings.applications.ApplicationFeatureProvider import com.android.settings.biometrics.face.FaceFeatureProvider +import com.android.settings.biometrics.fingerprint.FingerprintFeatureProvider import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider import com.android.settings.bluetooth.BluetoothFeatureProvider import com.android.settings.connecteddevice.fastpair.FastPairFeatureProvider @@ -104,8 +105,16 @@ abstract class FeatureFactory { */ abstract val bluetoothFeatureProvider: BluetoothFeatureProvider + /** + * Retrieves implementation for Face feature. + */ abstract val faceFeatureProvider: FaceFeatureProvider + /** + * Retrieves implementation for Fingerprint feature. + */ + abstract val fingerprintFeatureProvider: FingerprintFeatureProvider + /** * Gets implementation for Biometrics repository provider. */ diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.kt b/src/com/android/settings/overlay/FeatureFactoryImpl.kt index 0afe9f473be..7f991b7b7d8 100644 --- a/src/com/android/settings/overlay/FeatureFactoryImpl.kt +++ b/src/com/android/settings/overlay/FeatureFactoryImpl.kt @@ -29,6 +29,8 @@ import com.android.settings.accounts.AccountFeatureProviderImpl import com.android.settings.applications.ApplicationFeatureProviderImpl import com.android.settings.biometrics.face.FaceFeatureProvider import com.android.settings.biometrics.face.FaceFeatureProviderImpl +import com.android.settings.biometrics.fingerprint.FingerprintFeatureProvider +import com.android.settings.biometrics.fingerprint.FingerprintFeatureProviderImpl import com.android.settings.biometrics2.factory.BiometricsRepositoryProviderImpl import com.android.settings.bluetooth.BluetoothFeatureProvider import com.android.settings.bluetooth.BluetoothFeatureProviderImpl @@ -145,6 +147,10 @@ open class FeatureFactoryImpl : FeatureFactory() { override val faceFeatureProvider: FaceFeatureProvider by lazy { FaceFeatureProviderImpl() } + override val fingerprintFeatureProvider: FingerprintFeatureProvider by lazy { + FingerprintFeatureProviderImpl() + } + override val biometricsRepositoryProvider by lazy { BiometricsRepositoryProviderImpl() } override val wifiTrackerLibProvider: WifiTrackerLibProvider by lazy { diff --git a/tests/robotests/testutils/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/testutils/com/android/settings/testutils/FakeFeatureFactory.java index 52a5f24cf44..9156cae5d8f 100644 --- a/tests/robotests/testutils/com/android/settings/testutils/FakeFeatureFactory.java +++ b/tests/robotests/testutils/com/android/settings/testutils/FakeFeatureFactory.java @@ -24,6 +24,7 @@ import com.android.settings.accessibility.AccessibilitySearchFeatureProvider; import com.android.settings.accounts.AccountFeatureProvider; import com.android.settings.applications.ApplicationFeatureProvider; import com.android.settings.biometrics.face.FaceFeatureProvider; +import com.android.settings.biometrics.fingerprint.FingerprintFeatureProvider; import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider; import com.android.settings.bluetooth.BluetoothFeatureProvider; import com.android.settings.connecteddevice.fastpair.FastPairFeatureProvider; @@ -80,6 +81,7 @@ public class FakeFeatureFactory extends FeatureFactory { public final AccountFeatureProvider mAccountFeatureProvider; public final BluetoothFeatureProvider mBluetoothFeatureProvider; public final FaceFeatureProvider mFaceFeatureProvider; + public final FingerprintFeatureProvider mFingerprintFeatureProvider; public final BiometricsRepositoryProvider mBiometricsRepositoryProvider; public PanelFeatureProvider panelFeatureProvider; @@ -132,6 +134,7 @@ public class FakeFeatureFactory extends FeatureFactory { panelFeatureProvider = mock(PanelFeatureProvider.class); mBluetoothFeatureProvider = mock(BluetoothFeatureProvider.class); mFaceFeatureProvider = mock(FaceFeatureProvider.class); + mFingerprintFeatureProvider = mock(FingerprintFeatureProvider.class); mBiometricsRepositoryProvider = mock(BiometricsRepositoryProvider.class); wifiTrackerLibProvider = mock(WifiTrackerLibProvider.class); securitySettingsFeatureProvider = mock(SecuritySettingsFeatureProvider.class); @@ -256,6 +259,11 @@ public class FakeFeatureFactory extends FeatureFactory { return mFaceFeatureProvider; } + @Override + public FingerprintFeatureProvider getFingerprintFeatureProvider() { + return mFingerprintFeatureProvider; + } + @Override public BiometricsRepositoryProvider getBiometricsRepositoryProvider() { return mBiometricsRepositoryProvider; diff --git a/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt b/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt index 95f25adc999..54299eb3802 100644 --- a/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt +++ b/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt @@ -22,6 +22,7 @@ import com.android.settings.accessibility.AccessibilitySearchFeatureProvider import com.android.settings.accounts.AccountFeatureProvider import com.android.settings.applications.ApplicationFeatureProvider import com.android.settings.biometrics.face.FaceFeatureProvider +import com.android.settings.biometrics.fingerprint.FingerprintFeatureProvider import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider import com.android.settings.bluetooth.BluetoothFeatureProvider import com.android.settings.connecteddevice.fastpair.FastPairFeatureProvider @@ -120,6 +121,8 @@ class FakeFeatureFactory : FeatureFactory() { get() = TODO("Not yet implemented") override val faceFeatureProvider: FaceFeatureProvider get() = TODO("Not yet implemented") + override val fingerprintFeatureProvider: FingerprintFeatureProvider + get() = TODO("Not yet implemented") override val biometricsRepositoryProvider: BiometricsRepositoryProvider get() = TODO("Not yet implemented") override val wifiTrackerLibProvider: WifiTrackerLibProvider diff --git a/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java index a3a92a30b70..b5062a06c56 100644 --- a/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java +++ b/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java @@ -24,6 +24,7 @@ import com.android.settings.accessibility.AccessibilitySearchFeatureProvider; import com.android.settings.accounts.AccountFeatureProvider; import com.android.settings.applications.ApplicationFeatureProvider; import com.android.settings.biometrics.face.FaceFeatureProvider; +import com.android.settings.biometrics.fingerprint.FingerprintFeatureProvider; import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider; import com.android.settings.bluetooth.BluetoothFeatureProvider; import com.android.settings.connecteddevice.fastpair.FastPairFeatureProvider; @@ -79,6 +80,7 @@ public class FakeFeatureFactory extends FeatureFactory { public final AccountFeatureProvider mAccountFeatureProvider; public final BluetoothFeatureProvider mBluetoothFeatureProvider; public final FaceFeatureProvider mFaceFeatureProvider; + public final FingerprintFeatureProvider mFingerprintFeatureProvider; public final BiometricsRepositoryProvider mBiometricsRepositoryProvider; public PanelFeatureProvider panelFeatureProvider; @@ -131,6 +133,7 @@ public class FakeFeatureFactory extends FeatureFactory { panelFeatureProvider = mock(PanelFeatureProvider.class); mBluetoothFeatureProvider = mock(BluetoothFeatureProvider.class); mFaceFeatureProvider = mock(FaceFeatureProvider.class); + mFingerprintFeatureProvider = mock(FingerprintFeatureProvider.class); mBiometricsRepositoryProvider = mock(BiometricsRepositoryProvider.class); wifiTrackerLibProvider = mock(WifiTrackerLibProvider.class); securitySettingsFeatureProvider = mock(SecuritySettingsFeatureProvider.class); @@ -255,6 +258,11 @@ public class FakeFeatureFactory extends FeatureFactory { return mFaceFeatureProvider; } + @Override + public FingerprintFeatureProvider getFingerprintFeatureProvider() { + return mFingerprintFeatureProvider; + } + @Override public BiometricsRepositoryProvider getBiometricsRepositoryProvider() { return mBiometricsRepositoryProvider;