package com.jc.jcfw.security; import static androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG; import static androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL; import android.content.Context; import android.util.Log; import androidx.annotation.NonNull; import androidx.biometric.BiometricPrompt; import androidx.core.content.ContextCompat; import androidx.fragment.app.FragmentActivity; import com.cege.games.release.R; import java.util.concurrent.Executor; import java.util.function.Consumer; import javax.crypto.Cipher; public class BiometricHelper { public static final int ERROR_BIOMETRIC_FAIL = 100; public static final int ERROR_BIOMETRIC_NO_CIPHER = 101; private static final String TAG = BiometricHelper.class.getSimpleName(); public static BiometricPrompt.PromptInfo createPromptInfo(Context context) { BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder() .setTitle(context.getString(R.string.prompt_info_title)) // e.g. "Sign in" .setSubtitle(context.getString(R.string.prompt_info_subtitle)) // e.g. "Biometric for My App" .setDescription(context.getString(R.string.prompt_info_description)) // e.g. "Confirm biometric to continue" .setConfirmationRequired(false) .setAllowedAuthenticators(BIOMETRIC_STRONG | DEVICE_CREDENTIAL) // .setDeviceCredentialAllowed(true) // Allow PIN/pattern/password authentication. // Also note that setDeviceCredentialAllowed and setNegativeButtonText are // incompatible so that if you uncomment one you must comment out the other .build(); return promptInfo; } public static BiometricPrompt createBiometricPrompt(FragmentActivity activity, Consumer func) { Executor executor = ContextCompat.getMainExecutor(activity.getApplicationContext()); return new BiometricPrompt(activity, executor, new BiometricPrompt.AuthenticationCallback() { @Override public void onAuthenticationError(int errcode, @NonNull CharSequence errString) { super.onAuthenticationError(errcode, errString); Log.i(TAG, "Authentication error: " + errcode +" | "+ errString); func.accept(new BiometricResult(errcode, (String) errString)); } @Override public void onAuthenticationFailed() { super.onAuthenticationFailed(); Log.i(TAG, "Authentication failed!"); func.accept(new BiometricResult(ERROR_BIOMETRIC_FAIL, "Authentication failed")); } @Override public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) { super.onAuthenticationSucceeded(result); Log.i(TAG, "Authentication succeeded!"); func.accept(new BiometricResult(result.getCryptoObject().getCipher())); } }); } }