Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit daa7f4f3 authored by Wu Ahan's avatar Wu Ahan Committed by Android (Google) Code Review
Browse files

Merge "Reland sfps enroll improvement feature with feature provider" into main

parents 65b2bc3b 667341c3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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",
    ],
}

+9 −0
Original line number Diff line number Diff line
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"
}
+85 −42
Original line number Diff line number Diff line
@@ -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;
        }
    }

    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);
        }
    }
}
+27 −0
Original line number Diff line number Diff line
/*
 * 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();
}
+36 −0
Original line number Diff line number Diff line
/*
 * 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;
    }
}
Loading