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
This commit is contained in:
@@ -12,6 +12,7 @@ aconfig_declarations {
|
|||||||
"settings_experience_flag_declarations.aconfig",
|
"settings_experience_flag_declarations.aconfig",
|
||||||
"settings_onboarding_experience_flag_declarations.aconfig",
|
"settings_onboarding_experience_flag_declarations.aconfig",
|
||||||
"settings_telephony_flag_declarations.aconfig",
|
"settings_telephony_flag_declarations.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"
|
||||||
|
}
|
||||||
|
|
@@ -68,10 +68,13 @@ import com.android.settings.R;
|
|||||||
import com.android.settings.biometrics.BiometricEnrollSidecar;
|
import com.android.settings.biometrics.BiometricEnrollSidecar;
|
||||||
import com.android.settings.biometrics.BiometricUtils;
|
import com.android.settings.biometrics.BiometricUtils;
|
||||||
import com.android.settings.biometrics.BiometricsEnrollEnrolling;
|
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.core.instrumentation.InstrumentedDialogFragment;
|
||||||
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
import com.android.settingslib.display.DisplayDensityUtils;
|
import com.android.settingslib.display.DisplayDensityUtils;
|
||||||
|
|
||||||
import com.airbnb.lottie.LottieAnimationView;
|
import com.airbnb.lottie.LottieAnimationView;
|
||||||
|
import com.airbnb.lottie.LottieComposition;
|
||||||
import com.airbnb.lottie.LottieCompositionFactory;
|
import com.airbnb.lottie.LottieCompositionFactory;
|
||||||
import com.airbnb.lottie.LottieProperty;
|
import com.airbnb.lottie.LottieProperty;
|
||||||
import com.airbnb.lottie.model.KeyPath;
|
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.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activity which handles the actual enrolling for fingerprint.
|
* 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 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_CENTER = 0;
|
||||||
private static final int STAGE_GUIDED = 1;
|
private static final int STAGE_GUIDED = 1;
|
||||||
private static final int STAGE_FINGERTIP = 2;
|
private static final int STAGE_FINGERTIP = 2;
|
||||||
private static final int STAGE_LEFT_EDGE = 3;
|
private static final int STAGE_LEFT_EDGE = 3;
|
||||||
private static final int STAGE_RIGHT_EDGE = 4;
|
private static final int STAGE_RIGHT_EDGE = 4;
|
||||||
|
|
||||||
@VisibleForTesting
|
public static final int SFPS_STAGE_NO_ANIMATION = 0;
|
||||||
protected static final int SFPS_STAGE_NO_ANIMATION = 0;
|
|
||||||
|
|
||||||
@VisibleForTesting
|
public static final int SFPS_STAGE_CENTER = 1;
|
||||||
protected static final int SFPS_STAGE_CENTER = 1;
|
|
||||||
|
|
||||||
@VisibleForTesting
|
public static final int SFPS_STAGE_FINGERTIP = 2;
|
||||||
protected static final int SFPS_STAGE_FINGERTIP = 2;
|
|
||||||
|
|
||||||
@VisibleForTesting
|
public static final int SFPS_STAGE_LEFT_EDGE = 3;
|
||||||
protected static final int SFPS_STAGE_LEFT_EDGE = 3;
|
|
||||||
|
|
||||||
@VisibleForTesting
|
public static final int SFPS_STAGE_RIGHT_EDGE = 4;
|
||||||
protected static final int SFPS_STAGE_RIGHT_EDGE = 4;
|
|
||||||
|
|
||||||
@IntDef({STAGE_UNKNOWN, STAGE_CENTER, STAGE_GUIDED, STAGE_FINGERTIP, STAGE_LEFT_EDGE,
|
@IntDef({STAGE_UNKNOWN, STAGE_CENTER, STAGE_GUIDED, STAGE_FINGERTIP, STAGE_LEFT_EDGE,
|
||||||
STAGE_RIGHT_EDGE})
|
STAGE_RIGHT_EDGE})
|
||||||
@@ -196,6 +195,9 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
|
|||||||
private OrientationEventListener mOrientationEventListener;
|
private OrientationEventListener mOrientationEventListener;
|
||||||
private int mPreviousRotation = 0;
|
private int mPreviousRotation = 0;
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private SfpsEnrollmentFeature mSfpsEnrollmentFeature = new EmptySfpsEnrollmentFeature();
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
protected boolean shouldShowLottie() {
|
protected boolean shouldShowLottie() {
|
||||||
DisplayDensityUtils displayDensity = new DisplayDensityUtils(getApplicationContext());
|
DisplayDensityUtils displayDensity = new DisplayDensityUtils(getApplicationContext());
|
||||||
@@ -244,6 +246,8 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
|
|||||||
setContentView(layout);
|
setContentView(layout);
|
||||||
setDescriptionText(R.string.security_settings_udfps_enroll_start_message);
|
setDescriptionText(R.string.security_settings_udfps_enroll_start_message);
|
||||||
} else if (mCanAssumeSfps) {
|
} else if (mCanAssumeSfps) {
|
||||||
|
mSfpsEnrollmentFeature = FeatureFactory.getFeatureFactory()
|
||||||
|
.getFingerprintFeatureProvider().getSfpsEnrollmentFeature();
|
||||||
setContentView(R.layout.sfps_enroll_enrolling);
|
setContentView(R.layout.sfps_enroll_enrolling);
|
||||||
setHelpAnimation();
|
setHelpAnimation();
|
||||||
} else {
|
} else {
|
||||||
@@ -599,7 +603,8 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
|
|||||||
}
|
}
|
||||||
switch (getCurrentSfpsStage()) {
|
switch (getCurrentSfpsStage()) {
|
||||||
case SFPS_STAGE_NO_ANIMATION:
|
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) {
|
if (!mHaveShownSfpsNoAnimationLottie && mIllustrationLottie != null) {
|
||||||
mHaveShownSfpsNoAnimationLottie = true;
|
mHaveShownSfpsNoAnimationLottie = true;
|
||||||
mIllustrationLottie.setContentDescription(
|
mIllustrationLottie.setContentDescription(
|
||||||
@@ -608,39 +613,48 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
|
|||||||
0
|
0
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
configureEnrollmentStage(R.raw.sfps_lottie_no_animation);
|
configureEnrollmentStage(mSfpsEnrollmentFeature
|
||||||
|
.getSfpsEnrollLottiePerStage(SFPS_STAGE_NO_ANIMATION));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SFPS_STAGE_CENTER:
|
case SFPS_STAGE_CENTER:
|
||||||
setHeaderText(R.string.security_settings_sfps_enroll_finger_center_title);
|
setHeaderText(mSfpsEnrollmentFeature
|
||||||
|
.getFeaturedStageHeaderResource(SFPS_STAGE_CENTER));
|
||||||
if (!mHaveShownSfpsCenterLottie && mIllustrationLottie != null) {
|
if (!mHaveShownSfpsCenterLottie && mIllustrationLottie != null) {
|
||||||
mHaveShownSfpsCenterLottie = true;
|
mHaveShownSfpsCenterLottie = true;
|
||||||
configureEnrollmentStage(R.raw.sfps_lottie_pad_center);
|
configureEnrollmentStage(mSfpsEnrollmentFeature
|
||||||
|
.getSfpsEnrollLottiePerStage(SFPS_STAGE_CENTER));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SFPS_STAGE_FINGERTIP:
|
case SFPS_STAGE_FINGERTIP:
|
||||||
setHeaderText(R.string.security_settings_sfps_enroll_fingertip_title);
|
setHeaderText(mSfpsEnrollmentFeature
|
||||||
|
.getFeaturedStageHeaderResource(SFPS_STAGE_FINGERTIP));
|
||||||
if (!mHaveShownSfpsTipLottie && mIllustrationLottie != null) {
|
if (!mHaveShownSfpsTipLottie && mIllustrationLottie != null) {
|
||||||
mHaveShownSfpsTipLottie = true;
|
mHaveShownSfpsTipLottie = true;
|
||||||
configureEnrollmentStage(R.raw.sfps_lottie_tip);
|
configureEnrollmentStage(mSfpsEnrollmentFeature
|
||||||
|
.getSfpsEnrollLottiePerStage(SFPS_STAGE_FINGERTIP));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SFPS_STAGE_LEFT_EDGE:
|
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) {
|
if (!mHaveShownSfpsLeftEdgeLottie && mIllustrationLottie != null) {
|
||||||
mHaveShownSfpsLeftEdgeLottie = true;
|
mHaveShownSfpsLeftEdgeLottie = true;
|
||||||
configureEnrollmentStage(R.raw.sfps_lottie_left_edge);
|
configureEnrollmentStage(mSfpsEnrollmentFeature
|
||||||
|
.getSfpsEnrollLottiePerStage(SFPS_STAGE_LEFT_EDGE));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SFPS_STAGE_RIGHT_EDGE:
|
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) {
|
if (!mHaveShownSfpsRightEdgeLottie && mIllustrationLottie != null) {
|
||||||
mHaveShownSfpsRightEdgeLottie = true;
|
mHaveShownSfpsRightEdgeLottie = true;
|
||||||
configureEnrollmentStage(R.raw.sfps_lottie_right_edge);
|
configureEnrollmentStage(mSfpsEnrollmentFeature
|
||||||
|
.getSfpsEnrollLottiePerStage(SFPS_STAGE_RIGHT_EDGE));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -665,11 +679,16 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
|
|||||||
setDescriptionText("");
|
setDescriptionText("");
|
||||||
}
|
}
|
||||||
LottieCompositionFactory.fromRawRes(this, lottie)
|
LottieCompositionFactory.fromRawRes(this, lottie)
|
||||||
.addListener((c) -> {
|
.addListener((c) -> onLottieComposition(mIllustrationLottie, c));
|
||||||
mIllustrationLottie.setComposition(c);
|
}
|
||||||
mIllustrationLottie.setVisibility(View.VISIBLE);
|
|
||||||
mIllustrationLottie.playAnimation();
|
private void onLottieComposition(LottieAnimationView view, LottieComposition composition) {
|
||||||
});
|
if (view == null || composition == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
view.setComposition(composition);
|
||||||
|
view.setVisibility(View.VISIBLE);
|
||||||
|
view.playAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnrollStage
|
@EnrollStage
|
||||||
@@ -699,17 +718,8 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final int progressSteps = mSidecar.getEnrollmentSteps() - mSidecar.getEnrollmentRemaining();
|
final int progressSteps = mSidecar.getEnrollmentSteps() - mSidecar.getEnrollmentRemaining();
|
||||||
if (progressSteps < getStageThresholdSteps(0)) {
|
return mSfpsEnrollmentFeature
|
||||||
return SFPS_STAGE_NO_ANIMATION;
|
.getCurrentSfpsEnrollStage(progressSteps, this::getStageThresholdSteps);
|
||||||
} 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isStageHalfCompleted() {
|
private boolean isStageHalfCompleted() {
|
||||||
@@ -740,22 +750,31 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
|
|||||||
Log.w(TAG, "getStageThresholdSteps: Enrollment not started yet");
|
Log.w(TAG, "getStageThresholdSteps: Enrollment not started yet");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return Math.round(mSidecar.getEnrollmentSteps()
|
final float threshold = mCanAssumeSfps
|
||||||
* mFingerprintManager.getEnrollStageThreshold(index));
|
? mSfpsEnrollmentFeature.getEnrollStageThreshold(this, index)
|
||||||
|
: mFingerprintManager.getEnrollStageThreshold(index);
|
||||||
|
return Math.round(mSidecar.getEnrollmentSteps() * threshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnrollmentHelp(int helpMsgId, CharSequence helpString) {
|
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)) {
|
if (!(mCanAssumeUdfps || mCanAssumeSfps)) {
|
||||||
mErrorText.removeCallbacks(mTouchAgainRunnable);
|
mErrorText.removeCallbacks(mTouchAgainRunnable);
|
||||||
}
|
}
|
||||||
showError(helpString);
|
showError(featuredString);
|
||||||
|
|
||||||
if (mUdfpsEnrollHelper != null) mUdfpsEnrollHelper.onEnrollmentHelp();
|
if (mUdfpsEnrollHelper != null) mUdfpsEnrollHelper.onEnrollmentHelp();
|
||||||
}
|
}
|
||||||
|
|
||||||
dismissTouchDialogIfSfps();
|
dismissTouchDialogIfSfps();
|
||||||
|
if (mCanAssumeSfps) {
|
||||||
|
mSfpsEnrollmentFeature.handleOnEnrollmentHelp(helpMsgId, featuredString, () -> this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1170,4 +1189,28 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
|
|||||||
return SettingsEnums.DIALOG_FINGERPRINT_ICON_TOUCH;
|
return SettingsEnums.DIALOG_FINGERPRINT_ICON_TOUCH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class EmptySfpsEnrollmentFeature implements SfpsEnrollmentFeature {
|
||||||
|
private final String exceptionStr = "Assume sfps but no SfpsEnrollmentFeature impl.";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCurrentSfpsEnrollStage(int progressSteps, Function<Integer, Integer> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@@ -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();
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
@@ -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<Integer, Integer> 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<FingerprintEnrollEnrolling> enrollingSupplier) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the fingerprint enrollment threshold.
|
||||||
|
* @param context context
|
||||||
|
* @param index the enrollment stage index
|
||||||
|
* @return threshold
|
||||||
|
*/
|
||||||
|
float getEnrollStageThreshold(@NonNull Context context, int index);
|
||||||
|
}
|
@@ -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<Integer, Integer> 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);
|
||||||
|
}
|
||||||
|
}
|
@@ -21,6 +21,7 @@ import com.android.settings.accessibility.AccessibilitySearchFeatureProvider
|
|||||||
import com.android.settings.accounts.AccountFeatureProvider
|
import com.android.settings.accounts.AccountFeatureProvider
|
||||||
import com.android.settings.applications.ApplicationFeatureProvider
|
import com.android.settings.applications.ApplicationFeatureProvider
|
||||||
import com.android.settings.biometrics.face.FaceFeatureProvider
|
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.biometrics2.factory.BiometricsRepositoryProvider
|
||||||
import com.android.settings.bluetooth.BluetoothFeatureProvider
|
import com.android.settings.bluetooth.BluetoothFeatureProvider
|
||||||
import com.android.settings.connecteddevice.fastpair.FastPairFeatureProvider
|
import com.android.settings.connecteddevice.fastpair.FastPairFeatureProvider
|
||||||
@@ -104,8 +105,16 @@ abstract class FeatureFactory {
|
|||||||
*/
|
*/
|
||||||
abstract val bluetoothFeatureProvider: BluetoothFeatureProvider
|
abstract val bluetoothFeatureProvider: BluetoothFeatureProvider
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves implementation for Face feature.
|
||||||
|
*/
|
||||||
abstract val faceFeatureProvider: FaceFeatureProvider
|
abstract val faceFeatureProvider: FaceFeatureProvider
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves implementation for Fingerprint feature.
|
||||||
|
*/
|
||||||
|
abstract val fingerprintFeatureProvider: FingerprintFeatureProvider
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets implementation for Biometrics repository provider.
|
* Gets implementation for Biometrics repository provider.
|
||||||
*/
|
*/
|
||||||
|
@@ -29,6 +29,8 @@ import com.android.settings.accounts.AccountFeatureProviderImpl
|
|||||||
import com.android.settings.applications.ApplicationFeatureProviderImpl
|
import com.android.settings.applications.ApplicationFeatureProviderImpl
|
||||||
import com.android.settings.biometrics.face.FaceFeatureProvider
|
import com.android.settings.biometrics.face.FaceFeatureProvider
|
||||||
import com.android.settings.biometrics.face.FaceFeatureProviderImpl
|
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.biometrics2.factory.BiometricsRepositoryProviderImpl
|
||||||
import com.android.settings.bluetooth.BluetoothFeatureProvider
|
import com.android.settings.bluetooth.BluetoothFeatureProvider
|
||||||
import com.android.settings.bluetooth.BluetoothFeatureProviderImpl
|
import com.android.settings.bluetooth.BluetoothFeatureProviderImpl
|
||||||
@@ -145,6 +147,10 @@ open class FeatureFactoryImpl : FeatureFactory() {
|
|||||||
|
|
||||||
override val faceFeatureProvider: FaceFeatureProvider by lazy { FaceFeatureProviderImpl() }
|
override val faceFeatureProvider: FaceFeatureProvider by lazy { FaceFeatureProviderImpl() }
|
||||||
|
|
||||||
|
override val fingerprintFeatureProvider: FingerprintFeatureProvider by lazy {
|
||||||
|
FingerprintFeatureProviderImpl()
|
||||||
|
}
|
||||||
|
|
||||||
override val biometricsRepositoryProvider by lazy { BiometricsRepositoryProviderImpl() }
|
override val biometricsRepositoryProvider by lazy { BiometricsRepositoryProviderImpl() }
|
||||||
|
|
||||||
override val wifiTrackerLibProvider: WifiTrackerLibProvider by lazy {
|
override val wifiTrackerLibProvider: WifiTrackerLibProvider by lazy {
|
||||||
|
@@ -24,6 +24,7 @@ import com.android.settings.accessibility.AccessibilitySearchFeatureProvider;
|
|||||||
import com.android.settings.accounts.AccountFeatureProvider;
|
import com.android.settings.accounts.AccountFeatureProvider;
|
||||||
import com.android.settings.applications.ApplicationFeatureProvider;
|
import com.android.settings.applications.ApplicationFeatureProvider;
|
||||||
import com.android.settings.biometrics.face.FaceFeatureProvider;
|
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.biometrics2.factory.BiometricsRepositoryProvider;
|
||||||
import com.android.settings.bluetooth.BluetoothFeatureProvider;
|
import com.android.settings.bluetooth.BluetoothFeatureProvider;
|
||||||
import com.android.settings.connecteddevice.fastpair.FastPairFeatureProvider;
|
import com.android.settings.connecteddevice.fastpair.FastPairFeatureProvider;
|
||||||
@@ -80,6 +81,7 @@ public class FakeFeatureFactory extends FeatureFactory {
|
|||||||
public final AccountFeatureProvider mAccountFeatureProvider;
|
public final AccountFeatureProvider mAccountFeatureProvider;
|
||||||
public final BluetoothFeatureProvider mBluetoothFeatureProvider;
|
public final BluetoothFeatureProvider mBluetoothFeatureProvider;
|
||||||
public final FaceFeatureProvider mFaceFeatureProvider;
|
public final FaceFeatureProvider mFaceFeatureProvider;
|
||||||
|
public final FingerprintFeatureProvider mFingerprintFeatureProvider;
|
||||||
public final BiometricsRepositoryProvider mBiometricsRepositoryProvider;
|
public final BiometricsRepositoryProvider mBiometricsRepositoryProvider;
|
||||||
|
|
||||||
public PanelFeatureProvider panelFeatureProvider;
|
public PanelFeatureProvider panelFeatureProvider;
|
||||||
@@ -132,6 +134,7 @@ public class FakeFeatureFactory extends FeatureFactory {
|
|||||||
panelFeatureProvider = mock(PanelFeatureProvider.class);
|
panelFeatureProvider = mock(PanelFeatureProvider.class);
|
||||||
mBluetoothFeatureProvider = mock(BluetoothFeatureProvider.class);
|
mBluetoothFeatureProvider = mock(BluetoothFeatureProvider.class);
|
||||||
mFaceFeatureProvider = mock(FaceFeatureProvider.class);
|
mFaceFeatureProvider = mock(FaceFeatureProvider.class);
|
||||||
|
mFingerprintFeatureProvider = mock(FingerprintFeatureProvider.class);
|
||||||
mBiometricsRepositoryProvider = mock(BiometricsRepositoryProvider.class);
|
mBiometricsRepositoryProvider = mock(BiometricsRepositoryProvider.class);
|
||||||
wifiTrackerLibProvider = mock(WifiTrackerLibProvider.class);
|
wifiTrackerLibProvider = mock(WifiTrackerLibProvider.class);
|
||||||
securitySettingsFeatureProvider = mock(SecuritySettingsFeatureProvider.class);
|
securitySettingsFeatureProvider = mock(SecuritySettingsFeatureProvider.class);
|
||||||
@@ -256,6 +259,11 @@ public class FakeFeatureFactory extends FeatureFactory {
|
|||||||
return mFaceFeatureProvider;
|
return mFaceFeatureProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FingerprintFeatureProvider getFingerprintFeatureProvider() {
|
||||||
|
return mFingerprintFeatureProvider;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BiometricsRepositoryProvider getBiometricsRepositoryProvider() {
|
public BiometricsRepositoryProvider getBiometricsRepositoryProvider() {
|
||||||
return mBiometricsRepositoryProvider;
|
return mBiometricsRepositoryProvider;
|
||||||
|
@@ -22,6 +22,7 @@ import com.android.settings.accessibility.AccessibilitySearchFeatureProvider
|
|||||||
import com.android.settings.accounts.AccountFeatureProvider
|
import com.android.settings.accounts.AccountFeatureProvider
|
||||||
import com.android.settings.applications.ApplicationFeatureProvider
|
import com.android.settings.applications.ApplicationFeatureProvider
|
||||||
import com.android.settings.biometrics.face.FaceFeatureProvider
|
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.biometrics2.factory.BiometricsRepositoryProvider
|
||||||
import com.android.settings.bluetooth.BluetoothFeatureProvider
|
import com.android.settings.bluetooth.BluetoothFeatureProvider
|
||||||
import com.android.settings.connecteddevice.fastpair.FastPairFeatureProvider
|
import com.android.settings.connecteddevice.fastpair.FastPairFeatureProvider
|
||||||
@@ -120,6 +121,8 @@ class FakeFeatureFactory : FeatureFactory() {
|
|||||||
get() = TODO("Not yet implemented")
|
get() = TODO("Not yet implemented")
|
||||||
override val faceFeatureProvider: FaceFeatureProvider
|
override val faceFeatureProvider: FaceFeatureProvider
|
||||||
get() = TODO("Not yet implemented")
|
get() = TODO("Not yet implemented")
|
||||||
|
override val fingerprintFeatureProvider: FingerprintFeatureProvider
|
||||||
|
get() = TODO("Not yet implemented")
|
||||||
override val biometricsRepositoryProvider: BiometricsRepositoryProvider
|
override val biometricsRepositoryProvider: BiometricsRepositoryProvider
|
||||||
get() = TODO("Not yet implemented")
|
get() = TODO("Not yet implemented")
|
||||||
override val wifiTrackerLibProvider: WifiTrackerLibProvider
|
override val wifiTrackerLibProvider: WifiTrackerLibProvider
|
||||||
|
@@ -24,6 +24,7 @@ import com.android.settings.accessibility.AccessibilitySearchFeatureProvider;
|
|||||||
import com.android.settings.accounts.AccountFeatureProvider;
|
import com.android.settings.accounts.AccountFeatureProvider;
|
||||||
import com.android.settings.applications.ApplicationFeatureProvider;
|
import com.android.settings.applications.ApplicationFeatureProvider;
|
||||||
import com.android.settings.biometrics.face.FaceFeatureProvider;
|
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.biometrics2.factory.BiometricsRepositoryProvider;
|
||||||
import com.android.settings.bluetooth.BluetoothFeatureProvider;
|
import com.android.settings.bluetooth.BluetoothFeatureProvider;
|
||||||
import com.android.settings.connecteddevice.fastpair.FastPairFeatureProvider;
|
import com.android.settings.connecteddevice.fastpair.FastPairFeatureProvider;
|
||||||
@@ -79,6 +80,7 @@ public class FakeFeatureFactory extends FeatureFactory {
|
|||||||
public final AccountFeatureProvider mAccountFeatureProvider;
|
public final AccountFeatureProvider mAccountFeatureProvider;
|
||||||
public final BluetoothFeatureProvider mBluetoothFeatureProvider;
|
public final BluetoothFeatureProvider mBluetoothFeatureProvider;
|
||||||
public final FaceFeatureProvider mFaceFeatureProvider;
|
public final FaceFeatureProvider mFaceFeatureProvider;
|
||||||
|
public final FingerprintFeatureProvider mFingerprintFeatureProvider;
|
||||||
public final BiometricsRepositoryProvider mBiometricsRepositoryProvider;
|
public final BiometricsRepositoryProvider mBiometricsRepositoryProvider;
|
||||||
|
|
||||||
public PanelFeatureProvider panelFeatureProvider;
|
public PanelFeatureProvider panelFeatureProvider;
|
||||||
@@ -131,6 +133,7 @@ public class FakeFeatureFactory extends FeatureFactory {
|
|||||||
panelFeatureProvider = mock(PanelFeatureProvider.class);
|
panelFeatureProvider = mock(PanelFeatureProvider.class);
|
||||||
mBluetoothFeatureProvider = mock(BluetoothFeatureProvider.class);
|
mBluetoothFeatureProvider = mock(BluetoothFeatureProvider.class);
|
||||||
mFaceFeatureProvider = mock(FaceFeatureProvider.class);
|
mFaceFeatureProvider = mock(FaceFeatureProvider.class);
|
||||||
|
mFingerprintFeatureProvider = mock(FingerprintFeatureProvider.class);
|
||||||
mBiometricsRepositoryProvider = mock(BiometricsRepositoryProvider.class);
|
mBiometricsRepositoryProvider = mock(BiometricsRepositoryProvider.class);
|
||||||
wifiTrackerLibProvider = mock(WifiTrackerLibProvider.class);
|
wifiTrackerLibProvider = mock(WifiTrackerLibProvider.class);
|
||||||
securitySettingsFeatureProvider = mock(SecuritySettingsFeatureProvider.class);
|
securitySettingsFeatureProvider = mock(SecuritySettingsFeatureProvider.class);
|
||||||
@@ -255,6 +258,11 @@ public class FakeFeatureFactory extends FeatureFactory {
|
|||||||
return mFaceFeatureProvider;
|
return mFaceFeatureProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FingerprintFeatureProvider getFingerprintFeatureProvider() {
|
||||||
|
return mFingerprintFeatureProvider;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BiometricsRepositoryProvider getBiometricsRepositoryProvider() {
|
public BiometricsRepositoryProvider getBiometricsRepositoryProvider() {
|
||||||
return mBiometricsRepositoryProvider;
|
return mBiometricsRepositoryProvider;
|
||||||
|
Reference in New Issue
Block a user