diff --git a/Android.bp b/Android.bp index 43c83c98737..6d3b4106d70 100644 --- a/Android.bp +++ b/Android.bp @@ -55,6 +55,7 @@ android_library { srcs: [ "src/**/*.java", "src/**/*.kt", + "src/**/*.aidl", "Evolver/src/**/*.java", "Evolver/src/**/*.kt", ], diff --git a/res/values/arrays.xml b/res/values/arrays.xml index 80c3e8d2c4b..9ec4f0f2af3 100644 --- a/res/values/arrays.xml +++ b/res/values/arrays.xml @@ -1647,4 +1647,6 @@ + + diff --git a/src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeatureImpl.java b/src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeatureImpl.java index bf97478feef..a70144d47e7 100644 --- a/src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeatureImpl.java +++ b/src/com/android/settings/biometrics/fingerprint/feature/SfpsEnrollmentFeatureImpl.java @@ -25,21 +25,34 @@ import static com.android.settings.biometrics.fingerprint.FingerprintEnrollEnrol import android.animation.Animator; import android.animation.ObjectAnimator; +import android.app.AlertDialog; import android.content.Context; import android.content.res.Configuration; +import android.hardware.biometrics.BiometricFingerprintConstants; import android.hardware.fingerprint.FingerprintManager; +import android.os.Build; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.util.Log; import android.view.View; import android.view.animation.AccelerateInterpolator; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.core.util.Preconditions; import com.android.internal.annotations.VisibleForTesting; import com.android.settings.R; +import com.android.settings.biometrics.fingerprint.FingerprintEnrollEnrolling; +import com.google.hardware.biometrics.sidefps.IFingerprintExt; import java.util.function.Function; +import java.util.function.Supplier; public class SfpsEnrollmentFeatureImpl implements SfpsEnrollmentFeature { + static final String TAG = SfpsEnrollmentFeatureImpl.class.getSimpleName(); + @VisibleForTesting public static final int HELP_ANIMATOR_DURATION = 550; @@ -89,8 +102,31 @@ public class SfpsEnrollmentFeatureImpl implements SfpsEnrollmentFeature { }; } + private final boolean isGoogleDevice = "google".equals(Build.BRAND); + private float[] mEnrollStageThresholds; + @Override public float getEnrollStageThreshold(@NonNull Context context, int index) { + if (isGoogleDevice) { + Log.d(TAG, "getEnrollStageThreshold " + index); + if (mEnrollStageThresholds == null) { + // TODO: extract these values automatically from SettingsGoogle resource: + // com.google.android.settings.R.array.config_sfps_enroll_stage_thresholds + mEnrollStageThresholds = new float[] { + 0f, 0.04f, 0.48f, 0.52f + }; + } + + // this logic was copied from FingerprintManager.getEnrollStageThreshold() + + if (index < 0 || index > mEnrollStageThresholds.length) { + Log.w(TAG, "Unsupported enroll stage index: " + index); + return index < 0 ? 0f : 1f; + } + + return index == mEnrollStageThresholds.length ? 1f : mEnrollStageThresholds[index]; + } + if (mFingerprintManager == null) { mFingerprintManager = context.getSystemService(FingerprintManager.class); } @@ -113,4 +149,93 @@ public class SfpsEnrollmentFeatureImpl implements SfpsEnrollmentFeature { public boolean shouldAdjustHeaderText(@NonNull Configuration conf, boolean isFolded) { return conf.orientation == Configuration.ORIENTATION_LANDSCAPE; } + + @Override + public void handleOnEnrollmentHelp(int helpMsgId, CharSequence helpString, Supplier enrollingSupplier) { + if (isGoogleDevice) { + Log.d(TAG, "handleOnEnrollmentHelp, helpMsgId: " + helpMsgId + ", helpString: " + helpString, new Throwable()); + if (helpMsgId == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR_BASE || + helpMsgId == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_IMMOBILE) { + Context ctx = enrollingSupplier.get(); + Log.d(TAG, "getVendorString: " + getVendorString(ctx, 0)); + + if (getGoogleFingerprintExt() == null) { + return; + } + + if (mHelpDialog != null) { + mHelpDialog.dismiss(); + mHelpDialog = null; + } + + var d = new AlertDialog.Builder(ctx); + d.setMessage(getVendorString(ctx, VENDOR_STRING_FINGERPRINT_ACQUIRED_IMMOBILE)); + d.setPositiveButton(android.R.string.ok, (dialog, which) -> { + resumeEnroll(); + }); + mHelpDialog = d.show(); + } + } + } + + private AlertDialog mHelpDialog; + + @Override + public CharSequence getFeaturedVendorString(Context context, int id, CharSequence msg) { + if (!isGoogleDevice) { + return msg; + } + + Log.d(TAG, "getFeaturedVendorString, id: " + id + ", msg: " + msg, new Throwable()); + + if (id == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR_BASE || + id == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_IMMOBILE) { + return getVendorString(context, VENDOR_STRING_FINGERPRINT_ACQUIRED_IMMOBILE); + } + + return msg; + } + + private static final int VENDOR_STRING_FINGERPRINT_ACQUIRED_IMMOBILE = 0; + + private static String getVendorString(Context ctx, int index) { + String[] strings = ctx.getResources().getStringArray(R.array.fingerprint_acquired_vendor); + Preconditions.checkArgumentInRange(index, 0, strings.length - 1, "vendor string index"); + return strings[index]; + } + + @Nullable + private static IFingerprintExt getGoogleFingerprintExt() { + String fpServiceName = android.hardware.biometrics.fingerprint.IFingerprint.class.getName() + "/default"; + IBinder fpService = ServiceManager.getService(fpServiceName); + if (fpService == null) { + throw new IllegalStateException(fpServiceName + " is null"); + } + + IBinder fpServiceExt; + try { + fpServiceExt = fpService.getExtension(); + } catch (RemoteException e) { + throw new IllegalStateException(e); + } + + if (fpServiceExt == null) { + Log.e(TAG, "no IFingerprintExt"); + return null; + } + + return IFingerprintExt.Stub.asInterface(fpServiceExt); + } + + private static void resumeEnroll() { + IFingerprintExt fpExt = getGoogleFingerprintExt(); + if (fpExt == null) { + return; + } + try { + fpExt.resumeEnroll(); + } catch (RemoteException e) { + Log.e(TAG, "", e); + } + } } diff --git a/src/com/google/hardware/biometrics/sidefps/IFingerprintExt.aidl b/src/com/google/hardware/biometrics/sidefps/IFingerprintExt.aidl new file mode 100644 index 00000000000..9fa1fd500e5 --- /dev/null +++ b/src/com/google/hardware/biometrics/sidefps/IFingerprintExt.aidl @@ -0,0 +1,5 @@ +package com.google.hardware.biometrics.sidefps; + +interface IFingerprintExt { + void resumeEnroll() = 1; +}