3434import android .content .Context ;
3535import android .content .DialogInterface ;
3636import android .content .SharedPreferences ;
37+ import android .content .pm .PackageManager ;
3738import android .hardware .biometrics .BiometricManager ;
3839import android .hardware .biometrics .BiometricPrompt ;
3940import android .hardware .fingerprint .FingerprintManager .CryptoObject ;
@@ -77,14 +78,15 @@ public class InternalFingerprintImpl {
7778
7879
7980 public boolean isAvailable () {
80- final boolean [] response = new boolean [1 ];
81+ // final boolean[] response = new boolean[1];
8182 if (android .os .Build .VERSION .SDK_INT < 23 ) {
8283 return false ;
8384 }
84-
85+ final StringBuilder paramBuilder = new StringBuilder ();
8586 if (android .os .Build .VERSION .SDK_INT >= 29 ) {
87+ CN .setProperty ("FingerprintScanner.showDialogOnAndroid" , "false" );
8688 AndroidImplementation .runOnUiThreadAndBlock (new Runnable () {
87- @ RequiresApi (api = Build .VERSION_CODES .M )
89+ @ RequiresApi (api = Build .VERSION_CODES .Q )
8890 public void run () {
8991 if (!AndroidNativeUtil .checkForPermission (Manifest .permission .USE_BIOMETRIC , "Authorize using biometrics" )){
9092 return ;
@@ -94,16 +96,32 @@ public void run() {
9496 mBiometricManager = (BiometricManager )AndroidNativeUtil .getActivity ().
9597 getSystemService (Activity .BIOMETRIC_SERVICE );
9698 }
99+ PackageManager packageManager = AndroidNativeUtil .getActivity ().getPackageManager ();
100+ boolean canAuthenticate = mBiometricManager .canAuthenticate () == BiometricManager .BIOMETRIC_SUCCESS ;
101+ if (canAuthenticate ) {
102+ if (packageManager .hasSystemFeature (PackageManager .FEATURE_FINGERPRINT )) {
103+ FingerprintManager fingerprintManager = (FingerprintManager )AndroidNativeUtil .getActivity ().getSystemService (Activity .FINGERPRINT_SERVICE );
104+ if (fingerprintManager .hasEnrolledFingerprints ()) {
105+ paramBuilder .append ("touch " );
106+ }
107+ }
108+ if (packageManager .hasSystemFeature (PackageManager .FEATURE_FACE )) {
109+ paramBuilder .append ("face " );
110+ }
111+ if (packageManager .hasSystemFeature (PackageManager .FEATURE_IRIS )) {
112+ paramBuilder .append ("iris " );
113+ }
114+ }
97115
98- response [ 0 ] = mBiometricManager . canAuthenticate () == BiometricManager . BIOMETRIC_SUCCESS ;
116+
99117 } catch (Throwable t ) {
100118 Log .p ("This exception could be 100% valid on old devices, we're logging it just to be safe. Older devices might throw NoClassDefFoundError..." );
101119 Log .e (t );
102120 }
103121 }
104122 });
105123 } else {
106-
124+ CN . setProperty ( "FingerprintScanner.showDialogOnAndroid" , "true" );
107125 AndroidImplementation .runOnUiThreadAndBlock (new Runnable () {
108126 @ RequiresApi (api = Build .VERSION_CODES .M )
109127 public void run () {
@@ -114,40 +132,21 @@ public void run() {
114132 mFingerPrintManager = (FingerprintManager )AndroidNativeUtil .getActivity ().
115133 getSystemService (Activity .FINGERPRINT_SERVICE );
116134
117- response [0 ] = mFingerPrintManager .isHardwareDetected () &&
118- mFingerPrintManager .hasEnrolledFingerprints ();
135+ if (mFingerPrintManager .isHardwareDetected () &&
136+ mFingerPrintManager .hasEnrolledFingerprints ()) {
137+
138+ }
119139 } catch (Throwable t ) {
120140 Log .p ("This exception could be 100% valid on old devices, we're logging it just to be safe. Older devices might throw NoClassDefFoundError..." );
121141 Log .e (t );
122142 }
123143 }
124144 });
125145 }
126- if (response [0 ]) {
127- // Need to store the allowed biometric types in system property so that
128- // Fingerprint.isTouchIDAvailable() and Fingerprint.isFaceIDAvailable()
129- // will work correct.
130- // If face id is supported, we append "face"
131- // If touch id is supported, we append "touch".
132- // E.g. a property value that supports both face and touch would be "touch face"
133- String param = "touch" ;
134- if (android .os .Build .VERSION .SDK_INT >= 29 ) {
135- // On API 29, we Android doesn't give us a way to determine
136- // if facial recognition is supported.
137- // https://stackoverflow.com/questions/62430155/biometricmanager-on-android-9/62433371#62433371
138- //
139- // So we add "biometric" for these versions rather than "face"
140- // so that the mightFaceIDBeAvailable() will return true
141- // but isFaceIDAvailable() will still be false.
142- param += " biometric" ;
143-
144- // If we are using BiometricPrompt, we don't need to show the CN1 fingerprint
145- // dialog because the system provides its own UI.
146- CN .setProperty ("FingerprintScanner.showDialogOnAndroid" , "false" );
147- }
148- CN .setProperty ("Fingerprint.types" , param );
149- }
150- return response [0 ];
146+ String param = paramBuilder .toString ().trim ();
147+ CN .setProperty ("Fingerprint.types" , param );
148+
149+ return !param .isEmpty ();
151150 }
152151
153152 @ RequiresApi (api = Build .VERSION_CODES .Q )
0 commit comments