From b2463976562232ff07e0317d23ffc91f25545111 Mon Sep 17 00:00:00 2001 From: camsim99 Date: Wed, 21 Sep 2022 14:42:31 -0700 Subject: [PATCH 1/7] Remove allowedauthenticators where not needed --- .../plugins/localauth/AuthenticationHelper.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java index c30f879d2c7f..a1306a83f108 100644 --- a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java +++ b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java @@ -91,17 +91,12 @@ interface AuthCompletionHandler { .setConfirmationRequired((Boolean) call.argument("sensitiveTransaction")) .setConfirmationRequired((Boolean) call.argument("sensitiveTransaction")); - int allowedAuthenticators = - BiometricManager.Authenticators.BIOMETRIC_WEAK - | BiometricManager.Authenticators.BIOMETRIC_STRONG; - - if (allowCredentials) { - allowedAuthenticators |= BiometricManager.Authenticators.DEVICE_CREDENTIAL; - } else { + if (!allowCredentials) { + promptBuilder.setAllowedAuthenticators( + BiometricManager.Authenticators.BIOMETRIC_WEAK | BiometricManager.Authenticators.BIOMETRIC_STRONG); promptBuilder.setNegativeButtonText((String) call.argument("cancelButton")); } - promptBuilder.setAllowedAuthenticators(allowedAuthenticators); this.promptInfo = promptBuilder.build(); } From 76037c5366d76f452e94304904984ed4aa3c8aed Mon Sep 17 00:00:00 2001 From: camsim99 Date: Fri, 30 Sep 2022 13:46:27 -0700 Subject: [PATCH 2/7] Add fix --- .../plugins/localauth/AuthenticationHelper.java | 11 ++++++++--- .../io/flutter/plugins/localauth/LocalAuthPlugin.java | 4 +++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java index a1306a83f108..c30f879d2c7f 100644 --- a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java +++ b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java @@ -91,12 +91,17 @@ interface AuthCompletionHandler { .setConfirmationRequired((Boolean) call.argument("sensitiveTransaction")) .setConfirmationRequired((Boolean) call.argument("sensitiveTransaction")); - if (!allowCredentials) { - promptBuilder.setAllowedAuthenticators( - BiometricManager.Authenticators.BIOMETRIC_WEAK | BiometricManager.Authenticators.BIOMETRIC_STRONG); + int allowedAuthenticators = + BiometricManager.Authenticators.BIOMETRIC_WEAK + | BiometricManager.Authenticators.BIOMETRIC_STRONG; + + if (allowCredentials) { + allowedAuthenticators |= BiometricManager.Authenticators.DEVICE_CREDENTIAL; + } else { promptBuilder.setNegativeButtonText((String) call.argument("cancelButton")); } + promptBuilder.setAllowedAuthenticators(allowedAuthenticators); this.promptInfo = promptBuilder.build(); } diff --git a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java index e8632c474030..5b9a36967c5a 100644 --- a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java +++ b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java @@ -272,7 +272,9 @@ private boolean hasBiometricHardware() { private boolean canAuthenticateWithDeviceCredential() { if (biometricManager == null) return false; - return biometricManager.canAuthenticate(BiometricManager.Authenticators.DEVICE_CREDENTIAL) + // Only device credential authentication is not allowed before API 11, so check ability + // to authenticate both with device credential and biometric authentication. + return biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK | BiometricManager.Authenticators.DEVICE_CREDENTIAL ) == BiometricManager.BIOMETRIC_SUCCESS; } From 9ab5fe5675340ef60d0b4388c01cbc22e6b4d8b0 Mon Sep 17 00:00:00 2001 From: camsim99 Date: Fri, 30 Sep 2022 13:56:46 -0700 Subject: [PATCH 3/7] Modify fix --- .../io/flutter/plugins/localauth/LocalAuthPlugin.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java index 5b9a36967c5a..b5c49677c1c0 100644 --- a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java +++ b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java @@ -271,10 +271,14 @@ private boolean hasBiometricHardware() { } private boolean canAuthenticateWithDeviceCredential() { + if (Build.VERSION.SDK_INT < 30) { + // Checking/setting device credential only authentication is not allowed before API 11, + // so check for presence of PIN, pattern, or password instead. + return keyguardManager.isDeviceSecure(); + } + if (biometricManager == null) return false; - // Only device credential authentication is not allowed before API 11, so check ability - // to authenticate both with device credential and biometric authentication. - return biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK | BiometricManager.Authenticators.DEVICE_CREDENTIAL ) + return biometricManager.canAuthenticate(BiometricManager.Authenticators.DEVICE_CREDENTIAL) == BiometricManager.BIOMETRIC_SUCCESS; } From 878b826fe8d0254124bd31ca1ce16bd70b3deab1 Mon Sep 17 00:00:00 2001 From: camsim99 Date: Fri, 30 Sep 2022 14:01:19 -0700 Subject: [PATCH 4/7] Add null check --- .../main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java index b5c49677c1c0..615438b0c75b 100644 --- a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java +++ b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java @@ -274,6 +274,7 @@ private boolean canAuthenticateWithDeviceCredential() { if (Build.VERSION.SDK_INT < 30) { // Checking/setting device credential only authentication is not allowed before API 11, // so check for presence of PIN, pattern, or password instead. + if (keyguardManager == null) return false; return keyguardManager.isDeviceSecure(); } From 90bbba26c5d906aefdc3012aba40bd2e40e76ecf Mon Sep 17 00:00:00 2001 From: camsim99 Date: Mon, 17 Oct 2022 09:58:03 -0700 Subject: [PATCH 5/7] Dev --- .../local_auth_android/CHANGELOG.md | 4 ++ .../local_auth_android/android/build.gradle | 3 +- .../plugins/localauth/LocalAuthPlugin.java | 19 +++++-- .../plugins/localauth/LocalAuthTest.java | 55 +++++++++++++++++++ .../local_auth_android/pubspec.yaml | 2 +- 5 files changed, 76 insertions(+), 7 deletions(-) diff --git a/packages/local_auth/local_auth_android/CHANGELOG.md b/packages/local_auth/local_auth_android/CHANGELOG.md index 5a94fac16fe8..4dd0f1e94c3d 100644 --- a/packages/local_auth/local_auth_android/CHANGELOG.md +++ b/packages/local_auth/local_auth_android/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.13 + +* Fixes device credential authentication for API versions less than R. + ## 1.0.12 * Updates androidx.fragment version to 1.5.2. diff --git a/packages/local_auth/local_auth_android/android/build.gradle b/packages/local_auth/local_auth_android/android/build.gradle index 399d8a4fbb45..3d393baddb56 100644 --- a/packages/local_auth/local_auth_android/android/build.gradle +++ b/packages/local_auth/local_auth_android/android/build.gradle @@ -53,7 +53,8 @@ dependencies { api "androidx.biometric:biometric:1.1.0" api "androidx.fragment:fragment:1.5.2" testImplementation 'junit:junit:4.13.2' - testImplementation 'org.mockito:mockito-inline:4.7.0' + testImplementation 'org.mockito:mockito-inline:4.8.0' + testImplementation 'org.robolectric:robolectric:4.8.1' androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test:rules:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' diff --git a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java index 615438b0c75b..b99b45464cbe 100644 --- a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java +++ b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java @@ -252,12 +252,16 @@ public ArrayList getEnrolledBiometrics() { return biometrics; } - @VisibleForTesting - public boolean isDeviceSupported() { + private boolean isDeviceSecure() { if (keyguardManager == null) return false; return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && keyguardManager.isDeviceSecure()); } + @VisibleForTesting + public boolean isDeviceSupported() { + return isDeviceSecure() || canAuthenticateWithBiometrics(); + } + private boolean canAuthenticateWithBiometrics() { if (biometricManager == null) return false; return biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK) @@ -270,12 +274,12 @@ private boolean hasBiometricHardware() { != BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE; } - private boolean canAuthenticateWithDeviceCredential() { + @VisibleForTesting + public boolean canAuthenticateWithDeviceCredential() { if (Build.VERSION.SDK_INT < 30) { // Checking/setting device credential only authentication is not allowed before API 11, // so check for presence of PIN, pattern, or password instead. - if (keyguardManager == null) return false; - return keyguardManager.isDeviceSecure(); + return isDeviceSecure(); } if (biometricManager == null) return false; @@ -341,4 +345,9 @@ final Activity getActivity() { void setBiometricManager(BiometricManager biometricManager) { this.biometricManager = biometricManager; } + + @VisibleForTesting + void setKeyguardManager(KeyguardManager keyguardManager) { + this.keyguardManager = keyguardManager; + } } diff --git a/packages/local_auth/local_auth_android/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java b/packages/local_auth/local_auth_android/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java index 0eaf31255317..39be03910780 100644 --- a/packages/local_auth/local_auth_android/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java +++ b/packages/local_auth/local_auth_android/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java @@ -17,6 +17,7 @@ import static org.mockito.Mockito.when; import android.app.Activity; +import android.app.KeyguardManager; import android.app.NativeActivity; import android.content.Context; import androidx.biometric.BiometricManager; @@ -35,7 +36,10 @@ import java.util.HashMap; import org.junit.Test; import org.mockito.ArgumentCaptor; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; +@RunWith(RobolectricTestRunner.class) public class LocalAuthTest { @Test public void authenticate_returnsErrorWhenAuthInProgress() { @@ -111,6 +115,7 @@ public void authenticate_properlyConfiguresBiometricAndDeviceCredentialAuthentic final LocalAuthPlugin plugin = spy(new LocalAuthPlugin()); setPluginActivity(plugin, buildMockActivityWithContext(mock(FragmentActivity.class))); when(plugin.isDeviceSupported()).thenReturn(true); + when(plugin.canAuthenticateWithDeviceCredential()).thenReturn(true); final BiometricManager mockBiometricManager = mock(BiometricManager.class); when(mockBiometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK)) @@ -139,6 +144,7 @@ public void authenticate_properlyConfiguresDeviceCredentialOnlyAuthenticationReq final LocalAuthPlugin plugin = spy(new LocalAuthPlugin()); setPluginActivity(plugin, buildMockActivityWithContext(mock(FragmentActivity.class))); when(plugin.isDeviceSupported()).thenReturn(true); + when(plugin.canAuthenticateWithDeviceCredential()).thenReturn(true); final BiometricManager mockBiometricManager = mock(BiometricManager.class); when(mockBiometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK)) @@ -343,6 +349,55 @@ public void getEnrolledBiometrics_shouldAddStrongBiometrics() { }); } + @Test + @Config(maxSdk = 22) + public void isDeviceSecure_returnsFalseOnBelowApi23() { + final LocalAuthPlugin plugin = new LocalAuthPlugin(); + assertFalse(plugin.isDeviceSecure()); + } + + @Test + @Config(minSdk = 23) + public void isDeviceSecure_returnsTrueIfDeviceIsSecure() { + final LocalAuthPlugin plugin = new LocalAuthPlugin(); + KeyguardManager mockKeyguardManager = mock(KeyguardManager.class); + plugin.setKeyguardManager(mockKeyguardManager); + + when(mockKeyguardManager.isDeviceSecure()).thenReturn(true); + assertTrue(plugin.isDeviceSecure()); + + when(mockKeyguardManager.isDeviceSecure()).thenReturn(false); + assertFalse(plugin.isDeviceSecure()); + } + + @Test + @Config(maxSdk = 29) + public void canAuthenticateWithDeviceCredential_returnsTrueIfDeviceIsSecureOnBelowApi30() { + final LocalAuthPlugin plugin = new LocalAuthPlugin(); + + when(plugin.isDeviceSecure()).thenReturn(true); + assertTrue(plugin.canAuthenticateWithDeviceCredential()); + + when(plugin.isDeviceSecure()).thenReturn(false); + assertFalse(plugin.canAuthenticateWithDeviceCredential()); + } + + @Test + @Config(minSdk = 30) + public void canAuthenticateWithDeviceCredential_returnsTrueIfHasBiometricManagerSupportAboveApi30() { + final LocalAuthPlugin plugin = new LocalAuthPlugin(); + final BiometricManager mockBiometricManager = mock(BiometricManager.class); + plugin.setBiometricManager(mockBiometricManager); + + when(mockBiometricManager.canAuthenticate(BiometricManager.Authenticators.DEVICE_CREDENTIAL)) + .thenReturn(BiometricManager.BIOMETRIC_SUCCESS); + assertTrue(plugin.canAuthenticateWithDeviceCredential()); + + when(mockBiometricManager.canAuthenticate(BiometricManager.Authenticators.DEVICE_CREDENTIAL)) + .thenReturn(BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED); + assertFalse(plugin.canAuthenticateWithDeviceCredential()); + } + private Activity buildMockActivityWithContext(Activity mockActivity) { final Context mockContext = mock(Context.class); when(mockActivity.getBaseContext()).thenReturn(mockContext); diff --git a/packages/local_auth/local_auth_android/pubspec.yaml b/packages/local_auth/local_auth_android/pubspec.yaml index d621874106b3..35c2d3af983c 100644 --- a/packages/local_auth/local_auth_android/pubspec.yaml +++ b/packages/local_auth/local_auth_android/pubspec.yaml @@ -2,7 +2,7 @@ name: local_auth_android description: Android implementation of the local_auth plugin. repository: https://github.com/flutter/plugins/tree/main/packages/local_auth/local_auth_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+local_auth%22 -version: 1.0.12 +version: 1.0.13 environment: sdk: ">=2.14.0 <3.0.0" From 8f68071de93b0db6c7cb0512be6868efffbacf68 Mon Sep 17 00:00:00 2001 From: camsim99 Date: Mon, 17 Oct 2022 12:55:29 -0700 Subject: [PATCH 6/7] Fix test --- .../local_auth_android/android/build.gradle | 4 ++-- .../flutter/plugins/localauth/LocalAuthPlugin.java | 3 ++- .../flutter/plugins/localauth/LocalAuthTest.java | 14 ++++++++------ 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/packages/local_auth/local_auth_android/android/build.gradle b/packages/local_auth/local_auth_android/android/build.gradle index 63d5471c583e..6c9417008d27 100644 --- a/packages/local_auth/local_auth_android/android/build.gradle +++ b/packages/local_auth/local_auth_android/android/build.gradle @@ -55,8 +55,8 @@ dependencies { api "androidx.biometric:biometric:1.1.0" api "androidx.fragment:fragment:1.5.2" testImplementation 'junit:junit:4.13.2' - testImplementation 'org.mockito:mockito-inline:4.8.0' - testImplementation 'org.robolectric:robolectric:4.8.1' + testImplementation 'org.mockito:mockito-inline:4.7.0' + testImplementation 'org.robolectric:robolectric:4.5' androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test:rules:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' diff --git a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java index b99b45464cbe..5fa9a60aa7f1 100644 --- a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java +++ b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java @@ -252,7 +252,8 @@ public ArrayList getEnrolledBiometrics() { return biometrics; } - private boolean isDeviceSecure() { + @VisibleForTesting + public boolean isDeviceSecure() { if (keyguardManager == null) return false; return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && keyguardManager.isDeviceSecure()); } diff --git a/packages/local_auth/local_auth_android/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java b/packages/local_auth/local_auth_android/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java index 39be03910780..cc79c86ac64e 100644 --- a/packages/local_auth/local_auth_android/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java +++ b/packages/local_auth/local_auth_android/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java @@ -35,6 +35,7 @@ import java.util.Collections; import java.util.HashMap; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; @@ -350,14 +351,14 @@ public void getEnrolledBiometrics_shouldAddStrongBiometrics() { } @Test - @Config(maxSdk = 22) + @Config(sdk = 22) public void isDeviceSecure_returnsFalseOnBelowApi23() { final LocalAuthPlugin plugin = new LocalAuthPlugin(); assertFalse(plugin.isDeviceSecure()); } @Test - @Config(minSdk = 23) + @Config(sdk = 23) public void isDeviceSecure_returnsTrueIfDeviceIsSecure() { final LocalAuthPlugin plugin = new LocalAuthPlugin(); KeyguardManager mockKeyguardManager = mock(KeyguardManager.class); @@ -371,9 +372,9 @@ public void isDeviceSecure_returnsTrueIfDeviceIsSecure() { } @Test - @Config(maxSdk = 29) + @Config(sdk = 29) public void canAuthenticateWithDeviceCredential_returnsTrueIfDeviceIsSecureOnBelowApi30() { - final LocalAuthPlugin plugin = new LocalAuthPlugin(); + final LocalAuthPlugin plugin = spy(new LocalAuthPlugin()); when(plugin.isDeviceSecure()).thenReturn(true); assertTrue(plugin.canAuthenticateWithDeviceCredential()); @@ -383,8 +384,9 @@ public void canAuthenticateWithDeviceCredential_returnsTrueIfDeviceIsSecureOnBel } @Test - @Config(minSdk = 30) - public void canAuthenticateWithDeviceCredential_returnsTrueIfHasBiometricManagerSupportAboveApi30() { + @Config(sdk = 30) + public void + canAuthenticateWithDeviceCredential_returnsTrueIfHasBiometricManagerSupportAboveApi30() { final LocalAuthPlugin plugin = new LocalAuthPlugin(); final BiometricManager mockBiometricManager = mock(BiometricManager.class); plugin.setBiometricManager(mockBiometricManager); From b430bed8c04a25f0646d8c0080711fdd34117080 Mon Sep 17 00:00:00 2001 From: camsim99 Date: Thu, 20 Oct 2022 09:57:02 -0700 Subject: [PATCH 7/7] Revisions --- .../local_auth/local_auth_android/CHANGELOG.md | 2 +- .../plugins/localauth/LocalAuthPlugin.java | 5 +++-- .../plugins/localauth/LocalAuthTest.java | 18 ++---------------- 3 files changed, 6 insertions(+), 19 deletions(-) diff --git a/packages/local_auth/local_auth_android/CHANGELOG.md b/packages/local_auth/local_auth_android/CHANGELOG.md index 043800f8a44a..c9eeed9d01dd 100644 --- a/packages/local_auth/local_auth_android/CHANGELOG.md +++ b/packages/local_auth/local_auth_android/CHANGELOG.md @@ -1,6 +1,6 @@ ## 1.0.14 -* Fixes device credential authentication for API versions less than R. +* Fixes device credential authentication for API versions before R. ## 1.0.13 diff --git a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java index 5fa9a60aa7f1..e545df01e7c0 100644 --- a/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java +++ b/packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java @@ -278,8 +278,9 @@ private boolean hasBiometricHardware() { @VisibleForTesting public boolean canAuthenticateWithDeviceCredential() { if (Build.VERSION.SDK_INT < 30) { - // Checking/setting device credential only authentication is not allowed before API 11, - // so check for presence of PIN, pattern, or password instead. + // Checking for device credential only authentication via the BiometricManager + // is not allowed before API level 30, so we check for presence of PIN, pattern, + // or password instead. return isDeviceSecure(); } diff --git a/packages/local_auth/local_auth_android/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java b/packages/local_auth/local_auth_android/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java index cc79c86ac64e..7279a3c49af2 100644 --- a/packages/local_auth/local_auth_android/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java +++ b/packages/local_auth/local_auth_android/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java @@ -112,15 +112,13 @@ public void authenticate_properlyConfiguresBiometricOnlyAuthenticationRequest() } @Test + @Config(sdk = 30) public void authenticate_properlyConfiguresBiometricAndDeviceCredentialAuthenticationRequest() { final LocalAuthPlugin plugin = spy(new LocalAuthPlugin()); setPluginActivity(plugin, buildMockActivityWithContext(mock(FragmentActivity.class))); when(plugin.isDeviceSupported()).thenReturn(true); - when(plugin.canAuthenticateWithDeviceCredential()).thenReturn(true); final BiometricManager mockBiometricManager = mock(BiometricManager.class); - when(mockBiometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK)) - .thenReturn(BiometricManager.BIOMETRIC_SUCCESS); when(mockBiometricManager.canAuthenticate(BiometricManager.Authenticators.DEVICE_CREDENTIAL)) .thenReturn(BiometricManager.BIOMETRIC_SUCCESS); plugin.setBiometricManager(mockBiometricManager); @@ -141,11 +139,11 @@ public void authenticate_properlyConfiguresBiometricAndDeviceCredentialAuthentic } @Test + @Config(sdk = 30) public void authenticate_properlyConfiguresDeviceCredentialOnlyAuthenticationRequest() { final LocalAuthPlugin plugin = spy(new LocalAuthPlugin()); setPluginActivity(plugin, buildMockActivityWithContext(mock(FragmentActivity.class))); when(plugin.isDeviceSupported()).thenReturn(true); - when(plugin.canAuthenticateWithDeviceCredential()).thenReturn(true); final BiometricManager mockBiometricManager = mock(BiometricManager.class); when(mockBiometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK)) @@ -371,18 +369,6 @@ public void isDeviceSecure_returnsTrueIfDeviceIsSecure() { assertFalse(plugin.isDeviceSecure()); } - @Test - @Config(sdk = 29) - public void canAuthenticateWithDeviceCredential_returnsTrueIfDeviceIsSecureOnBelowApi30() { - final LocalAuthPlugin plugin = spy(new LocalAuthPlugin()); - - when(plugin.isDeviceSecure()).thenReturn(true); - assertTrue(plugin.canAuthenticateWithDeviceCredential()); - - when(plugin.isDeviceSecure()).thenReturn(false); - assertFalse(plugin.canAuthenticateWithDeviceCredential()); - } - @Test @Config(sdk = 30) public void