diff --git a/res/values/e_config.xml b/res/values/e_config.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2b8dabdbbc526ed12d9bb2349c7144316a118890
--- /dev/null
+++ b/res/values/e_config.xml
@@ -0,0 +1,20 @@
+
+
+
+
+ false
+
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
index f7134fba6e5b8d415fb825290e51bc69cce49742..8961c91eafcb895d3b5de2662c53802911376451 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
@@ -260,7 +260,7 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
}
} else if (mCanAssumeSfps) {
mSfpsEnrollmentFeature = FeatureFactory.getFeatureFactory()
- .getFingerprintFeatureProvider().getSfpsEnrollmentFeature();
+ .getFingerprintFeatureProvider().getSfpsEnrollmentFeature(getApplicationContext());
setContentView(R.layout.sfps_enroll_enrolling);
setHelpAnimation();
} else {
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintFeatureProvider.java b/src/com/android/settings/biometrics/fingerprint/FingerprintFeatureProvider.java
index c1e34a579a8f3344d16c87326bc4fc912494a01b..80547be1832348dcb177ef3e3bef5f60201c4b4a 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintFeatureProvider.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintFeatureProvider.java
@@ -31,7 +31,7 @@ public interface FingerprintFeatureProvider {
* Gets the feature implementation of SFPS enrollment.
* @return the feature implementation
*/
- SfpsEnrollmentFeature getSfpsEnrollmentFeature();
+ SfpsEnrollmentFeature getSfpsEnrollmentFeature(@NonNull Context context);
/**
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintFeatureProviderImpl.java b/src/com/android/settings/biometrics/fingerprint/FingerprintFeatureProviderImpl.java
index 8a8df984e5282c7d12652bac7d8704c2d0ff0b68..c7aa740c6bafe797651fee30dbddfbd17bc9a42b 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintFeatureProviderImpl.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintFeatureProviderImpl.java
@@ -35,9 +35,9 @@ public class FingerprintFeatureProviderImpl implements FingerprintFeatureProvide
private SfpsRestToUnlockFeature mSfpsRestToUnlockFeature = null;
@Override
- public SfpsEnrollmentFeature getSfpsEnrollmentFeature() {
+ public SfpsEnrollmentFeature getSfpsEnrollmentFeature(@NonNull Context context) {
if (mSfpsEnrollmentFeatureImpl == null) {
- mSfpsEnrollmentFeatureImpl = new SfpsEnrollmentFeatureImpl();
+ mSfpsEnrollmentFeatureImpl = new SfpsEnrollmentFeatureImpl(context);
}
return mSfpsEnrollmentFeatureImpl;
}
diff --git a/src/com/android/settings/biometrics/fingerprint/feature/IFingerprintExt.java b/src/com/android/settings/biometrics/fingerprint/feature/IFingerprintExt.java
new file mode 100644
index 0000000000000000000000000000000000000000..9c7376cf4025635da7b1a9bffafce86a7ccb3ad3
--- /dev/null
+++ b/src/com/android/settings/biometrics/fingerprint/feature/IFingerprintExt.java
@@ -0,0 +1,70 @@
+package com.android.settings.biometrics.fingerprint.feature;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.Parcel;
+import android.os.RemoteException;
+
+/**
+ * Interface for fingerprint extension functionalities.
+ */
+public interface IFingerprintExt extends IInterface {
+ String DESCRIPTOR = "com.google.hardware.biometrics.sidefps.IFingerprintExt";
+
+ void resumeEnroll() throws RemoteException;
+
+ /**
+ * Binder stub class for the IFingerprintExt interface.
+ */
+ abstract class Stub extends Binder implements IFingerprintExt {
+
+ /**
+ * Returns an instance of IFingerprintExt if available from the provided IBinder.
+ *
+ * @param binder the IBinder to convert
+ * @return IFingerprintExt instance or null if not available
+ */
+ public static IFingerprintExt asInterface(IBinder binder) {
+ if (binder == null) {
+ return null;
+ }
+ IInterface query = binder.queryLocalInterface(IFingerprintExt.DESCRIPTOR);
+ if (query instanceof IFingerprintExt) {
+ return (IFingerprintExt) query;
+ }
+ return new Proxy(binder);
+ }
+
+ /**
+ * Proxy implementation for IFingerprintExt.
+ */
+ private static class Proxy implements IFingerprintExt {
+ private final IBinder remote;
+
+ Proxy(IBinder binder) {
+ this.remote = binder;
+ }
+
+ @Override
+ public IBinder asBinder() {
+ return remote;
+ }
+
+ @Override
+ public void resumeEnroll() throws RemoteException {
+ Parcel data = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(DESCRIPTOR);
+ if (!remote.transact(TRANSACTION_RESUME_ENROLL, data, null, IBinder.FLAG_ONEWAY)) {
+ throw new RemoteException("Method resumeEnroll is unimplemented.");
+ }
+ } finally {
+ data.recycle();
+ }
+ }
+
+ private static final int TRANSACTION_RESUME_ENROLL = IBinder.FIRST_CALL_TRANSACTION + 1;
+ }
+ }
+}
diff --git a/src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeatureImpl.java b/src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeatureImpl.java
index 60ced6e95f1b0c2f72971bac6f4608779a9a350e..b5824186ac59593c843f113d4d7689389cc1921c 100644
--- a/src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeatureImpl.java
+++ b/src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeatureImpl.java
@@ -27,6 +27,7 @@ import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.hardware.fingerprint.FingerprintManager;
+import android.text.TextUtils;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
@@ -34,9 +35,11 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.biometrics.fingerprint.feature.SfpsUtils;
import com.android.settings.R;
import java.util.function.Function;
+import java.util.function.Supplier;
public class SfpsEnrollmentFeatureImpl implements SfpsEnrollmentFeature {
@VisibleForTesting
@@ -45,6 +48,13 @@ public class SfpsEnrollmentFeatureImpl implements SfpsEnrollmentFeature {
@Nullable
private FingerprintManager mFingerprintManager = null;
+ private static final int HELP_RESUME_ENROLL_MSG = 1000;
+ private Context mContext;
+
+ public SfpsEnrollmentFeatureImpl(Context context) {
+ this.mContext = context;
+ }
+
@Override
public int getCurrentSfpsEnrollStage(int progressSteps, Function mapper) {
if (mapper == null) {
@@ -96,6 +106,22 @@ public class SfpsEnrollmentFeatureImpl implements SfpsEnrollmentFeature {
return mFingerprintManager.getEnrollStageThreshold(index);
}
+ @Override
+ public void handleOnEnrollmentHelp(int helpMsgId, CharSequence helpString, Supplier supplier) {
+ if (supplier == null || TextUtils.isEmpty(helpString)) {
+ return;
+ }
+ resumeEnrollmentIfNecessary(helpMsgId, helpString.toString(), supplier);
+ }
+
+ private void resumeEnrollmentIfNecessary(int helpMsgId, String helpString, Supplier supplier) {
+ final boolean useGoogleSfps = mContext.getResources().getBoolean(
+ R.bool.config_use_google_side_fps);
+ if (helpMsgId == HELP_RESUME_ENROLL_MSG && useGoogleSfps) {
+ SfpsUtils.resumeEnroll();
+ }
+ }
+
@Override
public Animator getHelpAnimator(@NonNull View target) {
final float translationX = 40;
diff --git a/src/com/android/settings/biometrics/fingerprint/feature/SfpsUtils.java b/src/com/android/settings/biometrics/fingerprint/feature/SfpsUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..a44d5fd5d41b6835bce42718ad1986c79f7a6881
--- /dev/null
+++ b/src/com/android/settings/biometrics/fingerprint/feature/SfpsUtils.java
@@ -0,0 +1,62 @@
+package com.android.settings.biometrics.fingerprint.feature;
+
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+import com.android.settings.biometrics.fingerprint.feature.IFingerprintExt;
+
+import java.util.function.Supplier;
+
+public abstract class SfpsUtils {
+
+ private static final String TAG = "BiometricUtil";
+ private static final String FINGERPRINT_SERVICE = "android.hardware.biometrics.fingerprint.IFingerprint/default";
+
+ /**
+ * Resumes fingerprint enrollment using the IFingerprintExt interface.
+ */
+ public static void resumeEnroll() {
+ IFingerprintExt fingerprintExt = getFingerprintExtSupplier().get();
+
+ if (fingerprintExt == null) {
+ Log.e(TAG, "Failed to connect to the fingerprint extension");
+ return;
+ }
+
+ try {
+ fingerprintExt.resumeEnroll();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to resume enrollment due to RemoteException", e);
+ }
+ }
+
+ /**
+ * Provides a supplier for the IFingerprintExt interface.
+ *
+ * @return Supplier of IFingerprintExt
+ */
+ private static Supplier getFingerprintExtSupplier() {
+ return () -> getFingerprintExtInstance();
+ }
+
+ /**
+ * Retrieves an instance of IFingerprintExt.
+ *
+ * @return IFingerprintExt instance or null if unavailable
+ */
+ private static IFingerprintExt getFingerprintExtInstance() {
+ try {
+ IBinder serviceBinder = ServiceManager.waitForDeclaredService(FINGERPRINT_SERVICE);
+ if (serviceBinder == null) {
+ Log.e(TAG, "Unable to get fingerprint service");
+ return null;
+ }
+
+ return IFingerprintExt.Stub.asInterface(serviceBinder.getExtension());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error accessing fingerprint extension", e);
+ return null;
+ }
+ }
+}