From 94c4904d145798c752c9bd9991f47dcccee8a3ea Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Wed, 26 Jan 2022 14:39:13 +0100 Subject: [PATCH 01/36] Add platform interface for local_auth plugin to prepare for federated architecture --- packages/local_auth/{ => local_auth}/AUTHORS | 0 .../local_auth/{ => local_auth}/CHANGELOG.md | 0 packages/local_auth/{ => local_auth}/LICENSE | 0 .../local_auth/{ => local_auth}/README.md | 0 .../{ => local_auth}/android/build.gradle | 0 .../android/lint-baseline.xml | 0 .../{ => local_auth}/android/settings.gradle | 0 .../android/src/main/AndroidManifest.xml | 0 .../localauth/AuthenticationHelper.java | 0 .../plugins/localauth/LocalAuthPlugin.java | 0 .../res/drawable/fingerprint_initial_icon.xml | 0 .../res/drawable/fingerprint_success_icon.xml | 0 .../res/drawable/fingerprint_warning_icon.xml | 0 .../main/res/drawable/ic_done_white_24dp.xml | 0 .../drawable/ic_fingerprint_white_24dp.xml | 0 .../drawable/ic_priority_high_white_24dp.xml | 0 .../src/main/res/layout/go_to_setting.xml | 0 .../android/src/main/res/layout/scan_fp.xml | 0 .../android/src/main/res/values/colors.xml | 0 .../android/src/main/res/values/dimens.xml | 0 .../android/src/main/res/values/styles.xml | 0 .../plugins/localauth/LocalAuthTest.java | 0 .../{ => local_auth}/example/README.md | 0 .../example/android/app/build.gradle | 0 .../gradle/wrapper/gradle-wrapper.properties | 0 .../flutter/plugins/DartIntegrationTest.java | 0 .../FlutterFragmentActivityTest.java | 0 .../android/app/src/main/AndroidManifest.xml | 0 .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin .../example/android/build.gradle | 0 .../example/android/gradle.properties | 0 .../gradle/wrapper/gradle-wrapper.properties | 0 .../example/android/settings.gradle | 0 .../example/android/settings_aar.gradle | 0 .../integration_test/local_auth_test.dart | 0 .../ios/Flutter/AppFrameworkInfo.plist | 0 .../example/ios/Flutter/Debug.xcconfig | 0 .../example/ios/Flutter/Release.xcconfig | 0 .../{ => local_auth}/example/ios/Podfile | 0 .../ios/Runner.xcodeproj/project.pbxproj | 0 .../contents.xcworkspacedata | 0 .../xcshareddata/xcschemes/Runner.xcscheme | 0 .../contents.xcworkspacedata | 0 .../xcshareddata/IDEWorkspaceChecks.plist | 0 .../example/ios/Runner/AppDelegate.h | 0 .../example/ios/Runner/AppDelegate.m | 0 .../AppIcon.appiconset/Contents.json | 0 .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin .../Icon-App-83.5x83.5@2x.png | Bin .../Runner/Base.lproj/LaunchScreen.storyboard | 0 .../ios/Runner/Base.lproj/Main.storyboard | 0 .../example/ios/Runner/Info.plist | 0 .../example/ios/Runner/main.m | 0 .../ios/RunnerTests/FLTLocalAuthPluginTests.m | 0 .../example/ios/RunnerTests/Info.plist | 0 .../{ => local_auth}/example/lib/main.dart | 0 .../{ => local_auth}/example/pubspec.yaml | 0 .../example/test_driver/integration_test.dart | 0 .../{ => local_auth}/ios/Assets/.gitkeep | 0 .../ios/Classes/FLTLocalAuthPlugin.h | 0 .../ios/Classes/FLTLocalAuthPlugin.m | 0 .../{ => local_auth}/ios/local_auth.podspec | 0 .../{ => local_auth}/lib/auth_strings.dart | 0 .../{ => local_auth}/lib/error_codes.dart | 0 .../{ => local_auth}/lib/local_auth.dart | 0 .../local_auth/{ => local_auth}/pubspec.yaml | 0 .../test/local_auth_test.dart | 0 .../local_auth_platform_interface/AUTHORS | 67 ++++++++++ .../CHANGELOG.md | 3 + .../local_auth_platform_interface/LICENSE | 25 ++++ .../local_auth_platform_interface/README.md | 26 ++++ .../analysis_options.yaml | 4 + .../lib/local_auth_platform_interface.dart | 116 ++++++++++++++++++ .../lib/types/auth_strings.dart | 10 ++ .../lib/types/biometric_type.dart | 5 + .../pubspec.yaml | 22 ++++ 92 files changed, 278 insertions(+) rename packages/local_auth/{ => local_auth}/AUTHORS (100%) rename packages/local_auth/{ => local_auth}/CHANGELOG.md (100%) rename packages/local_auth/{ => local_auth}/LICENSE (100%) rename packages/local_auth/{ => local_auth}/README.md (100%) rename packages/local_auth/{ => local_auth}/android/build.gradle (100%) rename packages/local_auth/{ => local_auth}/android/lint-baseline.xml (100%) rename packages/local_auth/{ => local_auth}/android/settings.gradle (100%) rename packages/local_auth/{ => local_auth}/android/src/main/AndroidManifest.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java (100%) rename packages/local_auth/{ => local_auth}/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java (100%) rename packages/local_auth/{ => local_auth}/android/src/main/res/drawable/fingerprint_initial_icon.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/main/res/drawable/fingerprint_success_icon.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/main/res/drawable/fingerprint_warning_icon.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/main/res/drawable/ic_done_white_24dp.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/main/res/drawable/ic_fingerprint_white_24dp.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/main/res/drawable/ic_priority_high_white_24dp.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/main/res/layout/go_to_setting.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/main/res/layout/scan_fp.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/main/res/values/colors.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/main/res/values/dimens.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/main/res/values/styles.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java (100%) rename packages/local_auth/{ => local_auth}/example/README.md (100%) rename packages/local_auth/{ => local_auth}/example/android/app/build.gradle (100%) rename packages/local_auth/{ => local_auth}/example/android/app/gradle/wrapper/gradle-wrapper.properties (100%) rename packages/local_auth/{ => local_auth}/example/android/app/src/androidTest/java/io/flutter/plugins/DartIntegrationTest.java (100%) rename packages/local_auth/{ => local_auth}/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java (100%) rename packages/local_auth/{ => local_auth}/example/android/app/src/main/AndroidManifest.xml (100%) rename packages/local_auth/{ => local_auth}/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png (100%) rename packages/local_auth/{ => local_auth}/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png (100%) rename packages/local_auth/{ => local_auth}/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png (100%) rename packages/local_auth/{ => local_auth}/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png (100%) rename packages/local_auth/{ => local_auth}/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png (100%) rename packages/local_auth/{ => local_auth}/example/android/build.gradle (100%) rename packages/local_auth/{ => local_auth}/example/android/gradle.properties (100%) rename packages/local_auth/{ => local_auth}/example/android/gradle/wrapper/gradle-wrapper.properties (100%) rename packages/local_auth/{ => local_auth}/example/android/settings.gradle (100%) rename packages/local_auth/{ => local_auth}/example/android/settings_aar.gradle (100%) rename packages/local_auth/{ => local_auth}/example/integration_test/local_auth_test.dart (100%) rename packages/local_auth/{ => local_auth}/example/ios/Flutter/AppFrameworkInfo.plist (100%) rename packages/local_auth/{ => local_auth}/example/ios/Flutter/Debug.xcconfig (100%) rename packages/local_auth/{ => local_auth}/example/ios/Flutter/Release.xcconfig (100%) rename packages/local_auth/{ => local_auth}/example/ios/Podfile (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner.xcodeproj/project.pbxproj (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner.xcworkspace/contents.xcworkspacedata (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/AppDelegate.h (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/AppDelegate.m (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Base.lproj/LaunchScreen.storyboard (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Base.lproj/Main.storyboard (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Info.plist (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/main.m (100%) rename packages/local_auth/{ => local_auth}/example/ios/RunnerTests/FLTLocalAuthPluginTests.m (100%) rename packages/local_auth/{ => local_auth}/example/ios/RunnerTests/Info.plist (100%) rename packages/local_auth/{ => local_auth}/example/lib/main.dart (100%) rename packages/local_auth/{ => local_auth}/example/pubspec.yaml (100%) rename packages/local_auth/{ => local_auth}/example/test_driver/integration_test.dart (100%) rename packages/local_auth/{ => local_auth}/ios/Assets/.gitkeep (100%) rename packages/local_auth/{ => local_auth}/ios/Classes/FLTLocalAuthPlugin.h (100%) rename packages/local_auth/{ => local_auth}/ios/Classes/FLTLocalAuthPlugin.m (100%) rename packages/local_auth/{ => local_auth}/ios/local_auth.podspec (100%) rename packages/local_auth/{ => local_auth}/lib/auth_strings.dart (100%) rename packages/local_auth/{ => local_auth}/lib/error_codes.dart (100%) rename packages/local_auth/{ => local_auth}/lib/local_auth.dart (100%) rename packages/local_auth/{ => local_auth}/pubspec.yaml (100%) rename packages/local_auth/{ => local_auth}/test/local_auth_test.dart (100%) create mode 100644 packages/local_auth/local_auth_platform_interface/AUTHORS create mode 100644 packages/local_auth/local_auth_platform_interface/CHANGELOG.md create mode 100644 packages/local_auth/local_auth_platform_interface/LICENSE create mode 100644 packages/local_auth/local_auth_platform_interface/README.md create mode 100644 packages/local_auth/local_auth_platform_interface/analysis_options.yaml create mode 100644 packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart create mode 100644 packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart create mode 100644 packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart create mode 100644 packages/local_auth/local_auth_platform_interface/pubspec.yaml diff --git a/packages/local_auth/AUTHORS b/packages/local_auth/local_auth/AUTHORS similarity index 100% rename from packages/local_auth/AUTHORS rename to packages/local_auth/local_auth/AUTHORS diff --git a/packages/local_auth/CHANGELOG.md b/packages/local_auth/local_auth/CHANGELOG.md similarity index 100% rename from packages/local_auth/CHANGELOG.md rename to packages/local_auth/local_auth/CHANGELOG.md diff --git a/packages/local_auth/LICENSE b/packages/local_auth/local_auth/LICENSE similarity index 100% rename from packages/local_auth/LICENSE rename to packages/local_auth/local_auth/LICENSE diff --git a/packages/local_auth/README.md b/packages/local_auth/local_auth/README.md similarity index 100% rename from packages/local_auth/README.md rename to packages/local_auth/local_auth/README.md diff --git a/packages/local_auth/android/build.gradle b/packages/local_auth/local_auth/android/build.gradle similarity index 100% rename from packages/local_auth/android/build.gradle rename to packages/local_auth/local_auth/android/build.gradle diff --git a/packages/local_auth/android/lint-baseline.xml b/packages/local_auth/local_auth/android/lint-baseline.xml similarity index 100% rename from packages/local_auth/android/lint-baseline.xml rename to packages/local_auth/local_auth/android/lint-baseline.xml diff --git a/packages/local_auth/android/settings.gradle b/packages/local_auth/local_auth/android/settings.gradle similarity index 100% rename from packages/local_auth/android/settings.gradle rename to packages/local_auth/local_auth/android/settings.gradle diff --git a/packages/local_auth/android/src/main/AndroidManifest.xml b/packages/local_auth/local_auth/android/src/main/AndroidManifest.xml similarity index 100% rename from packages/local_auth/android/src/main/AndroidManifest.xml rename to packages/local_auth/local_auth/android/src/main/AndroidManifest.xml diff --git a/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java b/packages/local_auth/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java similarity index 100% rename from packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java rename to packages/local_auth/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java diff --git a/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java b/packages/local_auth/local_auth/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java similarity index 100% rename from packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java rename to packages/local_auth/local_auth/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java diff --git a/packages/local_auth/android/src/main/res/drawable/fingerprint_initial_icon.xml b/packages/local_auth/local_auth/android/src/main/res/drawable/fingerprint_initial_icon.xml similarity index 100% rename from packages/local_auth/android/src/main/res/drawable/fingerprint_initial_icon.xml rename to packages/local_auth/local_auth/android/src/main/res/drawable/fingerprint_initial_icon.xml diff --git a/packages/local_auth/android/src/main/res/drawable/fingerprint_success_icon.xml b/packages/local_auth/local_auth/android/src/main/res/drawable/fingerprint_success_icon.xml similarity index 100% rename from packages/local_auth/android/src/main/res/drawable/fingerprint_success_icon.xml rename to packages/local_auth/local_auth/android/src/main/res/drawable/fingerprint_success_icon.xml diff --git a/packages/local_auth/android/src/main/res/drawable/fingerprint_warning_icon.xml b/packages/local_auth/local_auth/android/src/main/res/drawable/fingerprint_warning_icon.xml similarity index 100% rename from packages/local_auth/android/src/main/res/drawable/fingerprint_warning_icon.xml rename to packages/local_auth/local_auth/android/src/main/res/drawable/fingerprint_warning_icon.xml diff --git a/packages/local_auth/android/src/main/res/drawable/ic_done_white_24dp.xml b/packages/local_auth/local_auth/android/src/main/res/drawable/ic_done_white_24dp.xml similarity index 100% rename from packages/local_auth/android/src/main/res/drawable/ic_done_white_24dp.xml rename to packages/local_auth/local_auth/android/src/main/res/drawable/ic_done_white_24dp.xml diff --git a/packages/local_auth/android/src/main/res/drawable/ic_fingerprint_white_24dp.xml b/packages/local_auth/local_auth/android/src/main/res/drawable/ic_fingerprint_white_24dp.xml similarity index 100% rename from packages/local_auth/android/src/main/res/drawable/ic_fingerprint_white_24dp.xml rename to packages/local_auth/local_auth/android/src/main/res/drawable/ic_fingerprint_white_24dp.xml diff --git a/packages/local_auth/android/src/main/res/drawable/ic_priority_high_white_24dp.xml b/packages/local_auth/local_auth/android/src/main/res/drawable/ic_priority_high_white_24dp.xml similarity index 100% rename from packages/local_auth/android/src/main/res/drawable/ic_priority_high_white_24dp.xml rename to packages/local_auth/local_auth/android/src/main/res/drawable/ic_priority_high_white_24dp.xml diff --git a/packages/local_auth/android/src/main/res/layout/go_to_setting.xml b/packages/local_auth/local_auth/android/src/main/res/layout/go_to_setting.xml similarity index 100% rename from packages/local_auth/android/src/main/res/layout/go_to_setting.xml rename to packages/local_auth/local_auth/android/src/main/res/layout/go_to_setting.xml diff --git a/packages/local_auth/android/src/main/res/layout/scan_fp.xml b/packages/local_auth/local_auth/android/src/main/res/layout/scan_fp.xml similarity index 100% rename from packages/local_auth/android/src/main/res/layout/scan_fp.xml rename to packages/local_auth/local_auth/android/src/main/res/layout/scan_fp.xml diff --git a/packages/local_auth/android/src/main/res/values/colors.xml b/packages/local_auth/local_auth/android/src/main/res/values/colors.xml similarity index 100% rename from packages/local_auth/android/src/main/res/values/colors.xml rename to packages/local_auth/local_auth/android/src/main/res/values/colors.xml diff --git a/packages/local_auth/android/src/main/res/values/dimens.xml b/packages/local_auth/local_auth/android/src/main/res/values/dimens.xml similarity index 100% rename from packages/local_auth/android/src/main/res/values/dimens.xml rename to packages/local_auth/local_auth/android/src/main/res/values/dimens.xml diff --git a/packages/local_auth/android/src/main/res/values/styles.xml b/packages/local_auth/local_auth/android/src/main/res/values/styles.xml similarity index 100% rename from packages/local_auth/android/src/main/res/values/styles.xml rename to packages/local_auth/local_auth/android/src/main/res/values/styles.xml diff --git a/packages/local_auth/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java b/packages/local_auth/local_auth/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java similarity index 100% rename from packages/local_auth/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java rename to packages/local_auth/local_auth/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java diff --git a/packages/local_auth/example/README.md b/packages/local_auth/local_auth/example/README.md similarity index 100% rename from packages/local_auth/example/README.md rename to packages/local_auth/local_auth/example/README.md diff --git a/packages/local_auth/example/android/app/build.gradle b/packages/local_auth/local_auth/example/android/app/build.gradle similarity index 100% rename from packages/local_auth/example/android/app/build.gradle rename to packages/local_auth/local_auth/example/android/app/build.gradle diff --git a/packages/local_auth/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/local_auth/local_auth/example/android/app/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from packages/local_auth/example/android/app/gradle/wrapper/gradle-wrapper.properties rename to packages/local_auth/local_auth/example/android/app/gradle/wrapper/gradle-wrapper.properties diff --git a/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/DartIntegrationTest.java b/packages/local_auth/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/DartIntegrationTest.java similarity index 100% rename from packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/DartIntegrationTest.java rename to packages/local_auth/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/DartIntegrationTest.java diff --git a/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java b/packages/local_auth/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java similarity index 100% rename from packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java rename to packages/local_auth/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java diff --git a/packages/local_auth/example/android/app/src/main/AndroidManifest.xml b/packages/local_auth/local_auth/example/android/app/src/main/AndroidManifest.xml similarity index 100% rename from packages/local_auth/example/android/app/src/main/AndroidManifest.xml rename to packages/local_auth/local_auth/example/android/app/src/main/AndroidManifest.xml diff --git a/packages/local_auth/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/packages/local_auth/local_auth/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from packages/local_auth/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png rename to packages/local_auth/local_auth/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/packages/local_auth/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/packages/local_auth/local_auth/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from packages/local_auth/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png rename to packages/local_auth/local_auth/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/packages/local_auth/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/packages/local_auth/local_auth/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from packages/local_auth/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png rename to packages/local_auth/local_auth/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/packages/local_auth/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/packages/local_auth/local_auth/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from packages/local_auth/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png rename to packages/local_auth/local_auth/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/packages/local_auth/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/packages/local_auth/local_auth/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from packages/local_auth/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png rename to packages/local_auth/local_auth/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/packages/local_auth/example/android/build.gradle b/packages/local_auth/local_auth/example/android/build.gradle similarity index 100% rename from packages/local_auth/example/android/build.gradle rename to packages/local_auth/local_auth/example/android/build.gradle diff --git a/packages/local_auth/example/android/gradle.properties b/packages/local_auth/local_auth/example/android/gradle.properties similarity index 100% rename from packages/local_auth/example/android/gradle.properties rename to packages/local_auth/local_auth/example/android/gradle.properties diff --git a/packages/local_auth/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/local_auth/local_auth/example/android/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from packages/local_auth/example/android/gradle/wrapper/gradle-wrapper.properties rename to packages/local_auth/local_auth/example/android/gradle/wrapper/gradle-wrapper.properties diff --git a/packages/local_auth/example/android/settings.gradle b/packages/local_auth/local_auth/example/android/settings.gradle similarity index 100% rename from packages/local_auth/example/android/settings.gradle rename to packages/local_auth/local_auth/example/android/settings.gradle diff --git a/packages/local_auth/example/android/settings_aar.gradle b/packages/local_auth/local_auth/example/android/settings_aar.gradle similarity index 100% rename from packages/local_auth/example/android/settings_aar.gradle rename to packages/local_auth/local_auth/example/android/settings_aar.gradle diff --git a/packages/local_auth/example/integration_test/local_auth_test.dart b/packages/local_auth/local_auth/example/integration_test/local_auth_test.dart similarity index 100% rename from packages/local_auth/example/integration_test/local_auth_test.dart rename to packages/local_auth/local_auth/example/integration_test/local_auth_test.dart diff --git a/packages/local_auth/example/ios/Flutter/AppFrameworkInfo.plist b/packages/local_auth/local_auth/example/ios/Flutter/AppFrameworkInfo.plist similarity index 100% rename from packages/local_auth/example/ios/Flutter/AppFrameworkInfo.plist rename to packages/local_auth/local_auth/example/ios/Flutter/AppFrameworkInfo.plist diff --git a/packages/local_auth/example/ios/Flutter/Debug.xcconfig b/packages/local_auth/local_auth/example/ios/Flutter/Debug.xcconfig similarity index 100% rename from packages/local_auth/example/ios/Flutter/Debug.xcconfig rename to packages/local_auth/local_auth/example/ios/Flutter/Debug.xcconfig diff --git a/packages/local_auth/example/ios/Flutter/Release.xcconfig b/packages/local_auth/local_auth/example/ios/Flutter/Release.xcconfig similarity index 100% rename from packages/local_auth/example/ios/Flutter/Release.xcconfig rename to packages/local_auth/local_auth/example/ios/Flutter/Release.xcconfig diff --git a/packages/local_auth/example/ios/Podfile b/packages/local_auth/local_auth/example/ios/Podfile similarity index 100% rename from packages/local_auth/example/ios/Podfile rename to packages/local_auth/local_auth/example/ios/Podfile diff --git a/packages/local_auth/example/ios/Runner.xcodeproj/project.pbxproj b/packages/local_auth/local_auth/example/ios/Runner.xcodeproj/project.pbxproj similarity index 100% rename from packages/local_auth/example/ios/Runner.xcodeproj/project.pbxproj rename to packages/local_auth/local_auth/example/ios/Runner.xcodeproj/project.pbxproj diff --git a/packages/local_auth/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/local_auth/local_auth/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from packages/local_auth/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to packages/local_auth/local_auth/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/packages/local_auth/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/local_auth/local_auth/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme similarity index 100% rename from packages/local_auth/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme rename to packages/local_auth/local_auth/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme diff --git a/packages/local_auth/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/local_auth/local_auth/example/ios/Runner.xcworkspace/contents.xcworkspacedata similarity index 100% rename from packages/local_auth/example/ios/Runner.xcworkspace/contents.xcworkspacedata rename to packages/local_auth/local_auth/example/ios/Runner.xcworkspace/contents.xcworkspacedata diff --git a/packages/local_auth/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/local_auth/local_auth/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from packages/local_auth/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to packages/local_auth/local_auth/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/packages/local_auth/example/ios/Runner/AppDelegate.h b/packages/local_auth/local_auth/example/ios/Runner/AppDelegate.h similarity index 100% rename from packages/local_auth/example/ios/Runner/AppDelegate.h rename to packages/local_auth/local_auth/example/ios/Runner/AppDelegate.h diff --git a/packages/local_auth/example/ios/Runner/AppDelegate.m b/packages/local_auth/local_auth/example/ios/Runner/AppDelegate.m similarity index 100% rename from packages/local_auth/example/ios/Runner/AppDelegate.m rename to packages/local_auth/local_auth/example/ios/Runner/AppDelegate.m diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png diff --git a/packages/local_auth/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/packages/local_auth/local_auth/example/ios/Runner/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from packages/local_auth/example/ios/Runner/Base.lproj/LaunchScreen.storyboard rename to packages/local_auth/local_auth/example/ios/Runner/Base.lproj/LaunchScreen.storyboard diff --git a/packages/local_auth/example/ios/Runner/Base.lproj/Main.storyboard b/packages/local_auth/local_auth/example/ios/Runner/Base.lproj/Main.storyboard similarity index 100% rename from packages/local_auth/example/ios/Runner/Base.lproj/Main.storyboard rename to packages/local_auth/local_auth/example/ios/Runner/Base.lproj/Main.storyboard diff --git a/packages/local_auth/example/ios/Runner/Info.plist b/packages/local_auth/local_auth/example/ios/Runner/Info.plist similarity index 100% rename from packages/local_auth/example/ios/Runner/Info.plist rename to packages/local_auth/local_auth/example/ios/Runner/Info.plist diff --git a/packages/local_auth/example/ios/Runner/main.m b/packages/local_auth/local_auth/example/ios/Runner/main.m similarity index 100% rename from packages/local_auth/example/ios/Runner/main.m rename to packages/local_auth/local_auth/example/ios/Runner/main.m diff --git a/packages/local_auth/example/ios/RunnerTests/FLTLocalAuthPluginTests.m b/packages/local_auth/local_auth/example/ios/RunnerTests/FLTLocalAuthPluginTests.m similarity index 100% rename from packages/local_auth/example/ios/RunnerTests/FLTLocalAuthPluginTests.m rename to packages/local_auth/local_auth/example/ios/RunnerTests/FLTLocalAuthPluginTests.m diff --git a/packages/local_auth/example/ios/RunnerTests/Info.plist b/packages/local_auth/local_auth/example/ios/RunnerTests/Info.plist similarity index 100% rename from packages/local_auth/example/ios/RunnerTests/Info.plist rename to packages/local_auth/local_auth/example/ios/RunnerTests/Info.plist diff --git a/packages/local_auth/example/lib/main.dart b/packages/local_auth/local_auth/example/lib/main.dart similarity index 100% rename from packages/local_auth/example/lib/main.dart rename to packages/local_auth/local_auth/example/lib/main.dart diff --git a/packages/local_auth/example/pubspec.yaml b/packages/local_auth/local_auth/example/pubspec.yaml similarity index 100% rename from packages/local_auth/example/pubspec.yaml rename to packages/local_auth/local_auth/example/pubspec.yaml diff --git a/packages/local_auth/example/test_driver/integration_test.dart b/packages/local_auth/local_auth/example/test_driver/integration_test.dart similarity index 100% rename from packages/local_auth/example/test_driver/integration_test.dart rename to packages/local_auth/local_auth/example/test_driver/integration_test.dart diff --git a/packages/local_auth/ios/Assets/.gitkeep b/packages/local_auth/local_auth/ios/Assets/.gitkeep similarity index 100% rename from packages/local_auth/ios/Assets/.gitkeep rename to packages/local_auth/local_auth/ios/Assets/.gitkeep diff --git a/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.h b/packages/local_auth/local_auth/ios/Classes/FLTLocalAuthPlugin.h similarity index 100% rename from packages/local_auth/ios/Classes/FLTLocalAuthPlugin.h rename to packages/local_auth/local_auth/ios/Classes/FLTLocalAuthPlugin.h diff --git a/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.m b/packages/local_auth/local_auth/ios/Classes/FLTLocalAuthPlugin.m similarity index 100% rename from packages/local_auth/ios/Classes/FLTLocalAuthPlugin.m rename to packages/local_auth/local_auth/ios/Classes/FLTLocalAuthPlugin.m diff --git a/packages/local_auth/ios/local_auth.podspec b/packages/local_auth/local_auth/ios/local_auth.podspec similarity index 100% rename from packages/local_auth/ios/local_auth.podspec rename to packages/local_auth/local_auth/ios/local_auth.podspec diff --git a/packages/local_auth/lib/auth_strings.dart b/packages/local_auth/local_auth/lib/auth_strings.dart similarity index 100% rename from packages/local_auth/lib/auth_strings.dart rename to packages/local_auth/local_auth/lib/auth_strings.dart diff --git a/packages/local_auth/lib/error_codes.dart b/packages/local_auth/local_auth/lib/error_codes.dart similarity index 100% rename from packages/local_auth/lib/error_codes.dart rename to packages/local_auth/local_auth/lib/error_codes.dart diff --git a/packages/local_auth/lib/local_auth.dart b/packages/local_auth/local_auth/lib/local_auth.dart similarity index 100% rename from packages/local_auth/lib/local_auth.dart rename to packages/local_auth/local_auth/lib/local_auth.dart diff --git a/packages/local_auth/pubspec.yaml b/packages/local_auth/local_auth/pubspec.yaml similarity index 100% rename from packages/local_auth/pubspec.yaml rename to packages/local_auth/local_auth/pubspec.yaml diff --git a/packages/local_auth/test/local_auth_test.dart b/packages/local_auth/local_auth/test/local_auth_test.dart similarity index 100% rename from packages/local_auth/test/local_auth_test.dart rename to packages/local_auth/local_auth/test/local_auth_test.dart diff --git a/packages/local_auth/local_auth_platform_interface/AUTHORS b/packages/local_auth/local_auth_platform_interface/AUTHORS new file mode 100644 index 000000000000..d5694690c247 --- /dev/null +++ b/packages/local_auth/local_auth_platform_interface/AUTHORS @@ -0,0 +1,67 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +The Chromium Authors +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> +Bodhi Mulders diff --git a/packages/local_auth/local_auth_platform_interface/CHANGELOG.md b/packages/local_auth/local_auth_platform_interface/CHANGELOG.md new file mode 100644 index 000000000000..0d8803f93540 --- /dev/null +++ b/packages/local_auth/local_auth_platform_interface/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.0 + +* Initial release. diff --git a/packages/local_auth/local_auth_platform_interface/LICENSE b/packages/local_auth/local_auth_platform_interface/LICENSE new file mode 100644 index 000000000000..c6823b81eb84 --- /dev/null +++ b/packages/local_auth/local_auth_platform_interface/LICENSE @@ -0,0 +1,25 @@ +Copyright 2013 The Flutter Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/local_auth/local_auth_platform_interface/README.md b/packages/local_auth/local_auth_platform_interface/README.md new file mode 100644 index 000000000000..3b01ced7b93b --- /dev/null +++ b/packages/local_auth/local_auth_platform_interface/README.md @@ -0,0 +1,26 @@ +# local_auth_platform_interface + +A common platform interface for the [`local_auth`][1] plugin. + +This interface allows platform-specific implementations of the `local_auth` +plugin, as well as the plugin itself, to ensure they are supporting the +same interface. + +# Usage + +To implement a new platform-specific implementation of `local_auth`, extend +[`LocalAuthPlatform`][2] with an implementation that performs the +platform-specific behavior, and when you register your plugin, set the default +`LocalAuthPlatform` by calling +`LocalAuthPlatform.instance = MyLocalAuthPlatform()`. + +# Note on breaking changes + +Strongly prefer non-breaking changes (such as adding a method to the interface) +over breaking changes for this package. + +See https://flutter.dev/go/platform-interface-breaking-changes for a discussion +on why a less-clean interface is preferable to a breaking change. + +[1]: ../local_auth +[2]: lib/local_auth_platform_interface.dart diff --git a/packages/local_auth/local_auth_platform_interface/analysis_options.yaml b/packages/local_auth/local_auth_platform_interface/analysis_options.yaml new file mode 100644 index 000000000000..a5744c1cfbe7 --- /dev/null +++ b/packages/local_auth/local_auth_platform_interface/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart b/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart new file mode 100644 index 000000000000..833004b7e032 --- /dev/null +++ b/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart @@ -0,0 +1,116 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:local_auth_platform_interface/types/biometric_type.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +/// The interface that implementations of local_auth must implement. +/// +/// Platform implementations should extend this class rather than implement it as `local_auth` +/// does not consider newly added methods to be breaking changes. Extending this class +/// (using `extends`) ensures that the subclass will get the default implementation, while +/// platform implementations that `implements` this interface will be broken by newly added +/// [LocalAuthPlatform] methods. +abstract class LocalAuthPlatform extends PlatformInterface { + /// Constructs a LocalAuthPlatform. + LocalAuthPlatform() : super(token: _token); + + static final Object _token = Object(); + + static LocalAuthPlatform _instance = DefaultLocalAuthPlatform(); + + /// The default instance of [LocalAuthPlatform] to use. + /// + /// Defaults to [DefaultLocalAuthPlatform]. + static LocalAuthPlatform get instance => _instance; + + /// Platform-specific plugins should set this with their own platform-specific + /// class that extends [LocalAuthPlatform] when they register themselves. + static set instance(LocalAuthPlatform instance) { + PlatformInterface.verifyToken(instance, _token); + _instance = instance; + } + + /// Authenticates the user with biometrics available on the device while also + /// allowing the user to use device authentication - pin, pattern, passcode. + /// + /// Returns a [Future] holding true, if the user successfully authenticated, + /// false otherwise. + /// + /// [localizedReason] is the message to show to user while prompting them + /// for authentication. This is typically along the lines of: 'Please scan + /// your finger to access MyApp.'. This must not be empty. + /// + /// [useErrorDialogs] = true means the system will attempt to handle user + /// fixable issues encountered while authenticating. For instance, if + /// fingerprint reader exists on the phone but there's no fingerprint + /// registered, the plugin will attempt to take the user to settings to add + /// one. Anything that is not user fixable, such as no biometric sensor on + /// device, will be returned as a [PlatformException]. + /// + /// [stickyAuth] is used when the application goes into background for any + /// reason while the authentication is in progress. Due to security reasons, + /// the authentication has to be stopped at that time. If stickyAuth is set + /// to true, authentication resumes when the app is resumed. If it is set to + /// false (default), then as soon as app is paused a failure message is sent + /// back to Dart and it is up to the client app to restart authentication or + /// do something else. + /// + /// Provide [authStrings] if you want to + /// customize messages in the dialogs. + /// + /// Setting [sensitiveTransaction] to true enables platform specific + /// precautions. For instance, on face unlock, Android opens a confirmation + /// dialog after the face is recognized to make sure the user meant to unlock + /// their phone. + /// + /// Setting [biometricOnly] to true prevents authenticates from using non-biometric + /// local authentication such as pin, passcode, and passcode. + /// + /// Throws an [PlatformException] if there were technical problems with local + /// authentication (e.g. lack of relevant hardware). This might throw + /// [PlatformException] with error code [otherOperatingSystem] on the iOS + /// simulator. + Future authenticate({ + required String localizedReason, + bool useErrorDialogs = true, + bool stickyAuth = false, + required Map authStrings, + bool sensitiveTransaction = true, + bool biometricOnly = false, + }) async { + throw UnimplementedError('authenticate() has not been implemented.'); + } + + /// Returns a list of enrolled biometrics. + /// + /// Returns a [Future] List with the following possibilities: + /// - BiometricType.face + /// - BiometricType.fingerprint + /// - BiometricType.iris (not yet implemented) + Future> getAvailableBiometrics() async { + throw UnimplementedError( + 'getAvailableBiometrics() has not been implemented.'); + } + + /// Returns true if device is capable of checking biometrics or is able to + /// fail over to device credentials. + /// + /// Returns a [Future] bool true or false: + Future isDeviceSupported() async { + throw UnimplementedError('isDeviceSupported() has not been implemented.'); + } + + /// Returns true if auth was cancelled successfully. + /// Returns false if there was some error or no auth in progress. + /// + /// Returns [Future] bool true or false: + Future stopAuthentication() async { + throw UnimplementedError('stopAuthentication() has not been implemented.'); + } +} + +/// The default interface implementation acting as a placeholder for +/// the native implementation to be set. +class DefaultLocalAuthPlatform extends LocalAuthPlatform {} diff --git a/packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart b/packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart new file mode 100644 index 000000000000..0ad81392edb9 --- /dev/null +++ b/packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart @@ -0,0 +1,10 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:intl/intl.dart'; + +String get goToSettings => Intl.message('Go to settings', + desc: 'Message showed on a button that the user can click to go to ' + 'settings pages from the current dialog. It is used on both Android ' + 'and iOS side. Maximum 30 characters.'); diff --git a/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart b/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart new file mode 100644 index 000000000000..23556ab37caa --- /dev/null +++ b/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart @@ -0,0 +1,5 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +enum BiometricType { face, fingerprint, iris } diff --git a/packages/local_auth/local_auth_platform_interface/pubspec.yaml b/packages/local_auth/local_auth_platform_interface/pubspec.yaml new file mode 100644 index 000000000000..0f88856bf4ee --- /dev/null +++ b/packages/local_auth/local_auth_platform_interface/pubspec.yaml @@ -0,0 +1,22 @@ +name: local_auth_platform_interface +description: A common platform interface for the local_auth plugin. +repository: https://github.com/flutter/plugins/tree/master/packages/local_auth/local_auth_platform_interface +issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22 +# NOTE: We strongly prefer non-breaking changes, even at the expense of a +# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes +version: 1.0.0 + +environment: + sdk: ">=2.14.0 <3.0.0" + flutter: ">=2.8.0" + +dependencies: + flutter: + sdk: flutter + plugin_platform_interface: ^2.1.2 + intl: ^0.17.0 + +dev_dependencies: + flutter_test: + sdk: flutter + mockito: ^5.0.0 \ No newline at end of file From 414d74b8147700a4df47deac089f2f96e800ee11 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Wed, 26 Jan 2022 15:11:37 +0100 Subject: [PATCH 02/36] Fix format --- packages/local_auth/local_auth/pubspec.yaml | 2 +- packages/local_auth/local_auth_platform_interface/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/local_auth/local_auth/pubspec.yaml b/packages/local_auth/local_auth/pubspec.yaml index 08215c566040..cd9d0d9760f4 100644 --- a/packages/local_auth/local_auth/pubspec.yaml +++ b/packages/local_auth/local_auth/pubspec.yaml @@ -1,7 +1,7 @@ name: local_auth description: Flutter plugin for Android and iOS devices to allow local authentication via fingerprint, touch ID, face ID, passcode, pin, or pattern. -repository: https://github.com/flutter/plugins/tree/main/packages/local_auth +repository: https://github.com/flutter/plugins/tree/main/packages/local_auth/local_auth issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+local_auth%22 version: 1.1.10 diff --git a/packages/local_auth/local_auth_platform_interface/pubspec.yaml b/packages/local_auth/local_auth_platform_interface/pubspec.yaml index 0f88856bf4ee..cdc8f3d31a0c 100644 --- a/packages/local_auth/local_auth_platform_interface/pubspec.yaml +++ b/packages/local_auth/local_auth_platform_interface/pubspec.yaml @@ -1,7 +1,7 @@ name: local_auth_platform_interface description: A common platform interface for the local_auth plugin. repository: https://github.com/flutter/plugins/tree/master/packages/local_auth/local_auth_platform_interface -issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22 +issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+local_auth%22 # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes version: 1.0.0 From c35fd925c2e1179be3d1197c97cce6a0a86c70f7 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Wed, 26 Jan 2022 15:20:24 +0100 Subject: [PATCH 03/36] Fix analysis issues --- .../analysis_options.yaml | 4 ---- .../lib/types/auth_strings.dart | 7 +++++-- .../lib/types/biometric_type.dart | 10 +++++++++- .../local_auth_platform_interface/pubspec.yaml | 2 +- 4 files changed, 15 insertions(+), 8 deletions(-) delete mode 100644 packages/local_auth/local_auth_platform_interface/analysis_options.yaml diff --git a/packages/local_auth/local_auth_platform_interface/analysis_options.yaml b/packages/local_auth/local_auth_platform_interface/analysis_options.yaml deleted file mode 100644 index a5744c1cfbe7..000000000000 --- a/packages/local_auth/local_auth_platform_interface/analysis_options.yaml +++ /dev/null @@ -1,4 +0,0 @@ -include: package:flutter_lints/flutter.yaml - -# Additional information about this file can be found at -# https://dart.dev/guides/language/analysis-options diff --git a/packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart b/packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart index 0ad81392edb9..be75ea1fe880 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart @@ -4,7 +4,10 @@ import 'package:intl/intl.dart'; +/// Message shown on a button that the user can click to go to settings pages +/// from the current dialog. It is used on both Android and iOS sides. +/// Maximum 30 characters. String get goToSettings => Intl.message('Go to settings', - desc: 'Message showed on a button that the user can click to go to ' + desc: 'Message shown on a button that the user can click to go to ' 'settings pages from the current dialog. It is used on both Android ' - 'and iOS side. Maximum 30 characters.'); + 'and iOS sides. Maximum 30 characters.'); diff --git a/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart b/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart index 23556ab37caa..84a75cc4c3c5 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart @@ -2,4 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -enum BiometricType { face, fingerprint, iris } +/// Various types of biometric authentication. +enum BiometricType { + /// Face authentication. + face, + /// Fingerprint authentication. + fingerprint, + /// Iris authentication. + iris, +} diff --git a/packages/local_auth/local_auth_platform_interface/pubspec.yaml b/packages/local_auth/local_auth_platform_interface/pubspec.yaml index cdc8f3d31a0c..f04268926ebd 100644 --- a/packages/local_auth/local_auth_platform_interface/pubspec.yaml +++ b/packages/local_auth/local_auth_platform_interface/pubspec.yaml @@ -13,8 +13,8 @@ environment: dependencies: flutter: sdk: flutter - plugin_platform_interface: ^2.1.2 intl: ^0.17.0 + plugin_platform_interface: ^2.1.2 dev_dependencies: flutter_test: From 2c6a9a9dec8eb7be78741e63d4228e692a534b6d Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Wed, 26 Jan 2022 15:24:32 +0100 Subject: [PATCH 04/36] Fix format --- .../local_auth_platform_interface/lib/types/biometric_type.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart b/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart index 84a75cc4c3c5..4265b5ef9ad1 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart @@ -6,8 +6,10 @@ enum BiometricType { /// Face authentication. face, + /// Fingerprint authentication. fingerprint, + /// Iris authentication. iris, } From bd35a9f9b606fab56ebb03985f2bc967a52d449b Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Thu, 27 Jan 2022 10:00:30 +0100 Subject: [PATCH 05/36] Move local_auth plugin into a subfolder in preparation for federation migration --- packages/local_auth/{ => local_auth}/AUTHORS | 0 packages/local_auth/{ => local_auth}/CHANGELOG.md | 0 packages/local_auth/{ => local_auth}/LICENSE | 0 packages/local_auth/{ => local_auth}/README.md | 0 .../{ => local_auth}/android/build.gradle | 0 .../{ => local_auth}/android/lint-baseline.xml | 0 .../{ => local_auth}/android/settings.gradle | 0 .../android/src/main/AndroidManifest.xml | 0 .../plugins/localauth/AuthenticationHelper.java | 0 .../flutter/plugins/localauth/LocalAuthPlugin.java | 0 .../main/res/drawable/fingerprint_initial_icon.xml | 0 .../main/res/drawable/fingerprint_success_icon.xml | 0 .../main/res/drawable/fingerprint_warning_icon.xml | 0 .../src/main/res/drawable/ic_done_white_24dp.xml | 0 .../main/res/drawable/ic_fingerprint_white_24dp.xml | 0 .../res/drawable/ic_priority_high_white_24dp.xml | 0 .../android/src/main/res/layout/go_to_setting.xml | 0 .../android/src/main/res/layout/scan_fp.xml | 0 .../android/src/main/res/values/colors.xml | 0 .../android/src/main/res/values/dimens.xml | 0 .../android/src/main/res/values/styles.xml | 0 .../io/flutter/plugins/localauth/LocalAuthTest.java | 0 .../local_auth/{ => local_auth}/example/README.md | 0 .../example/android/app/build.gradle | 0 .../app/gradle/wrapper/gradle-wrapper.properties | 0 .../io/flutter/plugins/DartIntegrationTest.java | 0 .../localauth/FlutterFragmentActivityTest.java | 0 .../android/app/src/main/AndroidManifest.xml | 0 .../app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin .../app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin .../app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin .../app/src/main/res/mipmap-xxhdpi/ic_launcher.png | Bin .../app/src/main/res/mipmap-xxxhdpi/ic_launcher.png | Bin .../{ => local_auth}/example/android/build.gradle | 0 .../example/android/gradle.properties | 0 .../gradle/wrapper/gradle-wrapper.properties | 0 .../example/android/settings.gradle | 0 .../example/android/settings_aar.gradle | 0 .../example/integration_test/local_auth_test.dart | 0 .../example/ios/Flutter/AppFrameworkInfo.plist | 0 .../example/ios/Flutter/Debug.xcconfig | 0 .../example/ios/Flutter/Release.xcconfig | 0 .../local_auth/{ => local_auth}/example/ios/Podfile | 0 .../example/ios/Runner.xcodeproj/project.pbxproj | 0 .../project.xcworkspace/contents.xcworkspacedata | 0 .../xcshareddata/xcschemes/Runner.xcscheme | 0 .../ios/Runner.xcworkspace/contents.xcworkspacedata | 0 .../xcshareddata/IDEWorkspaceChecks.plist | 0 .../example/ios/Runner/AppDelegate.h | 0 .../example/ios/Runner/AppDelegate.m | 0 .../AppIcon.appiconset/Contents.json | 0 .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin .../AppIcon.appiconset/Icon-App-83.5x83.5@2x.png | Bin .../ios/Runner/Base.lproj/LaunchScreen.storyboard | 0 .../example/ios/Runner/Base.lproj/Main.storyboard | 0 .../{ => local_auth}/example/ios/Runner/Info.plist | 0 .../{ => local_auth}/example/ios/Runner/main.m | 0 .../ios/RunnerTests/FLTLocalAuthPluginTests.m | 0 .../example/ios/RunnerTests/Info.plist | 0 .../{ => local_auth}/example/lib/main.dart | 0 .../{ => local_auth}/example/pubspec.yaml | 0 .../example/test_driver/integration_test.dart | 0 .../local_auth/{ => local_auth}/ios/Assets/.gitkeep | 0 .../ios/Classes/FLTLocalAuthPlugin.h | 0 .../ios/Classes/FLTLocalAuthPlugin.m | 0 .../{ => local_auth}/ios/local_auth.podspec | 0 .../{ => local_auth}/lib/auth_strings.dart | 0 .../{ => local_auth}/lib/error_codes.dart | 0 .../local_auth/{ => local_auth}/lib/local_auth.dart | 0 packages/local_auth/{ => local_auth}/pubspec.yaml | 2 +- .../{ => local_auth}/test/local_auth_test.dart | 0 83 files changed, 1 insertion(+), 1 deletion(-) rename packages/local_auth/{ => local_auth}/AUTHORS (100%) rename packages/local_auth/{ => local_auth}/CHANGELOG.md (100%) rename packages/local_auth/{ => local_auth}/LICENSE (100%) rename packages/local_auth/{ => local_auth}/README.md (100%) rename packages/local_auth/{ => local_auth}/android/build.gradle (100%) rename packages/local_auth/{ => local_auth}/android/lint-baseline.xml (100%) rename packages/local_auth/{ => local_auth}/android/settings.gradle (100%) rename packages/local_auth/{ => local_auth}/android/src/main/AndroidManifest.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java (100%) rename packages/local_auth/{ => local_auth}/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java (100%) rename packages/local_auth/{ => local_auth}/android/src/main/res/drawable/fingerprint_initial_icon.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/main/res/drawable/fingerprint_success_icon.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/main/res/drawable/fingerprint_warning_icon.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/main/res/drawable/ic_done_white_24dp.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/main/res/drawable/ic_fingerprint_white_24dp.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/main/res/drawable/ic_priority_high_white_24dp.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/main/res/layout/go_to_setting.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/main/res/layout/scan_fp.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/main/res/values/colors.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/main/res/values/dimens.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/main/res/values/styles.xml (100%) rename packages/local_auth/{ => local_auth}/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java (100%) rename packages/local_auth/{ => local_auth}/example/README.md (100%) rename packages/local_auth/{ => local_auth}/example/android/app/build.gradle (100%) rename packages/local_auth/{ => local_auth}/example/android/app/gradle/wrapper/gradle-wrapper.properties (100%) rename packages/local_auth/{ => local_auth}/example/android/app/src/androidTest/java/io/flutter/plugins/DartIntegrationTest.java (100%) rename packages/local_auth/{ => local_auth}/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java (100%) rename packages/local_auth/{ => local_auth}/example/android/app/src/main/AndroidManifest.xml (100%) rename packages/local_auth/{ => local_auth}/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png (100%) rename packages/local_auth/{ => local_auth}/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png (100%) rename packages/local_auth/{ => local_auth}/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png (100%) rename packages/local_auth/{ => local_auth}/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png (100%) rename packages/local_auth/{ => local_auth}/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png (100%) rename packages/local_auth/{ => local_auth}/example/android/build.gradle (100%) rename packages/local_auth/{ => local_auth}/example/android/gradle.properties (100%) rename packages/local_auth/{ => local_auth}/example/android/gradle/wrapper/gradle-wrapper.properties (100%) rename packages/local_auth/{ => local_auth}/example/android/settings.gradle (100%) rename packages/local_auth/{ => local_auth}/example/android/settings_aar.gradle (100%) rename packages/local_auth/{ => local_auth}/example/integration_test/local_auth_test.dart (100%) rename packages/local_auth/{ => local_auth}/example/ios/Flutter/AppFrameworkInfo.plist (100%) rename packages/local_auth/{ => local_auth}/example/ios/Flutter/Debug.xcconfig (100%) rename packages/local_auth/{ => local_auth}/example/ios/Flutter/Release.xcconfig (100%) rename packages/local_auth/{ => local_auth}/example/ios/Podfile (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner.xcodeproj/project.pbxproj (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner.xcworkspace/contents.xcworkspacedata (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/AppDelegate.h (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/AppDelegate.m (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Base.lproj/LaunchScreen.storyboard (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Base.lproj/Main.storyboard (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/Info.plist (100%) rename packages/local_auth/{ => local_auth}/example/ios/Runner/main.m (100%) rename packages/local_auth/{ => local_auth}/example/ios/RunnerTests/FLTLocalAuthPluginTests.m (100%) rename packages/local_auth/{ => local_auth}/example/ios/RunnerTests/Info.plist (100%) rename packages/local_auth/{ => local_auth}/example/lib/main.dart (100%) rename packages/local_auth/{ => local_auth}/example/pubspec.yaml (100%) rename packages/local_auth/{ => local_auth}/example/test_driver/integration_test.dart (100%) rename packages/local_auth/{ => local_auth}/ios/Assets/.gitkeep (100%) rename packages/local_auth/{ => local_auth}/ios/Classes/FLTLocalAuthPlugin.h (100%) rename packages/local_auth/{ => local_auth}/ios/Classes/FLTLocalAuthPlugin.m (100%) rename packages/local_auth/{ => local_auth}/ios/local_auth.podspec (100%) rename packages/local_auth/{ => local_auth}/lib/auth_strings.dart (100%) rename packages/local_auth/{ => local_auth}/lib/error_codes.dart (100%) rename packages/local_auth/{ => local_auth}/lib/local_auth.dart (100%) rename packages/local_auth/{ => local_auth}/pubspec.yaml (97%) rename packages/local_auth/{ => local_auth}/test/local_auth_test.dart (100%) diff --git a/packages/local_auth/AUTHORS b/packages/local_auth/local_auth/AUTHORS similarity index 100% rename from packages/local_auth/AUTHORS rename to packages/local_auth/local_auth/AUTHORS diff --git a/packages/local_auth/CHANGELOG.md b/packages/local_auth/local_auth/CHANGELOG.md similarity index 100% rename from packages/local_auth/CHANGELOG.md rename to packages/local_auth/local_auth/CHANGELOG.md diff --git a/packages/local_auth/LICENSE b/packages/local_auth/local_auth/LICENSE similarity index 100% rename from packages/local_auth/LICENSE rename to packages/local_auth/local_auth/LICENSE diff --git a/packages/local_auth/README.md b/packages/local_auth/local_auth/README.md similarity index 100% rename from packages/local_auth/README.md rename to packages/local_auth/local_auth/README.md diff --git a/packages/local_auth/android/build.gradle b/packages/local_auth/local_auth/android/build.gradle similarity index 100% rename from packages/local_auth/android/build.gradle rename to packages/local_auth/local_auth/android/build.gradle diff --git a/packages/local_auth/android/lint-baseline.xml b/packages/local_auth/local_auth/android/lint-baseline.xml similarity index 100% rename from packages/local_auth/android/lint-baseline.xml rename to packages/local_auth/local_auth/android/lint-baseline.xml diff --git a/packages/local_auth/android/settings.gradle b/packages/local_auth/local_auth/android/settings.gradle similarity index 100% rename from packages/local_auth/android/settings.gradle rename to packages/local_auth/local_auth/android/settings.gradle diff --git a/packages/local_auth/android/src/main/AndroidManifest.xml b/packages/local_auth/local_auth/android/src/main/AndroidManifest.xml similarity index 100% rename from packages/local_auth/android/src/main/AndroidManifest.xml rename to packages/local_auth/local_auth/android/src/main/AndroidManifest.xml diff --git a/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java b/packages/local_auth/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java similarity index 100% rename from packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java rename to packages/local_auth/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java diff --git a/packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java b/packages/local_auth/local_auth/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java similarity index 100% rename from packages/local_auth/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java rename to packages/local_auth/local_auth/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java diff --git a/packages/local_auth/android/src/main/res/drawable/fingerprint_initial_icon.xml b/packages/local_auth/local_auth/android/src/main/res/drawable/fingerprint_initial_icon.xml similarity index 100% rename from packages/local_auth/android/src/main/res/drawable/fingerprint_initial_icon.xml rename to packages/local_auth/local_auth/android/src/main/res/drawable/fingerprint_initial_icon.xml diff --git a/packages/local_auth/android/src/main/res/drawable/fingerprint_success_icon.xml b/packages/local_auth/local_auth/android/src/main/res/drawable/fingerprint_success_icon.xml similarity index 100% rename from packages/local_auth/android/src/main/res/drawable/fingerprint_success_icon.xml rename to packages/local_auth/local_auth/android/src/main/res/drawable/fingerprint_success_icon.xml diff --git a/packages/local_auth/android/src/main/res/drawable/fingerprint_warning_icon.xml b/packages/local_auth/local_auth/android/src/main/res/drawable/fingerprint_warning_icon.xml similarity index 100% rename from packages/local_auth/android/src/main/res/drawable/fingerprint_warning_icon.xml rename to packages/local_auth/local_auth/android/src/main/res/drawable/fingerprint_warning_icon.xml diff --git a/packages/local_auth/android/src/main/res/drawable/ic_done_white_24dp.xml b/packages/local_auth/local_auth/android/src/main/res/drawable/ic_done_white_24dp.xml similarity index 100% rename from packages/local_auth/android/src/main/res/drawable/ic_done_white_24dp.xml rename to packages/local_auth/local_auth/android/src/main/res/drawable/ic_done_white_24dp.xml diff --git a/packages/local_auth/android/src/main/res/drawable/ic_fingerprint_white_24dp.xml b/packages/local_auth/local_auth/android/src/main/res/drawable/ic_fingerprint_white_24dp.xml similarity index 100% rename from packages/local_auth/android/src/main/res/drawable/ic_fingerprint_white_24dp.xml rename to packages/local_auth/local_auth/android/src/main/res/drawable/ic_fingerprint_white_24dp.xml diff --git a/packages/local_auth/android/src/main/res/drawable/ic_priority_high_white_24dp.xml b/packages/local_auth/local_auth/android/src/main/res/drawable/ic_priority_high_white_24dp.xml similarity index 100% rename from packages/local_auth/android/src/main/res/drawable/ic_priority_high_white_24dp.xml rename to packages/local_auth/local_auth/android/src/main/res/drawable/ic_priority_high_white_24dp.xml diff --git a/packages/local_auth/android/src/main/res/layout/go_to_setting.xml b/packages/local_auth/local_auth/android/src/main/res/layout/go_to_setting.xml similarity index 100% rename from packages/local_auth/android/src/main/res/layout/go_to_setting.xml rename to packages/local_auth/local_auth/android/src/main/res/layout/go_to_setting.xml diff --git a/packages/local_auth/android/src/main/res/layout/scan_fp.xml b/packages/local_auth/local_auth/android/src/main/res/layout/scan_fp.xml similarity index 100% rename from packages/local_auth/android/src/main/res/layout/scan_fp.xml rename to packages/local_auth/local_auth/android/src/main/res/layout/scan_fp.xml diff --git a/packages/local_auth/android/src/main/res/values/colors.xml b/packages/local_auth/local_auth/android/src/main/res/values/colors.xml similarity index 100% rename from packages/local_auth/android/src/main/res/values/colors.xml rename to packages/local_auth/local_auth/android/src/main/res/values/colors.xml diff --git a/packages/local_auth/android/src/main/res/values/dimens.xml b/packages/local_auth/local_auth/android/src/main/res/values/dimens.xml similarity index 100% rename from packages/local_auth/android/src/main/res/values/dimens.xml rename to packages/local_auth/local_auth/android/src/main/res/values/dimens.xml diff --git a/packages/local_auth/android/src/main/res/values/styles.xml b/packages/local_auth/local_auth/android/src/main/res/values/styles.xml similarity index 100% rename from packages/local_auth/android/src/main/res/values/styles.xml rename to packages/local_auth/local_auth/android/src/main/res/values/styles.xml diff --git a/packages/local_auth/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java b/packages/local_auth/local_auth/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java similarity index 100% rename from packages/local_auth/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java rename to packages/local_auth/local_auth/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java diff --git a/packages/local_auth/example/README.md b/packages/local_auth/local_auth/example/README.md similarity index 100% rename from packages/local_auth/example/README.md rename to packages/local_auth/local_auth/example/README.md diff --git a/packages/local_auth/example/android/app/build.gradle b/packages/local_auth/local_auth/example/android/app/build.gradle similarity index 100% rename from packages/local_auth/example/android/app/build.gradle rename to packages/local_auth/local_auth/example/android/app/build.gradle diff --git a/packages/local_auth/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/local_auth/local_auth/example/android/app/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from packages/local_auth/example/android/app/gradle/wrapper/gradle-wrapper.properties rename to packages/local_auth/local_auth/example/android/app/gradle/wrapper/gradle-wrapper.properties diff --git a/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/DartIntegrationTest.java b/packages/local_auth/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/DartIntegrationTest.java similarity index 100% rename from packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/DartIntegrationTest.java rename to packages/local_auth/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/DartIntegrationTest.java diff --git a/packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java b/packages/local_auth/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java similarity index 100% rename from packages/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java rename to packages/local_auth/local_auth/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java diff --git a/packages/local_auth/example/android/app/src/main/AndroidManifest.xml b/packages/local_auth/local_auth/example/android/app/src/main/AndroidManifest.xml similarity index 100% rename from packages/local_auth/example/android/app/src/main/AndroidManifest.xml rename to packages/local_auth/local_auth/example/android/app/src/main/AndroidManifest.xml diff --git a/packages/local_auth/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/packages/local_auth/local_auth/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from packages/local_auth/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png rename to packages/local_auth/local_auth/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/packages/local_auth/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/packages/local_auth/local_auth/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from packages/local_auth/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png rename to packages/local_auth/local_auth/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/packages/local_auth/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/packages/local_auth/local_auth/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from packages/local_auth/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png rename to packages/local_auth/local_auth/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/packages/local_auth/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/packages/local_auth/local_auth/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from packages/local_auth/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png rename to packages/local_auth/local_auth/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/packages/local_auth/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/packages/local_auth/local_auth/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from packages/local_auth/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png rename to packages/local_auth/local_auth/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/packages/local_auth/example/android/build.gradle b/packages/local_auth/local_auth/example/android/build.gradle similarity index 100% rename from packages/local_auth/example/android/build.gradle rename to packages/local_auth/local_auth/example/android/build.gradle diff --git a/packages/local_auth/example/android/gradle.properties b/packages/local_auth/local_auth/example/android/gradle.properties similarity index 100% rename from packages/local_auth/example/android/gradle.properties rename to packages/local_auth/local_auth/example/android/gradle.properties diff --git a/packages/local_auth/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/local_auth/local_auth/example/android/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from packages/local_auth/example/android/gradle/wrapper/gradle-wrapper.properties rename to packages/local_auth/local_auth/example/android/gradle/wrapper/gradle-wrapper.properties diff --git a/packages/local_auth/example/android/settings.gradle b/packages/local_auth/local_auth/example/android/settings.gradle similarity index 100% rename from packages/local_auth/example/android/settings.gradle rename to packages/local_auth/local_auth/example/android/settings.gradle diff --git a/packages/local_auth/example/android/settings_aar.gradle b/packages/local_auth/local_auth/example/android/settings_aar.gradle similarity index 100% rename from packages/local_auth/example/android/settings_aar.gradle rename to packages/local_auth/local_auth/example/android/settings_aar.gradle diff --git a/packages/local_auth/example/integration_test/local_auth_test.dart b/packages/local_auth/local_auth/example/integration_test/local_auth_test.dart similarity index 100% rename from packages/local_auth/example/integration_test/local_auth_test.dart rename to packages/local_auth/local_auth/example/integration_test/local_auth_test.dart diff --git a/packages/local_auth/example/ios/Flutter/AppFrameworkInfo.plist b/packages/local_auth/local_auth/example/ios/Flutter/AppFrameworkInfo.plist similarity index 100% rename from packages/local_auth/example/ios/Flutter/AppFrameworkInfo.plist rename to packages/local_auth/local_auth/example/ios/Flutter/AppFrameworkInfo.plist diff --git a/packages/local_auth/example/ios/Flutter/Debug.xcconfig b/packages/local_auth/local_auth/example/ios/Flutter/Debug.xcconfig similarity index 100% rename from packages/local_auth/example/ios/Flutter/Debug.xcconfig rename to packages/local_auth/local_auth/example/ios/Flutter/Debug.xcconfig diff --git a/packages/local_auth/example/ios/Flutter/Release.xcconfig b/packages/local_auth/local_auth/example/ios/Flutter/Release.xcconfig similarity index 100% rename from packages/local_auth/example/ios/Flutter/Release.xcconfig rename to packages/local_auth/local_auth/example/ios/Flutter/Release.xcconfig diff --git a/packages/local_auth/example/ios/Podfile b/packages/local_auth/local_auth/example/ios/Podfile similarity index 100% rename from packages/local_auth/example/ios/Podfile rename to packages/local_auth/local_auth/example/ios/Podfile diff --git a/packages/local_auth/example/ios/Runner.xcodeproj/project.pbxproj b/packages/local_auth/local_auth/example/ios/Runner.xcodeproj/project.pbxproj similarity index 100% rename from packages/local_auth/example/ios/Runner.xcodeproj/project.pbxproj rename to packages/local_auth/local_auth/example/ios/Runner.xcodeproj/project.pbxproj diff --git a/packages/local_auth/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/local_auth/local_auth/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from packages/local_auth/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to packages/local_auth/local_auth/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/packages/local_auth/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/local_auth/local_auth/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme similarity index 100% rename from packages/local_auth/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme rename to packages/local_auth/local_auth/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme diff --git a/packages/local_auth/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/local_auth/local_auth/example/ios/Runner.xcworkspace/contents.xcworkspacedata similarity index 100% rename from packages/local_auth/example/ios/Runner.xcworkspace/contents.xcworkspacedata rename to packages/local_auth/local_auth/example/ios/Runner.xcworkspace/contents.xcworkspacedata diff --git a/packages/local_auth/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/local_auth/local_auth/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from packages/local_auth/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to packages/local_auth/local_auth/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/packages/local_auth/example/ios/Runner/AppDelegate.h b/packages/local_auth/local_auth/example/ios/Runner/AppDelegate.h similarity index 100% rename from packages/local_auth/example/ios/Runner/AppDelegate.h rename to packages/local_auth/local_auth/example/ios/Runner/AppDelegate.h diff --git a/packages/local_auth/example/ios/Runner/AppDelegate.m b/packages/local_auth/local_auth/example/ios/Runner/AppDelegate.m similarity index 100% rename from packages/local_auth/example/ios/Runner/AppDelegate.m rename to packages/local_auth/local_auth/example/ios/Runner/AppDelegate.m diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png diff --git a/packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png similarity index 100% rename from packages/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png rename to packages/local_auth/local_auth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png diff --git a/packages/local_auth/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/packages/local_auth/local_auth/example/ios/Runner/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from packages/local_auth/example/ios/Runner/Base.lproj/LaunchScreen.storyboard rename to packages/local_auth/local_auth/example/ios/Runner/Base.lproj/LaunchScreen.storyboard diff --git a/packages/local_auth/example/ios/Runner/Base.lproj/Main.storyboard b/packages/local_auth/local_auth/example/ios/Runner/Base.lproj/Main.storyboard similarity index 100% rename from packages/local_auth/example/ios/Runner/Base.lproj/Main.storyboard rename to packages/local_auth/local_auth/example/ios/Runner/Base.lproj/Main.storyboard diff --git a/packages/local_auth/example/ios/Runner/Info.plist b/packages/local_auth/local_auth/example/ios/Runner/Info.plist similarity index 100% rename from packages/local_auth/example/ios/Runner/Info.plist rename to packages/local_auth/local_auth/example/ios/Runner/Info.plist diff --git a/packages/local_auth/example/ios/Runner/main.m b/packages/local_auth/local_auth/example/ios/Runner/main.m similarity index 100% rename from packages/local_auth/example/ios/Runner/main.m rename to packages/local_auth/local_auth/example/ios/Runner/main.m diff --git a/packages/local_auth/example/ios/RunnerTests/FLTLocalAuthPluginTests.m b/packages/local_auth/local_auth/example/ios/RunnerTests/FLTLocalAuthPluginTests.m similarity index 100% rename from packages/local_auth/example/ios/RunnerTests/FLTLocalAuthPluginTests.m rename to packages/local_auth/local_auth/example/ios/RunnerTests/FLTLocalAuthPluginTests.m diff --git a/packages/local_auth/example/ios/RunnerTests/Info.plist b/packages/local_auth/local_auth/example/ios/RunnerTests/Info.plist similarity index 100% rename from packages/local_auth/example/ios/RunnerTests/Info.plist rename to packages/local_auth/local_auth/example/ios/RunnerTests/Info.plist diff --git a/packages/local_auth/example/lib/main.dart b/packages/local_auth/local_auth/example/lib/main.dart similarity index 100% rename from packages/local_auth/example/lib/main.dart rename to packages/local_auth/local_auth/example/lib/main.dart diff --git a/packages/local_auth/example/pubspec.yaml b/packages/local_auth/local_auth/example/pubspec.yaml similarity index 100% rename from packages/local_auth/example/pubspec.yaml rename to packages/local_auth/local_auth/example/pubspec.yaml diff --git a/packages/local_auth/example/test_driver/integration_test.dart b/packages/local_auth/local_auth/example/test_driver/integration_test.dart similarity index 100% rename from packages/local_auth/example/test_driver/integration_test.dart rename to packages/local_auth/local_auth/example/test_driver/integration_test.dart diff --git a/packages/local_auth/ios/Assets/.gitkeep b/packages/local_auth/local_auth/ios/Assets/.gitkeep similarity index 100% rename from packages/local_auth/ios/Assets/.gitkeep rename to packages/local_auth/local_auth/ios/Assets/.gitkeep diff --git a/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.h b/packages/local_auth/local_auth/ios/Classes/FLTLocalAuthPlugin.h similarity index 100% rename from packages/local_auth/ios/Classes/FLTLocalAuthPlugin.h rename to packages/local_auth/local_auth/ios/Classes/FLTLocalAuthPlugin.h diff --git a/packages/local_auth/ios/Classes/FLTLocalAuthPlugin.m b/packages/local_auth/local_auth/ios/Classes/FLTLocalAuthPlugin.m similarity index 100% rename from packages/local_auth/ios/Classes/FLTLocalAuthPlugin.m rename to packages/local_auth/local_auth/ios/Classes/FLTLocalAuthPlugin.m diff --git a/packages/local_auth/ios/local_auth.podspec b/packages/local_auth/local_auth/ios/local_auth.podspec similarity index 100% rename from packages/local_auth/ios/local_auth.podspec rename to packages/local_auth/local_auth/ios/local_auth.podspec diff --git a/packages/local_auth/lib/auth_strings.dart b/packages/local_auth/local_auth/lib/auth_strings.dart similarity index 100% rename from packages/local_auth/lib/auth_strings.dart rename to packages/local_auth/local_auth/lib/auth_strings.dart diff --git a/packages/local_auth/lib/error_codes.dart b/packages/local_auth/local_auth/lib/error_codes.dart similarity index 100% rename from packages/local_auth/lib/error_codes.dart rename to packages/local_auth/local_auth/lib/error_codes.dart diff --git a/packages/local_auth/lib/local_auth.dart b/packages/local_auth/local_auth/lib/local_auth.dart similarity index 100% rename from packages/local_auth/lib/local_auth.dart rename to packages/local_auth/local_auth/lib/local_auth.dart diff --git a/packages/local_auth/pubspec.yaml b/packages/local_auth/local_auth/pubspec.yaml similarity index 97% rename from packages/local_auth/pubspec.yaml rename to packages/local_auth/local_auth/pubspec.yaml index 08215c566040..cd9d0d9760f4 100644 --- a/packages/local_auth/pubspec.yaml +++ b/packages/local_auth/local_auth/pubspec.yaml @@ -1,7 +1,7 @@ name: local_auth description: Flutter plugin for Android and iOS devices to allow local authentication via fingerprint, touch ID, face ID, passcode, pin, or pattern. -repository: https://github.com/flutter/plugins/tree/main/packages/local_auth +repository: https://github.com/flutter/plugins/tree/main/packages/local_auth/local_auth issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+local_auth%22 version: 1.1.10 diff --git a/packages/local_auth/test/local_auth_test.dart b/packages/local_auth/local_auth/test/local_auth_test.dart similarity index 100% rename from packages/local_auth/test/local_auth_test.dart rename to packages/local_auth/local_auth/test/local_auth_test.dart From e10bbb855c694527d353f7f81dda2b5ad0c3e8ae Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Thu, 27 Jan 2022 11:36:10 +0100 Subject: [PATCH 06/36] Process PR Feedback --- .../lib/default_method_channel_platform.dart | 65 +++++++ .../lib/local_auth_platform_interface.dart | 39 +--- .../lib/types/auth_options.dart | 40 ++++ .../lib/types/biometric_type.dart | 10 + ...default_methbod_channel_platform_test.dart | 172 ++++++++++++++++++ 5 files changed, 294 insertions(+), 32 deletions(-) create mode 100644 packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart create mode 100644 packages/local_auth/local_auth_platform_interface/lib/types/auth_options.dart create mode 100644 packages/local_auth/local_auth_platform_interface/test/default_methbod_channel_platform_test.dart diff --git a/packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart b/packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart new file mode 100644 index 000000000000..5256f3d6070d --- /dev/null +++ b/packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart @@ -0,0 +1,65 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/services.dart'; +import 'package:local_auth_platform_interface/local_auth_platform_interface.dart'; +import 'package:local_auth_platform_interface/types/auth_options.dart'; +import 'package:local_auth_platform_interface/types/biometric_type.dart'; + +const MethodChannel _channel = MethodChannel('plugins.flutter.io/local_auth'); + +/// The default interface implementation acting as a placeholder for +/// the native implementation to be set. +class DefaultLocalAuthPlatform extends LocalAuthPlatform { + @override + Future authenticate({ + required String localizedReason, + required Map authStrings, + AuthenticationOptions options = const AuthenticationOptions(), + }) async { + assert(localizedReason.isNotEmpty); + final Map args = { + 'localizedReason': localizedReason, + 'useErrorDialogs': options.useErrorDialogs, + 'stickyAuth': options.stickyAuth, + 'sensitiveTransaction': options.sensitiveTransaction, + 'biometricOnly': options.biometricOnly, + }; + args.addAll(authStrings); + return (await _channel.invokeMethod('authenticate', args)) ?? false; + } + + @override + Future> getAvailableBiometrics() async { + final List result = (await _channel.invokeListMethod( + 'getAvailableBiometrics', + )) ?? + []; + final List biometrics = []; + for (final String value in result) { + switch (value) { + case 'face': + biometrics.add(BiometricType.face); + break; + case 'fingerprint': + biometrics.add(BiometricType.fingerprint); + break; + case 'iris': + biometrics.add(BiometricType.iris); + break; + case 'undefined': + break; + } + } + return biometrics; + } + + @override + Future isDeviceSupported() async => + (await _channel.invokeMethod('isDeviceSupported')) ?? false; + + @override + Future stopAuthentication() async => + await _channel.invokeMethod('stopAuthentication') ?? false; +} diff --git a/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart b/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart index 833004b7e032..32f039e86063 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:local_auth_platform_interface/default_method_channel_platform.dart'; +import 'package:local_auth_platform_interface/types/auth_options.dart'; import 'package:local_auth_platform_interface/types/biometric_type.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; @@ -25,8 +27,9 @@ abstract class LocalAuthPlatform extends PlatformInterface { /// Defaults to [DefaultLocalAuthPlatform]. static LocalAuthPlatform get instance => _instance; - /// Platform-specific plugins should set this with their own platform-specific - /// class that extends [LocalAuthPlatform] when they register themselves. + /// Platform-specific implementations should set this with their own + /// platform-specific class that extends [LocalAuthPlatform] when they + /// register themselves. static set instance(LocalAuthPlatform instance) { PlatformInterface.verifyToken(instance, _token); _instance = instance; @@ -42,31 +45,10 @@ abstract class LocalAuthPlatform extends PlatformInterface { /// for authentication. This is typically along the lines of: 'Please scan /// your finger to access MyApp.'. This must not be empty. /// - /// [useErrorDialogs] = true means the system will attempt to handle user - /// fixable issues encountered while authenticating. For instance, if - /// fingerprint reader exists on the phone but there's no fingerprint - /// registered, the plugin will attempt to take the user to settings to add - /// one. Anything that is not user fixable, such as no biometric sensor on - /// device, will be returned as a [PlatformException]. - /// - /// [stickyAuth] is used when the application goes into background for any - /// reason while the authentication is in progress. Due to security reasons, - /// the authentication has to be stopped at that time. If stickyAuth is set - /// to true, authentication resumes when the app is resumed. If it is set to - /// false (default), then as soon as app is paused a failure message is sent - /// back to Dart and it is up to the client app to restart authentication or - /// do something else. - /// /// Provide [authStrings] if you want to /// customize messages in the dialogs. /// - /// Setting [sensitiveTransaction] to true enables platform specific - /// precautions. For instance, on face unlock, Android opens a confirmation - /// dialog after the face is recognized to make sure the user meant to unlock - /// their phone. - /// - /// Setting [biometricOnly] to true prevents authenticates from using non-biometric - /// local authentication such as pin, passcode, and passcode. + /// Provide [options] for configuring further authentication related options. /// /// Throws an [PlatformException] if there were technical problems with local /// authentication (e.g. lack of relevant hardware). This might throw @@ -74,11 +56,8 @@ abstract class LocalAuthPlatform extends PlatformInterface { /// simulator. Future authenticate({ required String localizedReason, - bool useErrorDialogs = true, - bool stickyAuth = false, required Map authStrings, - bool sensitiveTransaction = true, - bool biometricOnly = false, + AuthenticationOptions options = const AuthenticationOptions(), }) async { throw UnimplementedError('authenticate() has not been implemented.'); } @@ -110,7 +89,3 @@ abstract class LocalAuthPlatform extends PlatformInterface { throw UnimplementedError('stopAuthentication() has not been implemented.'); } } - -/// The default interface implementation acting as a placeholder for -/// the native implementation to be set. -class DefaultLocalAuthPlatform extends LocalAuthPlatform {} diff --git a/packages/local_auth/local_auth_platform_interface/lib/types/auth_options.dart b/packages/local_auth/local_auth_platform_interface/lib/types/auth_options.dart new file mode 100644 index 000000000000..8a8efc6c2411 --- /dev/null +++ b/packages/local_auth/local_auth_platform_interface/lib/types/auth_options.dart @@ -0,0 +1,40 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/// Options wrapper for [LocalAuthPlatform.authenticate] parameters. +class AuthenticationOptions { + /// Construct a new instance. + const AuthenticationOptions({ + this.useErrorDialogs = true, + this.stickyAuth = false, + this.sensitiveTransaction = true, + this.biometricOnly = false, + }); + + /// Whether the system will attempt to handle user fixable issues encountered + /// while authenticating. For instance, if fingerprint reader exists on the + /// phone but there's no fingerprint registered, the plugin will attempt to + /// take the user to settings to add one. Anything that is not user fixable, + /// such as no biometric sensor on device, will be returned + /// as a [PlatformException]. + final bool useErrorDialogs; + + /// Used when the application goes into background for any reason while the + /// authentication is in progress. Due to security reasons, the + /// authentication has to be stopped at that time. If stickyAuth is set to + /// true, authentication resumes when the app is resumed. If it is set to + /// false (default), then as soon as app is paused a failure message is sent + /// back to Dart and it is up to the client app to restart authentication or + /// do something else. + final bool stickyAuth; + + /// Whether platform specific precautions are enabled. For instance, on face + /// unlock, Android opens a confirmation dialog after the face is recognized + /// to make sure the user meant to unlock their phone. + final bool sensitiveTransaction; + + /// Prevent authentications from using non-biometric local authentication + /// such as pin, passcode, and passcode. + final bool biometricOnly; +} diff --git a/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart b/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart index 4265b5ef9ad1..9c7d2eb8d83e 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart @@ -12,4 +12,14 @@ enum BiometricType { /// Iris authentication. iris, + + /// Any biometric (e.g. fingerprint, iris, or face) on the device that meets + /// or exceeds the requirements for Class 3 (formerly Strong), as defined + /// by the Android CDD. Android only. + strong, + + /// Any biometric (e.g. fingerprint, iris, or face) on the device that meets + /// or exceeds the requirements for Class 2 (formerly Weak), as defined + /// by the Android CDD. Android only. + weak, } diff --git a/packages/local_auth/local_auth_platform_interface/test/default_methbod_channel_platform_test.dart b/packages/local_auth/local_auth_platform_interface/test/default_methbod_channel_platform_test.dart new file mode 100644 index 000000000000..d1ee3c504c40 --- /dev/null +++ b/packages/local_auth/local_auth_platform_interface/test/default_methbod_channel_platform_test.dart @@ -0,0 +1,172 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:local_auth_platform_interface/default_method_channel_platform.dart'; +import 'package:local_auth_platform_interface/local_auth_platform_interface.dart'; +import 'package:local_auth_platform_interface/types/auth_options.dart'; +import 'package:local_auth_platform_interface/types/biometric_type.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + const MethodChannel channel = MethodChannel( + 'plugins.flutter.io/local_auth', + ); + + final List log = []; + late LocalAuthPlatform localAuthentication; + + test('getAvailableBiometrics', () async { + channel.setMockMethodCallHandler((MethodCall methodCall) { + log.add(methodCall); + return Future.value([]); + }); + localAuthentication = DefaultLocalAuthPlatform(); + log.clear(); + await localAuthentication.getAvailableBiometrics(); + expect( + log, + [ + isMethodCall('getAvailableBiometrics', arguments: null), + ], + ); + }); + + group('Boolean returning methods', () { + setUp(() { + channel.setMockMethodCallHandler((MethodCall methodCall) { + log.add(methodCall); + return Future.value(true); + }); + localAuthentication = DefaultLocalAuthPlatform(); + log.clear(); + }); + + test('isDeviceSupported', () async { + await localAuthentication.isDeviceSupported(); + expect( + log, + [ + isMethodCall('isDeviceSupported', arguments: null), + ], + ); + }); + + test('stopAuthentication', () async { + await localAuthentication.stopAuthentication(); + expect( + log, + [ + isMethodCall('stopAuthentication', arguments: null), + ], + ); + }); + + group('authenticate with device auth fail over', () { + test('authenticate with no args.', () async { + await localAuthentication.authenticate( + authStrings: {}, + localizedReason: 'Needs secure', + options: const AuthenticationOptions(biometricOnly: true), + ); + expect( + log, + [ + isMethodCall( + 'authenticate', + arguments: { + 'localizedReason': 'Needs secure', + 'useErrorDialogs': true, + 'stickyAuth': false, + 'sensitiveTransaction': true, + 'biometricOnly': true, + }, + ), + ], + ); + }); + + test('authenticate with no sensitive transaction.', () async { + await localAuthentication.authenticate( + authStrings: {}, + localizedReason: 'Insecure', + options: const AuthenticationOptions( + sensitiveTransaction: false, + useErrorDialogs: false, + biometricOnly: true, + ), + ); + expect( + log, + [ + isMethodCall( + 'authenticate', + arguments: { + 'localizedReason': 'Insecure', + 'useErrorDialogs': false, + 'stickyAuth': false, + 'sensitiveTransaction': false, + 'biometricOnly': true, + }, + ), + ], + ); + }); + }); + + group('authenticate with biometrics only', () { + test('authenticate with no args.', () async { + await localAuthentication.authenticate( + authStrings: {}, + localizedReason: 'Needs secure', + ); + expect( + log, + [ + isMethodCall( + 'authenticate', + arguments: { + 'localizedReason': 'Needs secure', + 'useErrorDialogs': true, + 'stickyAuth': false, + 'sensitiveTransaction': true, + 'biometricOnly': false, + }, + ), + ], + ); + }); + + test('authenticate with no sensitive transaction.', () async { + await localAuthentication.authenticate( + authStrings: {}, + localizedReason: 'Insecure', + options: const AuthenticationOptions( + sensitiveTransaction: false, + useErrorDialogs: false, + ), + ); + expect( + log, + [ + isMethodCall( + 'authenticate', + arguments: { + 'localizedReason': 'Insecure', + 'useErrorDialogs': false, + 'stickyAuth': false, + 'sensitiveTransaction': false, + 'biometricOnly': false, + }, + ), + ], + ); + }); + }); + }); +} From c3d5a1b2bacc037287beb2a45d8a9f5c5fa3708f Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Thu, 27 Jan 2022 11:37:42 +0100 Subject: [PATCH 07/36] Fix typo in file name --- ...atform_test.dart => default_method_channel_platform_test.dart} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/local_auth/local_auth_platform_interface/test/{default_methbod_channel_platform_test.dart => default_method_channel_platform_test.dart} (100%) diff --git a/packages/local_auth/local_auth_platform_interface/test/default_methbod_channel_platform_test.dart b/packages/local_auth/local_auth_platform_interface/test/default_method_channel_platform_test.dart similarity index 100% rename from packages/local_auth/local_auth_platform_interface/test/default_methbod_channel_platform_test.dart rename to packages/local_auth/local_auth_platform_interface/test/default_method_channel_platform_test.dart From cdf2cfee3984c582f044843549bc177bdcf0cd56 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Thu, 27 Jan 2022 12:33:05 +0100 Subject: [PATCH 08/36] Add Android implementation of platform interface --- packages/local_auth/local_auth/pubspec.yaml | 7 + .../local_auth/local_auth_android/AUTHORS | 67 +++++ .../local_auth_android/CHANGELOG.md | 3 + .../local_auth/local_auth_android/LICENSE | 25 ++ .../local_auth/local_auth_android/README.md | 11 + .../android/build.gradle | 0 .../android/lint-baseline.xml | 0 .../android/settings.gradle | 0 .../android/src/main/AndroidManifest.xml | 0 .../localauth/AuthenticationHelper.java | 0 .../plugins/localauth/LocalAuthPlugin.java | 2 +- .../res/drawable/fingerprint_initial_icon.xml | 0 .../res/drawable/fingerprint_success_icon.xml | 0 .../res/drawable/fingerprint_warning_icon.xml | 0 .../main/res/drawable/ic_done_white_24dp.xml | 0 .../drawable/ic_fingerprint_white_24dp.xml | 0 .../drawable/ic_priority_high_white_24dp.xml | 0 .../src/main/res/layout/go_to_setting.xml | 0 .../android/src/main/res/layout/scan_fp.xml | 0 .../android/src/main/res/values/colors.xml | 0 .../android/src/main/res/values/dimens.xml | 0 .../android/src/main/res/values/styles.xml | 0 .../plugins/localauth/LocalAuthTest.java | 0 .../local_auth_android/example/README.md | 8 + .../example/android/app/build.gradle | 58 +++++ .../gradle/wrapper/gradle-wrapper.properties | 5 + .../flutter/plugins/DartIntegrationTest.java | 14 ++ .../FlutterFragmentActivityTest.java | 20 ++ .../android/app/src/main/AndroidManifest.xml | 21 ++ .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 544 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 442 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 721 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 1031 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 1443 bytes .../example/android/build.gradle | 29 +++ .../example/android/gradle.properties | 4 + .../gradle/wrapper/gradle-wrapper.properties | 6 + .../example/android/settings.gradle | 15 ++ .../example/android/settings_aar.gradle | 1 + .../integration_test/local_auth_test.dart | 19 ++ .../local_auth_android/example/lib/main.dart | 231 ++++++++++++++++++ .../local_auth_android/example/pubspec.yaml | 28 +++ .../example/test_driver/integration_test.dart | 7 + .../lib/local_auth_android.dart | 74 ++++++ .../lib/types/auth_strings_android.dart | 159 ++++++++++++ .../local_auth_android/pubspec.yaml | 32 +++ .../test/local_auth_test.dart | 122 +++++++++ .../analysis_options.yaml | 4 - .../lib/default_method_channel_platform.dart | 65 +++++ .../lib/local_auth_platform_interface.dart | 39 +-- .../lib/types/auth_options.dart | 40 +++ .../lib/types/auth_strings.dart | 7 +- .../lib/types/biometric_type.dart | 22 +- .../pubspec.yaml | 4 +- .../default_method_channel_platform_test.dart | 172 +++++++++++++ 55 files changed, 1279 insertions(+), 42 deletions(-) create mode 100644 packages/local_auth/local_auth_android/AUTHORS create mode 100644 packages/local_auth/local_auth_android/CHANGELOG.md create mode 100644 packages/local_auth/local_auth_android/LICENSE create mode 100644 packages/local_auth/local_auth_android/README.md rename packages/local_auth/{local_auth => local_auth_android}/android/build.gradle (100%) rename packages/local_auth/{local_auth => local_auth_android}/android/lint-baseline.xml (100%) rename packages/local_auth/{local_auth => local_auth_android}/android/settings.gradle (100%) rename packages/local_auth/{local_auth => local_auth_android}/android/src/main/AndroidManifest.xml (100%) rename packages/local_auth/{local_auth => local_auth_android}/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java (100%) rename packages/local_auth/{local_auth => local_auth_android}/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java (99%) rename packages/local_auth/{local_auth => local_auth_android}/android/src/main/res/drawable/fingerprint_initial_icon.xml (100%) rename packages/local_auth/{local_auth => local_auth_android}/android/src/main/res/drawable/fingerprint_success_icon.xml (100%) rename packages/local_auth/{local_auth => local_auth_android}/android/src/main/res/drawable/fingerprint_warning_icon.xml (100%) rename packages/local_auth/{local_auth => local_auth_android}/android/src/main/res/drawable/ic_done_white_24dp.xml (100%) rename packages/local_auth/{local_auth => local_auth_android}/android/src/main/res/drawable/ic_fingerprint_white_24dp.xml (100%) rename packages/local_auth/{local_auth => local_auth_android}/android/src/main/res/drawable/ic_priority_high_white_24dp.xml (100%) rename packages/local_auth/{local_auth => local_auth_android}/android/src/main/res/layout/go_to_setting.xml (100%) rename packages/local_auth/{local_auth => local_auth_android}/android/src/main/res/layout/scan_fp.xml (100%) rename packages/local_auth/{local_auth => local_auth_android}/android/src/main/res/values/colors.xml (100%) rename packages/local_auth/{local_auth => local_auth_android}/android/src/main/res/values/dimens.xml (100%) rename packages/local_auth/{local_auth => local_auth_android}/android/src/main/res/values/styles.xml (100%) rename packages/local_auth/{local_auth => local_auth_android}/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java (100%) create mode 100644 packages/local_auth/local_auth_android/example/README.md create mode 100644 packages/local_auth/local_auth_android/example/android/app/build.gradle create mode 100644 packages/local_auth/local_auth_android/example/android/app/gradle/wrapper/gradle-wrapper.properties create mode 100644 packages/local_auth/local_auth_android/example/android/app/src/androidTest/java/io/flutter/plugins/DartIntegrationTest.java create mode 100644 packages/local_auth/local_auth_android/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java create mode 100644 packages/local_auth/local_auth_android/example/android/app/src/main/AndroidManifest.xml create mode 100644 packages/local_auth/local_auth_android/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 packages/local_auth/local_auth_android/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 packages/local_auth/local_auth_android/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 packages/local_auth/local_auth_android/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 packages/local_auth/local_auth_android/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 packages/local_auth/local_auth_android/example/android/build.gradle create mode 100644 packages/local_auth/local_auth_android/example/android/gradle.properties create mode 100644 packages/local_auth/local_auth_android/example/android/gradle/wrapper/gradle-wrapper.properties create mode 100644 packages/local_auth/local_auth_android/example/android/settings.gradle create mode 100644 packages/local_auth/local_auth_android/example/android/settings_aar.gradle create mode 100644 packages/local_auth/local_auth_android/example/integration_test/local_auth_test.dart create mode 100644 packages/local_auth/local_auth_android/example/lib/main.dart create mode 100644 packages/local_auth/local_auth_android/example/pubspec.yaml create mode 100644 packages/local_auth/local_auth_android/example/test_driver/integration_test.dart create mode 100644 packages/local_auth/local_auth_android/lib/local_auth_android.dart create mode 100644 packages/local_auth/local_auth_android/lib/types/auth_strings_android.dart create mode 100644 packages/local_auth/local_auth_android/pubspec.yaml create mode 100644 packages/local_auth/local_auth_android/test/local_auth_test.dart delete mode 100644 packages/local_auth/local_auth_platform_interface/analysis_options.yaml create mode 100644 packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart create mode 100644 packages/local_auth/local_auth_platform_interface/lib/types/auth_options.dart create mode 100644 packages/local_auth/local_auth_platform_interface/test/default_method_channel_platform_test.dart diff --git a/packages/local_auth/local_auth/pubspec.yaml b/packages/local_auth/local_auth/pubspec.yaml index cd9d0d9760f4..f7bba9f26554 100644 --- a/packages/local_auth/local_auth/pubspec.yaml +++ b/packages/local_auth/local_auth/pubspec.yaml @@ -5,6 +5,10 @@ repository: https://github.com/flutter/plugins/tree/main/packages/local_auth/loc issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+local_auth%22 version: 1.1.10 +# Temporarily disable publishing to allow moving Android and iOS +# implementations. +publish_to: none + environment: sdk: ">=2.14.0 <3.0.0" flutter: ">=2.5.0" @@ -15,6 +19,7 @@ flutter: android: package: io.flutter.plugins.localauth pluginClass: LocalAuthPlugin + default_package: local_auth_android ios: pluginClass: FLTLocalAuthPlugin @@ -23,6 +28,8 @@ dependencies: sdk: flutter flutter_plugin_android_lifecycle: ^2.0.1 intl: ^0.17.0 + local_auth_android: + path: ../local_auth_android platform: ^3.0.0 dev_dependencies: diff --git a/packages/local_auth/local_auth_android/AUTHORS b/packages/local_auth/local_auth_android/AUTHORS new file mode 100644 index 000000000000..d5694690c247 --- /dev/null +++ b/packages/local_auth/local_auth_android/AUTHORS @@ -0,0 +1,67 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +The Chromium Authors +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> +Bodhi Mulders diff --git a/packages/local_auth/local_auth_android/CHANGELOG.md b/packages/local_auth/local_auth_android/CHANGELOG.md new file mode 100644 index 000000000000..7f198f2d66c0 --- /dev/null +++ b/packages/local_auth/local_auth_android/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.0 + +* Initial release from migration to federated architecture. diff --git a/packages/local_auth/local_auth_android/LICENSE b/packages/local_auth/local_auth_android/LICENSE new file mode 100644 index 000000000000..c6823b81eb84 --- /dev/null +++ b/packages/local_auth/local_auth_android/LICENSE @@ -0,0 +1,25 @@ +Copyright 2013 The Flutter Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/local_auth/local_auth_android/README.md b/packages/local_auth/local_auth_android/README.md new file mode 100644 index 000000000000..07244912f231 --- /dev/null +++ b/packages/local_auth/local_auth_android/README.md @@ -0,0 +1,11 @@ +# local\_auth\_android + +The Android implementation of [`local_auth`][1]. + +## Usage + +This package is [endorsed][2], which means you can simply use `local_auth` +normally. This package will be automatically included in your app when you do. + +[1]: https://pub.dev/packages/local_auth +[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin \ No newline at end of file diff --git a/packages/local_auth/local_auth/android/build.gradle b/packages/local_auth/local_auth_android/android/build.gradle similarity index 100% rename from packages/local_auth/local_auth/android/build.gradle rename to packages/local_auth/local_auth_android/android/build.gradle diff --git a/packages/local_auth/local_auth/android/lint-baseline.xml b/packages/local_auth/local_auth_android/android/lint-baseline.xml similarity index 100% rename from packages/local_auth/local_auth/android/lint-baseline.xml rename to packages/local_auth/local_auth_android/android/lint-baseline.xml diff --git a/packages/local_auth/local_auth/android/settings.gradle b/packages/local_auth/local_auth_android/android/settings.gradle similarity index 100% rename from packages/local_auth/local_auth/android/settings.gradle rename to packages/local_auth/local_auth_android/android/settings.gradle diff --git a/packages/local_auth/local_auth/android/src/main/AndroidManifest.xml b/packages/local_auth/local_auth_android/android/src/main/AndroidManifest.xml similarity index 100% rename from packages/local_auth/local_auth/android/src/main/AndroidManifest.xml rename to packages/local_auth/local_auth_android/android/src/main/AndroidManifest.xml diff --git a/packages/local_auth/local_auth/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 similarity index 100% rename from packages/local_auth/local_auth/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java rename to packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/AuthenticationHelper.java diff --git a/packages/local_auth/local_auth/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 similarity index 99% rename from packages/local_auth/local_auth/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java rename to packages/local_auth/local_auth_android/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java index a63e22a512d0..49a6b788fe46 100644 --- a/packages/local_auth/local_auth/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 @@ -40,7 +40,7 @@ */ @SuppressWarnings("deprecation") public class LocalAuthPlugin implements MethodCallHandler, FlutterPlugin, ActivityAware { - private static final String CHANNEL_NAME = "plugins.flutter.io/local_auth"; + private static final String CHANNEL_NAME = "plugins.flutter.io/local_auth_android"; private static final int LOCK_REQUEST_CODE = 221; private Activity activity; private final AtomicBoolean authInProgress = new AtomicBoolean(false); diff --git a/packages/local_auth/local_auth/android/src/main/res/drawable/fingerprint_initial_icon.xml b/packages/local_auth/local_auth_android/android/src/main/res/drawable/fingerprint_initial_icon.xml similarity index 100% rename from packages/local_auth/local_auth/android/src/main/res/drawable/fingerprint_initial_icon.xml rename to packages/local_auth/local_auth_android/android/src/main/res/drawable/fingerprint_initial_icon.xml diff --git a/packages/local_auth/local_auth/android/src/main/res/drawable/fingerprint_success_icon.xml b/packages/local_auth/local_auth_android/android/src/main/res/drawable/fingerprint_success_icon.xml similarity index 100% rename from packages/local_auth/local_auth/android/src/main/res/drawable/fingerprint_success_icon.xml rename to packages/local_auth/local_auth_android/android/src/main/res/drawable/fingerprint_success_icon.xml diff --git a/packages/local_auth/local_auth/android/src/main/res/drawable/fingerprint_warning_icon.xml b/packages/local_auth/local_auth_android/android/src/main/res/drawable/fingerprint_warning_icon.xml similarity index 100% rename from packages/local_auth/local_auth/android/src/main/res/drawable/fingerprint_warning_icon.xml rename to packages/local_auth/local_auth_android/android/src/main/res/drawable/fingerprint_warning_icon.xml diff --git a/packages/local_auth/local_auth/android/src/main/res/drawable/ic_done_white_24dp.xml b/packages/local_auth/local_auth_android/android/src/main/res/drawable/ic_done_white_24dp.xml similarity index 100% rename from packages/local_auth/local_auth/android/src/main/res/drawable/ic_done_white_24dp.xml rename to packages/local_auth/local_auth_android/android/src/main/res/drawable/ic_done_white_24dp.xml diff --git a/packages/local_auth/local_auth/android/src/main/res/drawable/ic_fingerprint_white_24dp.xml b/packages/local_auth/local_auth_android/android/src/main/res/drawable/ic_fingerprint_white_24dp.xml similarity index 100% rename from packages/local_auth/local_auth/android/src/main/res/drawable/ic_fingerprint_white_24dp.xml rename to packages/local_auth/local_auth_android/android/src/main/res/drawable/ic_fingerprint_white_24dp.xml diff --git a/packages/local_auth/local_auth/android/src/main/res/drawable/ic_priority_high_white_24dp.xml b/packages/local_auth/local_auth_android/android/src/main/res/drawable/ic_priority_high_white_24dp.xml similarity index 100% rename from packages/local_auth/local_auth/android/src/main/res/drawable/ic_priority_high_white_24dp.xml rename to packages/local_auth/local_auth_android/android/src/main/res/drawable/ic_priority_high_white_24dp.xml diff --git a/packages/local_auth/local_auth/android/src/main/res/layout/go_to_setting.xml b/packages/local_auth/local_auth_android/android/src/main/res/layout/go_to_setting.xml similarity index 100% rename from packages/local_auth/local_auth/android/src/main/res/layout/go_to_setting.xml rename to packages/local_auth/local_auth_android/android/src/main/res/layout/go_to_setting.xml diff --git a/packages/local_auth/local_auth/android/src/main/res/layout/scan_fp.xml b/packages/local_auth/local_auth_android/android/src/main/res/layout/scan_fp.xml similarity index 100% rename from packages/local_auth/local_auth/android/src/main/res/layout/scan_fp.xml rename to packages/local_auth/local_auth_android/android/src/main/res/layout/scan_fp.xml diff --git a/packages/local_auth/local_auth/android/src/main/res/values/colors.xml b/packages/local_auth/local_auth_android/android/src/main/res/values/colors.xml similarity index 100% rename from packages/local_auth/local_auth/android/src/main/res/values/colors.xml rename to packages/local_auth/local_auth_android/android/src/main/res/values/colors.xml diff --git a/packages/local_auth/local_auth/android/src/main/res/values/dimens.xml b/packages/local_auth/local_auth_android/android/src/main/res/values/dimens.xml similarity index 100% rename from packages/local_auth/local_auth/android/src/main/res/values/dimens.xml rename to packages/local_auth/local_auth_android/android/src/main/res/values/dimens.xml diff --git a/packages/local_auth/local_auth/android/src/main/res/values/styles.xml b/packages/local_auth/local_auth_android/android/src/main/res/values/styles.xml similarity index 100% rename from packages/local_auth/local_auth/android/src/main/res/values/styles.xml rename to packages/local_auth/local_auth_android/android/src/main/res/values/styles.xml diff --git a/packages/local_auth/local_auth/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 similarity index 100% rename from packages/local_auth/local_auth/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java rename to packages/local_auth/local_auth_android/android/src/test/java/io/flutter/plugins/localauth/LocalAuthTest.java diff --git a/packages/local_auth/local_auth_android/example/README.md b/packages/local_auth/local_auth_android/example/README.md new file mode 100644 index 000000000000..a4a6091c9ba6 --- /dev/null +++ b/packages/local_auth/local_auth_android/example/README.md @@ -0,0 +1,8 @@ +# local_auth_example + +Demonstrates how to use the local_auth plugin. + +## Getting Started + +For help getting started with Flutter, view our online +[documentation](https://flutter.dev/). diff --git a/packages/local_auth/local_auth_android/example/android/app/build.gradle b/packages/local_auth/local_auth_android/example/android/app/build.gradle new file mode 100644 index 000000000000..d1cef4bf53a9 --- /dev/null +++ b/packages/local_auth/local_auth_android/example/android/app/build.gradle @@ -0,0 +1,58 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 31 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + applicationId "io.flutter.plugins.localauthexample" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test:runner:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' +} diff --git a/packages/local_auth/local_auth_android/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/local_auth/local_auth_android/example/android/app/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000000..186b71557c50 --- /dev/null +++ b/packages/local_auth/local_auth_android/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/packages/local_auth/local_auth_android/example/android/app/src/androidTest/java/io/flutter/plugins/DartIntegrationTest.java b/packages/local_auth/local_auth_android/example/android/app/src/androidTest/java/io/flutter/plugins/DartIntegrationTest.java new file mode 100644 index 000000000000..0f4298dca155 --- /dev/null +++ b/packages/local_auth/local_auth_android/example/android/app/src/androidTest/java/io/flutter/plugins/DartIntegrationTest.java @@ -0,0 +1,14 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface DartIntegrationTest {} diff --git a/packages/local_auth/local_auth_android/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java b/packages/local_auth/local_auth_android/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java new file mode 100644 index 000000000000..68c22371d7dd --- /dev/null +++ b/packages/local_auth/local_auth_android/example/android/app/src/androidTest/java/io/flutter/plugins/localauth/FlutterFragmentActivityTest.java @@ -0,0 +1,20 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.localauth; + +import androidx.test.rule.ActivityTestRule; +import dev.flutter.plugins.integration_test.FlutterTestRunner; +import io.flutter.embedding.android.FlutterFragmentActivity; +import io.flutter.plugins.DartIntegrationTest; +import org.junit.Rule; +import org.junit.runner.RunWith; + +@DartIntegrationTest +@RunWith(FlutterTestRunner.class) +public class FlutterFragmentActivityTest { + @Rule + public ActivityTestRule rule = + new ActivityTestRule<>(FlutterFragmentActivity.class); +} diff --git a/packages/local_auth/local_auth_android/example/android/app/src/main/AndroidManifest.xml b/packages/local_auth/local_auth_android/example/android/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000000..8c091772107a --- /dev/null +++ b/packages/local_auth/local_auth_android/example/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + diff --git a/packages/local_auth/local_auth_android/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/packages/local_auth/local_auth_android/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..db77bb4b7b0906d62b1847e87f15cdcacf6a4f29 GIT binary patch literal 544 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAj~WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8bpbvhu0Wd6uZuB!w&u2PAxD2eNXD>P5D~Wn-+_Wa#27Xc zC?Zj|6r#X(-D3u$NCt}(Ms06KgJ4FxJVv{GM)!I~&n8Bnc94O7-Hd)cjDZswgC;Qs zO=b+9!WcT8F?0rF7!Uys2bs@gozCP?z~o%U|N3vA*22NaGQG zlg@K`O_XuxvZ&Ks^m&R!`&1=spLvfx7oGDKDwpwW`#iqdw@AL`7MR}m`rwr|mZgU`8P7SBkL78fFf!WnuYWm$5Z0 zNXhDbCv&49sM544K|?c)WrFfiZvCi9h0O)B3Pgg&ebxsLQ05GG~ AQ2+n{ literal 0 HcmV?d00001 diff --git a/packages/local_auth/local_auth_android/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/packages/local_auth/local_auth_android/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..17987b79bb8a35cc66c3c1fd44f5a5526c1b78be GIT binary patch literal 442 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xx&nMcT!A!W`0S9QKQy;}1Cl^CgaH=;G9cpY;r$Q>i*pfB zP2drbID<_#qf;rPZx^FqH)F_D#*k@@q03KywUtLX8Ua?`H+NMzkczFPK3lFz@i_kW%1NOn0|D2I9n9wzH8m|-tHjsw|9>@K=iMBhxvkv6m8Y-l zytQ?X=U+MF$@3 zt`~i=@j|6y)RWMK--}M|=T`o&^Ni>IoWKHEbBXz7?A@mgWoL>!*SXo`SZH-*HSdS+ yn*9;$7;m`l>wYBC5bq;=U}IMqLzqbYCidGC!)_gkIk_C@Uy!y&wkt5C($~2D>~)O*cj@FGjOCM)M>_ixfudOh)?xMu#Fs z#}Y=@YDTwOM)x{K_j*Q;dPdJ?Mz0n|pLRx{4n|)f>SXlmV)XB04CrSJn#dS5nK2lM zrZ9#~WelCp7&e13Y$jvaEXHskn$2V!!DN-nWS__6T*l;H&Fopn?A6HZ-6WRLFP=R` zqG+CE#d4|IbyAI+rJJ`&x9*T`+a=p|0O(+s{UBcyZdkhj=yS1>AirP+0R;mf2uMgM zC}@~JfByORAh4SyRgi&!(cja>F(l*O+nd+@4m$|6K6KDn_&uvCpV23&>G9HJp{xgg zoq1^2_p9@|WEo z*X_Uko@K)qYYv~>43eQGMdbiGbo>E~Q& zrYBH{QP^@Sti!`2)uG{irBBq@y*$B zi#&(U-*=fp74j)RyIw49+0MRPMRU)+a2r*PJ$L5roHt2$UjExCTZSbq%V!HeS7J$N zdG@vOZB4v_lF7Plrx+hxo7(fCV&}fHq)$ literal 0 HcmV?d00001 diff --git a/packages/local_auth/local_auth_android/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/packages/local_auth/local_auth_android/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..d5f1c8d34e7a88e3f88bea192c3a370d44689c3c GIT binary patch literal 1031 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFa`(sgt!6~Yi|1%a`XoT0ojZ}lNrNjb9xjc(B0U1_% zz5^97Xt*%oq$rQy4?0GKNfJ44uvxI)gC`h-NZ|&0-7(qS@?b!5r36oQ}zyZrNO3 zMO=Or+<~>+A&uN&E!^Sl+>xE!QC-|oJv`ApDhqC^EWD|@=#J`=d#Xzxs4ah}w&Jnc z$|q_opQ^2TrnVZ0o~wh<3t%W&flvYGe#$xqda2bR_R zvPYgMcHgjZ5nSA^lJr%;<&0do;O^tDDh~=pIxA#coaCY>&N%M2^tq^U%3DB@ynvKo}b?yu-bFc-u0JHzced$sg7S3zqI(2 z#Km{dPr7I=pQ5>FuK#)QwK?Y`E`B?nP+}U)I#c1+FM*1kNvWG|a(TpksZQ3B@sD~b zpQ2)*V*TdwjFOtHvV|;OsiDqHi=6%)o4b!)x$)%9pGTsE z-JL={-Ffv+T87W(Xpooq<`r*VzWQcgBN$$`u}f>-ZQI1BB8ykN*=e4rIsJx9>z}*o zo~|9I;xof literal 0 HcmV?d00001 diff --git a/packages/local_auth/local_auth_android/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/packages/local_auth/local_auth_android/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..4d6372eebdb28e45604e46eeda8dd24651419bc0 GIT binary patch literal 1443 zcmb`G{WsKk6vsdJTdFg%tJav9_E4vzrOaqkWF|A724Nly!y+?N9`YV6wZ}5(X(D_N(?!*n3`|_r0Hc?=PQw&*vnU?QTFY zB_MsH|!j$PP;I}?dppoE_gA(4uc!jV&0!l7_;&p2^pxNo>PEcNJv za5_RT$o2Mf!<+r?&EbHH6nMoTsDOa;mN(wv8RNsHpG)`^ymG-S5By8=l9iVXzN_eG%Xg2@Xeq76tTZ*dGh~Lo9vl;Zfs+W#BydUw zCkZ$o1LqWQO$FC9aKlLl*7x9^0q%0}$OMlp@Kk_jHXOjofdePND+j!A{q!8~Jn+s3 z?~~w@4?egS02}8NuulUA=L~QQfm;MzCGd)XhiftT;+zFO&JVyp2mBww?;QByS_1w! zrQlx%{^cMj0|Bo1FjwY@Q8?Hx0cIPF*@-ZRFpPc#bBw{5@tD(5%sClzIfl8WU~V#u zm5Q;_F!wa$BSpqhN>W@2De?TKWR*!ujY;Yylk_X5#~V!L*Gw~;$%4Q8~Mad z@`-kG?yb$a9cHIApZDVZ^U6Xkp<*4rU82O7%}0jjHlK{id@?-wpN*fCHXyXh(bLt* zPc}H-x0e4E&nQ>y%B-(EL=9}RyC%MyX=upHuFhAk&MLbsF0LP-q`XnH78@fT+pKPW zu72MW`|?8ht^tz$iC}ZwLp4tB;Q49K!QCF3@!iB1qOI=?w z7In!}F~ij(18UYUjnbmC!qKhPo%24?8U1x{7o(+?^Zu0Hx81|FuS?bJ0jgBhEMzf< zCgUq7r2OCB(`XkKcN-TL>u5y#dD6D!)5W?`O5)V^>jb)P)GBdy%t$uUMpf$SNV31$ zb||OojAbvMP?T@$h_ZiFLFVHDmbyMhJF|-_)HX3%m=CDI+ID$0^C>kzxprBW)hw(v zr!Gmda);ICoQyhV_oP5+C%?jcG8v+D@9f?Dk*!BxY}dazmrT@64UrP3hlslANK)bq z$67n83eh}OeW&SV@HG95P|bjfqJ7gw$e+`Hxo!4cx`jdK1bJ>YDSpGKLPZ^1cv$ek zIB?0S<#tX?SJCLWdMd{-ME?$hc7A$zBOdIJ)4!KcAwb=VMov)nK;9z>x~rfT1>dS+ zZ6#`2v@`jgbqq)P22H)Tx2CpmM^o1$B+xT6`(v%5xJ(?j#>Q$+rx_R|7TzDZe{J6q zG1*EcU%tE?!kO%^M;3aM6JN*LAKUVb^xz8-Pxo#jR5(-KBeLJvA@-gxNHx0M-ZJLl z;#JwQoh~9V?`UVo#}{6ka@II>++D@%KqGpMdlQ}?9E*wFcf5(#XQnP$Dk5~%iX^>f z%$y;?M0BLp{O3a(-4A?ewryHrrD%cx#Q^%KY1H zNre$ve+vceSLZcNY4U(RBX&)oZn*Py()h)XkE?PL$!bNb{N5FVI2Y%LKEm%yvpyTP z(1P?z~7YxD~Rf<(a@_y` literal 0 HcmV?d00001 diff --git a/packages/local_auth/local_auth_android/example/android/build.gradle b/packages/local_auth/local_auth_android/example/android/build.gradle new file mode 100644 index 000000000000..54c943621de5 --- /dev/null +++ b/packages/local_auth/local_auth_android/example/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:4.1.1' + } +} + +allprojects { + repositories { + google() + mavenCentral() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/packages/local_auth/local_auth_android/example/android/gradle.properties b/packages/local_auth/local_auth_android/example/android/gradle.properties new file mode 100644 index 000000000000..7fe61a74cee0 --- /dev/null +++ b/packages/local_auth/local_auth_android/example/android/gradle.properties @@ -0,0 +1,4 @@ +org.gradle.jvmargs=-Xmx1024m +android.useAndroidX=true +android.enableJetifier=true +android.enableR8=true diff --git a/packages/local_auth/local_auth_android/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/local_auth/local_auth_android/example/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000000..cd9fe1c68282 --- /dev/null +++ b/packages/local_auth/local_auth_android/example/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Sun Jan 03 14:07:08 CST 2021 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip diff --git a/packages/local_auth/local_auth_android/example/android/settings.gradle b/packages/local_auth/local_auth_android/example/android/settings.gradle new file mode 100644 index 000000000000..115da6cb4f4d --- /dev/null +++ b/packages/local_auth/local_auth_android/example/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withInputStream { stream -> plugins.load(stream) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/packages/local_auth/local_auth_android/example/android/settings_aar.gradle b/packages/local_auth/local_auth_android/example/android/settings_aar.gradle new file mode 100644 index 000000000000..e7b4def49cb5 --- /dev/null +++ b/packages/local_auth/local_auth_android/example/android/settings_aar.gradle @@ -0,0 +1 @@ +include ':app' diff --git a/packages/local_auth/local_auth_android/example/integration_test/local_auth_test.dart b/packages/local_auth/local_auth_android/example/integration_test/local_auth_test.dart new file mode 100644 index 000000000000..8e4f4748f05f --- /dev/null +++ b/packages/local_auth/local_auth_android/example/integration_test/local_auth_test.dart @@ -0,0 +1,19 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; + +import 'package:local_auth_android/local_auth_android.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + testWidgets('canCheckBiometrics', (WidgetTester tester) async { + expect( + LocalAuthAndroid().getAvailableBiometrics(), + completion(isList), + ); + }); +} diff --git a/packages/local_auth/local_auth_android/example/lib/main.dart b/packages/local_auth/local_auth_android/example/lib/main.dart new file mode 100644 index 000000000000..4328f28136c2 --- /dev/null +++ b/packages/local_auth/local_auth_android/example/lib/main.dart @@ -0,0 +1,231 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// ignore_for_file: public_member_api_docs + +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:local_auth_android/local_auth_android.dart'; +import 'package:local_auth_android/types/auth_strings_android.dart'; + +void main() { + runApp(MyApp()); +} + +class MyApp extends StatefulWidget { + @override + _MyAppState createState() => _MyAppState(); +} + +class _MyAppState extends State { + final LocalAuthAndroid auth = LocalAuthAndroid(); + _SupportState _supportState = _SupportState.unknown; + bool? _canCheckBiometrics; + List? _availableBiometrics; + String _authorized = 'Not Authorized'; + bool _isAuthenticating = false; + + @override + void initState() { + super.initState(); + auth.isDeviceSupported().then( + (bool isSupported) => setState(() => _supportState = isSupported + ? _SupportState.supported + : _SupportState.unsupported), + ); + } + + Future _checkBiometrics() async { + late bool canCheckBiometrics; + try { + canCheckBiometrics = (await auth.getAvailableBiometrics()).isNotEmpty; + } on PlatformException catch (e) { + canCheckBiometrics = false; + print(e); + } + if (!mounted) { + return; + } + + setState(() { + _canCheckBiometrics = canCheckBiometrics; + }); + } + + Future _getAvailableBiometrics() async { + late List availableBiometrics; + try { + availableBiometrics = await auth.getAvailableBiometrics(); + } on PlatformException catch (e) { + availableBiometrics = []; + print(e); + } + if (!mounted) { + return; + } + + setState(() { + _availableBiometrics = availableBiometrics; + }); + } + + Future _authenticate() async { + bool authenticated = false; + try { + setState(() { + _isAuthenticating = true; + _authorized = 'Authenticating'; + }); + authenticated = await auth.authenticate( + localizedReason: 'Let OS determine authentication method', + authStrings: const AndroidAuthMessages().args, + useErrorDialogs: true, + stickyAuth: true); + setState(() { + _isAuthenticating = false; + }); + } on PlatformException catch (e) { + print(e); + setState(() { + _isAuthenticating = false; + _authorized = 'Error - ${e.message}'; + }); + return; + } + if (!mounted) { + return; + } + + setState( + () => _authorized = authenticated ? 'Authorized' : 'Not Authorized'); + } + + Future _authenticateWithBiometrics() async { + bool authenticated = false; + try { + setState(() { + _isAuthenticating = true; + _authorized = 'Authenticating'; + }); + authenticated = await auth.authenticate( + localizedReason: + 'Scan your fingerprint (or face or whatever) to authenticate', + authStrings: const AndroidAuthMessages().args, + useErrorDialogs: true, + stickyAuth: true, + biometricOnly: true); + setState(() { + _isAuthenticating = false; + _authorized = 'Authenticating'; + }); + } on PlatformException catch (e) { + print(e); + setState(() { + _isAuthenticating = false; + _authorized = 'Error - ${e.message}'; + }); + return; + } + if (!mounted) { + return; + } + + final String message = authenticated ? 'Authorized' : 'Not Authorized'; + setState(() { + _authorized = message; + }); + } + + Future _cancelAuthentication() async { + await auth.stopAuthentication(); + setState(() => _isAuthenticating = false); + } + + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + appBar: AppBar( + title: const Text('Plugin example app'), + ), + body: ListView( + padding: const EdgeInsets.only(top: 30), + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (_supportState == _SupportState.unknown) + const CircularProgressIndicator() + else if (_supportState == _SupportState.supported) + const Text('This device is supported') + else + const Text('This device is not supported'), + const Divider(height: 100), + Text('Can check biometrics: $_canCheckBiometrics\n'), + ElevatedButton( + child: const Text('Check biometrics'), + onPressed: _checkBiometrics, + ), + const Divider(height: 100), + Text('Available biometrics: $_availableBiometrics\n'), + ElevatedButton( + child: const Text('Get available biometrics'), + onPressed: _getAvailableBiometrics, + ), + const Divider(height: 100), + Text('Current State: $_authorized\n'), + if (_isAuthenticating) + ElevatedButton( + onPressed: _cancelAuthentication, + child: Row( + mainAxisSize: MainAxisSize.min, + children: const [ + Text('Cancel Authentication'), + Icon(Icons.cancel), + ], + ), + ) + else + Column( + children: [ + ElevatedButton( + child: Row( + mainAxisSize: MainAxisSize.min, + children: const [ + Text('Authenticate'), + Icon(Icons.perm_device_information), + ], + ), + onPressed: _authenticate, + ), + ElevatedButton( + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text(_isAuthenticating + ? 'Cancel' + : 'Authenticate: biometrics only'), + const Icon(Icons.fingerprint), + ], + ), + onPressed: _authenticateWithBiometrics, + ), + ], + ), + ], + ), + ], + ), + ), + ); + } +} + +enum _SupportState { + unknown, + supported, + unsupported, +} diff --git a/packages/local_auth/local_auth_android/example/pubspec.yaml b/packages/local_auth/local_auth_android/example/pubspec.yaml new file mode 100644 index 000000000000..efd7c9c79f7f --- /dev/null +++ b/packages/local_auth/local_auth_android/example/pubspec.yaml @@ -0,0 +1,28 @@ +name: local_auth_android_example +description: Demonstrates how to use the local_auth_android plugin. +publish_to: none + +environment: + sdk: ">=2.14.0 <3.0.0" + flutter: ">=2.5.0" + +dependencies: + flutter: + sdk: flutter + local_auth_android: + # When depending on this package from a real application you should use: + # local_auth: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. + path: ../ + +dev_dependencies: + flutter_driver: + sdk: flutter + integration_test: + sdk: flutter + pedantic: ^1.10.0 + +flutter: + uses-material-design: true diff --git a/packages/local_auth/local_auth_android/example/test_driver/integration_test.dart b/packages/local_auth/local_auth_android/example/test_driver/integration_test.dart new file mode 100644 index 000000000000..4f10f2a522f3 --- /dev/null +++ b/packages/local_auth/local_auth_android/example/test_driver/integration_test.dart @@ -0,0 +1,7 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:integration_test/integration_test_driver.dart'; + +Future main() => integrationDriver(); diff --git a/packages/local_auth/local_auth_android/lib/local_auth_android.dart b/packages/local_auth/local_auth_android/lib/local_auth_android.dart new file mode 100644 index 000000000000..0f82e7cf9158 --- /dev/null +++ b/packages/local_auth/local_auth_android/lib/local_auth_android.dart @@ -0,0 +1,74 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/services.dart'; +import 'package:local_auth_platform_interface/local_auth_platform_interface.dart'; +import 'package:local_auth_platform_interface/types/biometric_type.dart'; + +export 'package:local_auth_platform_interface/types/biometric_type.dart'; + +const MethodChannel _channel = + MethodChannel('plugins.flutter.io/local_auth_android'); + +/// The implementation of [LocalAuthPlatform] for Android. +class LocalAuthAndroid extends LocalAuthPlatform { + /// Registers this class as the default instance of [LocalAuthPlatform]. + static void registerWith() { + LocalAuthPlatform.instance = LocalAuthAndroid(); + } + + @override + Future authenticate({ + required String localizedReason, + bool useErrorDialogs = true, + bool stickyAuth = false, + required Map authStrings, + bool sensitiveTransaction = true, + bool biometricOnly = false, + }) async { + assert(localizedReason.isNotEmpty); + final Map args = { + 'localizedReason': localizedReason, + 'useErrorDialogs': useErrorDialogs, + 'stickyAuth': stickyAuth, + 'sensitiveTransaction': sensitiveTransaction, + 'biometricOnly': biometricOnly, + }; + args.addAll(authStrings); + return (await _channel.invokeMethod('authenticate', args)) ?? false; + } + + @override + Future> getAvailableBiometrics() async { + final List result = (await _channel.invokeListMethod( + 'getAvailableBiometrics', + )) ?? + []; + final List biometrics = []; + for (final String value in result) { + switch (value) { + case 'face': + biometrics.add(BiometricType.face); + break; + case 'fingerprint': + biometrics.add(BiometricType.fingerprint); + break; + case 'iris': + biometrics.add(BiometricType.iris); + break; + case 'undefined': + break; + } + } + return biometrics; + } + + @override + Future isDeviceSupported() async => + (await _channel.invokeMethod('isDeviceSupported')) ?? false; + + @override + Future stopAuthentication() async => + await _channel.invokeMethod('stopAuthentication') ?? false; +} diff --git a/packages/local_auth/local_auth_android/lib/types/auth_strings_android.dart b/packages/local_auth/local_auth_android/lib/types/auth_strings_android.dart new file mode 100644 index 000000000000..9d9886ce7168 --- /dev/null +++ b/packages/local_auth/local_auth_android/lib/types/auth_strings_android.dart @@ -0,0 +1,159 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:intl/intl.dart'; +import 'package:local_auth_platform_interface/types/auth_strings.dart'; + +/// Android side authentication messages. +/// +/// Provides default values for all messages. +class AndroidAuthMessages { + /// Constructs a new instance. + const AndroidAuthMessages({ + this.biometricHint, + this.biometricNotRecognized, + this.biometricRequiredTitle, + this.biometricSuccess, + this.cancelButton, + this.deviceCredentialsRequiredTitle, + this.deviceCredentialsSetupDescription, + this.goToSettingsButton, + this.goToSettingsDescription, + this.signInTitle, + }); + + /// Hint message advising the user how to authenticate with biometrics. It is + /// used on Android. Maximum 60 characters. + final String? biometricHint; + + /// Message to let the user know that authentication was failed. It is used + /// on Android. Maximum 60 characters.' + final String? biometricNotRecognized; + + /// Message shown as a title in a dialog which indicates the user + /// has not set up biometric authentication on their device. It is used on + /// Android. Maximum 60 characters. + final String? biometricRequiredTitle; + + /// Message to let the user know that authentication was successful. It + /// is used on Android. Maximum 60 characters + final String? biometricSuccess; + + /// Message shown on a button that the user can click to leave the + /// current dialog. It is used on Android. Maximum 30 characters. + final String? cancelButton; + + /// Message shown as a title in a dialog which indicates the user + /// has not set up credentials authentication on their device. It is used on Android. + /// Maximum 60 characters. + final String? deviceCredentialsRequiredTitle; + + /// Message advising the user to go to the settings and configure + /// device credentials on their device. It shows in a dialog on Android. + final String? deviceCredentialsSetupDescription; + + /// Message shown on a button that the user can click to go to settings pages + /// from the current dialog. It is used on both Android and iOS sides. + /// Maximum 30 characters. + final String? goToSettingsButton; + + /// Message advising the user to go to the settings and configure + /// biometric on their device. It shows in a dialog on Android. + final String? goToSettingsDescription; + + /// Message shown as a title in a dialog which indicates the user + /// that they need to scan biometric to continue. It is used on + /// Android. Maximum 60 characters. + final String? signInTitle; + + /// Gets the messaged stored in this class instance as a string map. + Map get args { + return { + 'biometricHint': biometricHint ?? androidBiometricHint, + 'biometricNotRecognized': + biometricNotRecognized ?? androidBiometricNotRecognized, + 'biometricSuccess': biometricSuccess ?? androidBiometricSuccess, + 'biometricRequired': + biometricRequiredTitle ?? androidBiometricRequiredTitle, + 'cancelButton': cancelButton ?? androidCancelButton, + 'deviceCredentialsRequired': deviceCredentialsRequiredTitle ?? + androidDeviceCredentialsRequiredTitle, + 'deviceCredentialsSetupDescription': deviceCredentialsSetupDescription ?? + androidDeviceCredentialsSetupDescription, + 'goToSetting': goToSettingsButton ?? goToSettings, + 'goToSettingDescription': + goToSettingsDescription ?? androidGoToSettingsDescription, + 'signInTitle': signInTitle ?? androidSignInTitle, + }; + } +} + +// Strings for local_authentication plugin. Currently supports English. +// Intl.message must be string literals. + +/// Hint message advising the user how to authenticate with biometrics. It is +/// used on Android. Maximum 60 characters. +String get androidBiometricHint => Intl.message('Verify identity', + desc: + 'Hint message advising the user how to authenticate with biometrics. It is ' + 'used on Android. Maximum 60 characters.'); + +/// Message to let the user know that authentication was failed. It is used +/// on Android. Maximum 60 characters.' +String get androidBiometricNotRecognized => + Intl.message('Not recognized. Try again.', + desc: 'Message to let the user know that authentication was failed. It ' + 'is used on Android. Maximum 60 characters.'); + +/// Message to let the user know that authentication was successful. It +/// is used on Android. Maximum 60 characters +String get androidBiometricSuccess => Intl.message('Success', + desc: 'Message to let the user know that authentication was successful. It ' + 'is used on Android. Maximum 60 characters.'); + +/// Message shown on a button that the user can click to leave the +/// current dialog. It is used on Android. Maximum 30 characters. +String get androidCancelButton => Intl.message('Cancel', + desc: 'Message shown on a button that the user can click to leave the ' + 'current dialog. It is used on Android. Maximum 30 characters.'); + +/// Message shown as a title in a dialog which indicates the user +/// that they need to scan biometric to continue. It is used on +/// Android. Maximum 60 characters. +String get androidSignInTitle => Intl.message('Authentication required', + desc: 'Message shown as a title in a dialog which indicates the user ' + 'that they need to scan biometric to continue. It is used on ' + 'Android. Maximum 60 characters.'); + +/// Message shown as a title in a dialog which indicates the user +/// has not set up biometric authentication on their device. It is used on +/// Android. Maximum 60 characters. +String get androidBiometricRequiredTitle => Intl.message('Biometric required', + desc: 'Message shown as a title in a dialog which indicates the user ' + 'has not set up biometric authentication on their device. It is used on Android.' + ' Maximum 60 characters.'); + +/// Message shown as a title in a dialog which indicates the user +/// has not set up credentials authentication on their device. It is used on Android. +/// Maximum 60 characters. +String get androidDeviceCredentialsRequiredTitle => Intl.message( + 'Device credentials required', + desc: 'Message shown as a title in a dialog which indicates the user ' + 'has not set up credentials authentication on their device. It is used on Android.' + ' Maximum 60 characters.'); + +/// Message advising the user to go to the settings and configure +/// device credentials on their device. It shows in a dialog on Android. +String get androidDeviceCredentialsSetupDescription => Intl.message( + 'Device credentials required', + desc: 'Message advising the user to go to the settings and configure ' + 'device credentials on their device. It shows in a dialog on Android.'); + +/// Message advising the user to go to the settings and configure +/// biometric on their device. It shows in a dialog on Android. +String get androidGoToSettingsDescription => Intl.message( + 'Biometric authentication is not set up on your device. Go to ' + '\'Settings > Security\' to add biometric authentication.', + desc: 'Message advising the user to go to the settings and configure ' + 'biometric on their device. It shows in a dialog on Android.'); diff --git a/packages/local_auth/local_auth_android/pubspec.yaml b/packages/local_auth/local_auth_android/pubspec.yaml new file mode 100644 index 000000000000..e677132205f2 --- /dev/null +++ b/packages/local_auth/local_auth_android/pubspec.yaml @@ -0,0 +1,32 @@ +name: local_auth_android +description: Android implementation of the local_auth plugin. +repository: https://github.com/flutter/plugins/tree/master/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 +# NOTE: We strongly prefer non-breaking changes, even at the expense of a +# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes +version: 1.0.0 + +flutter: + plugin: + platforms: + android: + package: io.flutter.plugins.localauth + pluginClass: LocalAuthPlugin + dartPluginClass: LocalAuthAndroid + +environment: + sdk: ">=2.14.0 <3.0.0" + flutter: ">=2.8.0" + +dependencies: + flutter: + sdk: flutter + flutter_plugin_android_lifecycle: ^2.0.1 + intl: ^0.17.0 + local_auth_platform_interface: + path: ../local_auth_platform_interface + +dev_dependencies: + flutter_test: + sdk: flutter + mockito: ^5.0.0 \ No newline at end of file diff --git a/packages/local_auth/local_auth_android/test/local_auth_test.dart b/packages/local_auth/local_auth_android/test/local_auth_test.dart new file mode 100644 index 000000000000..b81884be8051 --- /dev/null +++ b/packages/local_auth/local_auth_android/test/local_auth_test.dart @@ -0,0 +1,122 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:local_auth_android/local_auth_android.dart'; +import 'package:local_auth_android/types/auth_strings_android.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('LocalAuth', () { + const MethodChannel channel = MethodChannel( + 'plugins.flutter.io/local_auth_android', + ); + + final List log = []; + late LocalAuthAndroid localAuthentication; + + setUp(() { + channel.setMockMethodCallHandler((MethodCall methodCall) { + log.add(methodCall); + return Future.value(true); + }); + localAuthentication = LocalAuthAndroid(); + log.clear(); + }); + + group('With device auth fail over', () { + test('authenticate with no args on Android.', () async { + await localAuthentication.authenticate( + authStrings: const AndroidAuthMessages().args, + localizedReason: 'Needs secure', + biometricOnly: true, + ); + expect( + log, + [ + isMethodCall('authenticate', + arguments: { + 'localizedReason': 'Needs secure', + 'useErrorDialogs': true, + 'stickyAuth': false, + 'sensitiveTransaction': true, + 'biometricOnly': true, + }..addAll(const AndroidAuthMessages().args)), + ], + ); + }); + + test('authenticate with no sensitive transaction.', () async { + await localAuthentication.authenticate( + authStrings: const AndroidAuthMessages().args, + localizedReason: 'Insecure', + sensitiveTransaction: false, + useErrorDialogs: false, + biometricOnly: true, + ); + expect( + log, + [ + isMethodCall('authenticate', + arguments: { + 'localizedReason': 'Insecure', + 'useErrorDialogs': false, + 'stickyAuth': false, + 'sensitiveTransaction': false, + 'biometricOnly': true, + }..addAll(const AndroidAuthMessages().args)), + ], + ); + }); + }); + + group('With biometrics only', () { + test('authenticate with no args on Android.', () async { + await localAuthentication.authenticate( + authStrings: const AndroidAuthMessages().args, + localizedReason: 'Needs secure', + ); + expect( + log, + [ + isMethodCall('authenticate', + arguments: { + 'localizedReason': 'Needs secure', + 'useErrorDialogs': true, + 'stickyAuth': false, + 'sensitiveTransaction': true, + 'biometricOnly': false, + }..addAll(const AndroidAuthMessages().args)), + ], + ); + }); + + test('authenticate with no sensitive transaction.', () async { + await localAuthentication.authenticate( + authStrings: const AndroidAuthMessages().args, + localizedReason: 'Insecure', + sensitiveTransaction: false, + useErrorDialogs: false, + ); + expect( + log, + [ + isMethodCall('authenticate', + arguments: { + 'localizedReason': 'Insecure', + 'useErrorDialogs': false, + 'stickyAuth': false, + 'sensitiveTransaction': false, + 'biometricOnly': false, + }..addAll(const AndroidAuthMessages().args)), + ], + ); + }); + }); + }); +} diff --git a/packages/local_auth/local_auth_platform_interface/analysis_options.yaml b/packages/local_auth/local_auth_platform_interface/analysis_options.yaml deleted file mode 100644 index a5744c1cfbe7..000000000000 --- a/packages/local_auth/local_auth_platform_interface/analysis_options.yaml +++ /dev/null @@ -1,4 +0,0 @@ -include: package:flutter_lints/flutter.yaml - -# Additional information about this file can be found at -# https://dart.dev/guides/language/analysis-options diff --git a/packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart b/packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart new file mode 100644 index 000000000000..5256f3d6070d --- /dev/null +++ b/packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart @@ -0,0 +1,65 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/services.dart'; +import 'package:local_auth_platform_interface/local_auth_platform_interface.dart'; +import 'package:local_auth_platform_interface/types/auth_options.dart'; +import 'package:local_auth_platform_interface/types/biometric_type.dart'; + +const MethodChannel _channel = MethodChannel('plugins.flutter.io/local_auth'); + +/// The default interface implementation acting as a placeholder for +/// the native implementation to be set. +class DefaultLocalAuthPlatform extends LocalAuthPlatform { + @override + Future authenticate({ + required String localizedReason, + required Map authStrings, + AuthenticationOptions options = const AuthenticationOptions(), + }) async { + assert(localizedReason.isNotEmpty); + final Map args = { + 'localizedReason': localizedReason, + 'useErrorDialogs': options.useErrorDialogs, + 'stickyAuth': options.stickyAuth, + 'sensitiveTransaction': options.sensitiveTransaction, + 'biometricOnly': options.biometricOnly, + }; + args.addAll(authStrings); + return (await _channel.invokeMethod('authenticate', args)) ?? false; + } + + @override + Future> getAvailableBiometrics() async { + final List result = (await _channel.invokeListMethod( + 'getAvailableBiometrics', + )) ?? + []; + final List biometrics = []; + for (final String value in result) { + switch (value) { + case 'face': + biometrics.add(BiometricType.face); + break; + case 'fingerprint': + biometrics.add(BiometricType.fingerprint); + break; + case 'iris': + biometrics.add(BiometricType.iris); + break; + case 'undefined': + break; + } + } + return biometrics; + } + + @override + Future isDeviceSupported() async => + (await _channel.invokeMethod('isDeviceSupported')) ?? false; + + @override + Future stopAuthentication() async => + await _channel.invokeMethod('stopAuthentication') ?? false; +} diff --git a/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart b/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart index 833004b7e032..32f039e86063 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:local_auth_platform_interface/default_method_channel_platform.dart'; +import 'package:local_auth_platform_interface/types/auth_options.dart'; import 'package:local_auth_platform_interface/types/biometric_type.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; @@ -25,8 +27,9 @@ abstract class LocalAuthPlatform extends PlatformInterface { /// Defaults to [DefaultLocalAuthPlatform]. static LocalAuthPlatform get instance => _instance; - /// Platform-specific plugins should set this with their own platform-specific - /// class that extends [LocalAuthPlatform] when they register themselves. + /// Platform-specific implementations should set this with their own + /// platform-specific class that extends [LocalAuthPlatform] when they + /// register themselves. static set instance(LocalAuthPlatform instance) { PlatformInterface.verifyToken(instance, _token); _instance = instance; @@ -42,31 +45,10 @@ abstract class LocalAuthPlatform extends PlatformInterface { /// for authentication. This is typically along the lines of: 'Please scan /// your finger to access MyApp.'. This must not be empty. /// - /// [useErrorDialogs] = true means the system will attempt to handle user - /// fixable issues encountered while authenticating. For instance, if - /// fingerprint reader exists on the phone but there's no fingerprint - /// registered, the plugin will attempt to take the user to settings to add - /// one. Anything that is not user fixable, such as no biometric sensor on - /// device, will be returned as a [PlatformException]. - /// - /// [stickyAuth] is used when the application goes into background for any - /// reason while the authentication is in progress. Due to security reasons, - /// the authentication has to be stopped at that time. If stickyAuth is set - /// to true, authentication resumes when the app is resumed. If it is set to - /// false (default), then as soon as app is paused a failure message is sent - /// back to Dart and it is up to the client app to restart authentication or - /// do something else. - /// /// Provide [authStrings] if you want to /// customize messages in the dialogs. /// - /// Setting [sensitiveTransaction] to true enables platform specific - /// precautions. For instance, on face unlock, Android opens a confirmation - /// dialog after the face is recognized to make sure the user meant to unlock - /// their phone. - /// - /// Setting [biometricOnly] to true prevents authenticates from using non-biometric - /// local authentication such as pin, passcode, and passcode. + /// Provide [options] for configuring further authentication related options. /// /// Throws an [PlatformException] if there were technical problems with local /// authentication (e.g. lack of relevant hardware). This might throw @@ -74,11 +56,8 @@ abstract class LocalAuthPlatform extends PlatformInterface { /// simulator. Future authenticate({ required String localizedReason, - bool useErrorDialogs = true, - bool stickyAuth = false, required Map authStrings, - bool sensitiveTransaction = true, - bool biometricOnly = false, + AuthenticationOptions options = const AuthenticationOptions(), }) async { throw UnimplementedError('authenticate() has not been implemented.'); } @@ -110,7 +89,3 @@ abstract class LocalAuthPlatform extends PlatformInterface { throw UnimplementedError('stopAuthentication() has not been implemented.'); } } - -/// The default interface implementation acting as a placeholder for -/// the native implementation to be set. -class DefaultLocalAuthPlatform extends LocalAuthPlatform {} diff --git a/packages/local_auth/local_auth_platform_interface/lib/types/auth_options.dart b/packages/local_auth/local_auth_platform_interface/lib/types/auth_options.dart new file mode 100644 index 000000000000..8a8efc6c2411 --- /dev/null +++ b/packages/local_auth/local_auth_platform_interface/lib/types/auth_options.dart @@ -0,0 +1,40 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/// Options wrapper for [LocalAuthPlatform.authenticate] parameters. +class AuthenticationOptions { + /// Construct a new instance. + const AuthenticationOptions({ + this.useErrorDialogs = true, + this.stickyAuth = false, + this.sensitiveTransaction = true, + this.biometricOnly = false, + }); + + /// Whether the system will attempt to handle user fixable issues encountered + /// while authenticating. For instance, if fingerprint reader exists on the + /// phone but there's no fingerprint registered, the plugin will attempt to + /// take the user to settings to add one. Anything that is not user fixable, + /// such as no biometric sensor on device, will be returned + /// as a [PlatformException]. + final bool useErrorDialogs; + + /// Used when the application goes into background for any reason while the + /// authentication is in progress. Due to security reasons, the + /// authentication has to be stopped at that time. If stickyAuth is set to + /// true, authentication resumes when the app is resumed. If it is set to + /// false (default), then as soon as app is paused a failure message is sent + /// back to Dart and it is up to the client app to restart authentication or + /// do something else. + final bool stickyAuth; + + /// Whether platform specific precautions are enabled. For instance, on face + /// unlock, Android opens a confirmation dialog after the face is recognized + /// to make sure the user meant to unlock their phone. + final bool sensitiveTransaction; + + /// Prevent authentications from using non-biometric local authentication + /// such as pin, passcode, and passcode. + final bool biometricOnly; +} diff --git a/packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart b/packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart index 0ad81392edb9..be75ea1fe880 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart @@ -4,7 +4,10 @@ import 'package:intl/intl.dart'; +/// Message shown on a button that the user can click to go to settings pages +/// from the current dialog. It is used on both Android and iOS sides. +/// Maximum 30 characters. String get goToSettings => Intl.message('Go to settings', - desc: 'Message showed on a button that the user can click to go to ' + desc: 'Message shown on a button that the user can click to go to ' 'settings pages from the current dialog. It is used on both Android ' - 'and iOS side. Maximum 30 characters.'); + 'and iOS sides. Maximum 30 characters.'); diff --git a/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart b/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart index 23556ab37caa..9c7d2eb8d83e 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart @@ -2,4 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -enum BiometricType { face, fingerprint, iris } +/// Various types of biometric authentication. +enum BiometricType { + /// Face authentication. + face, + + /// Fingerprint authentication. + fingerprint, + + /// Iris authentication. + iris, + + /// Any biometric (e.g. fingerprint, iris, or face) on the device that meets + /// or exceeds the requirements for Class 3 (formerly Strong), as defined + /// by the Android CDD. Android only. + strong, + + /// Any biometric (e.g. fingerprint, iris, or face) on the device that meets + /// or exceeds the requirements for Class 2 (formerly Weak), as defined + /// by the Android CDD. Android only. + weak, +} diff --git a/packages/local_auth/local_auth_platform_interface/pubspec.yaml b/packages/local_auth/local_auth_platform_interface/pubspec.yaml index 0f88856bf4ee..f04268926ebd 100644 --- a/packages/local_auth/local_auth_platform_interface/pubspec.yaml +++ b/packages/local_auth/local_auth_platform_interface/pubspec.yaml @@ -1,7 +1,7 @@ name: local_auth_platform_interface description: A common platform interface for the local_auth plugin. repository: https://github.com/flutter/plugins/tree/master/packages/local_auth/local_auth_platform_interface -issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22 +issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+local_auth%22 # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes version: 1.0.0 @@ -13,8 +13,8 @@ environment: dependencies: flutter: sdk: flutter - plugin_platform_interface: ^2.1.2 intl: ^0.17.0 + plugin_platform_interface: ^2.1.2 dev_dependencies: flutter_test: diff --git a/packages/local_auth/local_auth_platform_interface/test/default_method_channel_platform_test.dart b/packages/local_auth/local_auth_platform_interface/test/default_method_channel_platform_test.dart new file mode 100644 index 000000000000..d1ee3c504c40 --- /dev/null +++ b/packages/local_auth/local_auth_platform_interface/test/default_method_channel_platform_test.dart @@ -0,0 +1,172 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:local_auth_platform_interface/default_method_channel_platform.dart'; +import 'package:local_auth_platform_interface/local_auth_platform_interface.dart'; +import 'package:local_auth_platform_interface/types/auth_options.dart'; +import 'package:local_auth_platform_interface/types/biometric_type.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + const MethodChannel channel = MethodChannel( + 'plugins.flutter.io/local_auth', + ); + + final List log = []; + late LocalAuthPlatform localAuthentication; + + test('getAvailableBiometrics', () async { + channel.setMockMethodCallHandler((MethodCall methodCall) { + log.add(methodCall); + return Future.value([]); + }); + localAuthentication = DefaultLocalAuthPlatform(); + log.clear(); + await localAuthentication.getAvailableBiometrics(); + expect( + log, + [ + isMethodCall('getAvailableBiometrics', arguments: null), + ], + ); + }); + + group('Boolean returning methods', () { + setUp(() { + channel.setMockMethodCallHandler((MethodCall methodCall) { + log.add(methodCall); + return Future.value(true); + }); + localAuthentication = DefaultLocalAuthPlatform(); + log.clear(); + }); + + test('isDeviceSupported', () async { + await localAuthentication.isDeviceSupported(); + expect( + log, + [ + isMethodCall('isDeviceSupported', arguments: null), + ], + ); + }); + + test('stopAuthentication', () async { + await localAuthentication.stopAuthentication(); + expect( + log, + [ + isMethodCall('stopAuthentication', arguments: null), + ], + ); + }); + + group('authenticate with device auth fail over', () { + test('authenticate with no args.', () async { + await localAuthentication.authenticate( + authStrings: {}, + localizedReason: 'Needs secure', + options: const AuthenticationOptions(biometricOnly: true), + ); + expect( + log, + [ + isMethodCall( + 'authenticate', + arguments: { + 'localizedReason': 'Needs secure', + 'useErrorDialogs': true, + 'stickyAuth': false, + 'sensitiveTransaction': true, + 'biometricOnly': true, + }, + ), + ], + ); + }); + + test('authenticate with no sensitive transaction.', () async { + await localAuthentication.authenticate( + authStrings: {}, + localizedReason: 'Insecure', + options: const AuthenticationOptions( + sensitiveTransaction: false, + useErrorDialogs: false, + biometricOnly: true, + ), + ); + expect( + log, + [ + isMethodCall( + 'authenticate', + arguments: { + 'localizedReason': 'Insecure', + 'useErrorDialogs': false, + 'stickyAuth': false, + 'sensitiveTransaction': false, + 'biometricOnly': true, + }, + ), + ], + ); + }); + }); + + group('authenticate with biometrics only', () { + test('authenticate with no args.', () async { + await localAuthentication.authenticate( + authStrings: {}, + localizedReason: 'Needs secure', + ); + expect( + log, + [ + isMethodCall( + 'authenticate', + arguments: { + 'localizedReason': 'Needs secure', + 'useErrorDialogs': true, + 'stickyAuth': false, + 'sensitiveTransaction': true, + 'biometricOnly': false, + }, + ), + ], + ); + }); + + test('authenticate with no sensitive transaction.', () async { + await localAuthentication.authenticate( + authStrings: {}, + localizedReason: 'Insecure', + options: const AuthenticationOptions( + sensitiveTransaction: false, + useErrorDialogs: false, + ), + ); + expect( + log, + [ + isMethodCall( + 'authenticate', + arguments: { + 'localizedReason': 'Insecure', + 'useErrorDialogs': false, + 'stickyAuth': false, + 'sensitiveTransaction': false, + 'biometricOnly': false, + }, + ), + ], + ); + }); + }); + }); +} From af311ccc6a5c5ccf87125bdb35827fa437f610ab Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Thu, 27 Jan 2022 12:49:28 +0100 Subject: [PATCH 09/36] Adjust to changes in platform interface --- .../local_auth_android/example/lib/main.dart | 20 ++++++++++++------- .../lib/local_auth_android.dart | 15 +++++++------- .../test/local_auth_test.dart | 16 +++++++++------ 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/packages/local_auth/local_auth_android/example/lib/main.dart b/packages/local_auth/local_auth_android/example/lib/main.dart index 4328f28136c2..d94b4ed894c9 100644 --- a/packages/local_auth/local_auth_android/example/lib/main.dart +++ b/packages/local_auth/local_auth_android/example/lib/main.dart @@ -80,10 +80,13 @@ class _MyAppState extends State { _authorized = 'Authenticating'; }); authenticated = await auth.authenticate( - localizedReason: 'Let OS determine authentication method', - authStrings: const AndroidAuthMessages().args, + localizedReason: 'Let OS determine authentication method', + authStrings: const AndroidAuthMessages().args, + options: const AuthenticationOptions( useErrorDialogs: true, - stickyAuth: true); + stickyAuth: true, + ), + ); setState(() { _isAuthenticating = false; }); @@ -111,12 +114,15 @@ class _MyAppState extends State { _authorized = 'Authenticating'; }); authenticated = await auth.authenticate( - localizedReason: - 'Scan your fingerprint (or face or whatever) to authenticate', - authStrings: const AndroidAuthMessages().args, + localizedReason: + 'Scan your fingerprint (or face or whatever) to authenticate', + authStrings: const AndroidAuthMessages().args, + options: const AuthenticationOptions( useErrorDialogs: true, stickyAuth: true, - biometricOnly: true); + biometricOnly: true, + ), + ); setState(() { _isAuthenticating = false; _authorized = 'Authenticating'; diff --git a/packages/local_auth/local_auth_android/lib/local_auth_android.dart b/packages/local_auth/local_auth_android/lib/local_auth_android.dart index 0f82e7cf9158..1869506035f1 100644 --- a/packages/local_auth/local_auth_android/lib/local_auth_android.dart +++ b/packages/local_auth/local_auth_android/lib/local_auth_android.dart @@ -4,8 +4,10 @@ import 'package:flutter/services.dart'; import 'package:local_auth_platform_interface/local_auth_platform_interface.dart'; +import 'package:local_auth_platform_interface/types/auth_options.dart'; import 'package:local_auth_platform_interface/types/biometric_type.dart'; +export 'package:local_auth_platform_interface/types/auth_options.dart'; export 'package:local_auth_platform_interface/types/biometric_type.dart'; const MethodChannel _channel = @@ -21,19 +23,16 @@ class LocalAuthAndroid extends LocalAuthPlatform { @override Future authenticate({ required String localizedReason, - bool useErrorDialogs = true, - bool stickyAuth = false, required Map authStrings, - bool sensitiveTransaction = true, - bool biometricOnly = false, + AuthenticationOptions options = const AuthenticationOptions(), }) async { assert(localizedReason.isNotEmpty); final Map args = { 'localizedReason': localizedReason, - 'useErrorDialogs': useErrorDialogs, - 'stickyAuth': stickyAuth, - 'sensitiveTransaction': sensitiveTransaction, - 'biometricOnly': biometricOnly, + 'useErrorDialogs': options.useErrorDialogs, + 'stickyAuth': options.stickyAuth, + 'sensitiveTransaction': options.sensitiveTransaction, + 'biometricOnly': options.biometricOnly, }; args.addAll(authStrings); return (await _channel.invokeMethod('authenticate', args)) ?? false; diff --git a/packages/local_auth/local_auth_android/test/local_auth_test.dart b/packages/local_auth/local_auth_android/test/local_auth_test.dart index b81884be8051..33be63657dee 100644 --- a/packages/local_auth/local_auth_android/test/local_auth_test.dart +++ b/packages/local_auth/local_auth_android/test/local_auth_test.dart @@ -34,7 +34,7 @@ void main() { await localAuthentication.authenticate( authStrings: const AndroidAuthMessages().args, localizedReason: 'Needs secure', - biometricOnly: true, + options: const AuthenticationOptions(biometricOnly: true), ); expect( log, @@ -55,9 +55,11 @@ void main() { await localAuthentication.authenticate( authStrings: const AndroidAuthMessages().args, localizedReason: 'Insecure', - sensitiveTransaction: false, - useErrorDialogs: false, - biometricOnly: true, + options: const AuthenticationOptions( + sensitiveTransaction: false, + useErrorDialogs: false, + biometricOnly: true, + ), ); expect( log, @@ -100,8 +102,10 @@ void main() { await localAuthentication.authenticate( authStrings: const AndroidAuthMessages().args, localizedReason: 'Insecure', - sensitiveTransaction: false, - useErrorDialogs: false, + options: const AuthenticationOptions( + sensitiveTransaction: false, + useErrorDialogs: false, + ), ); expect( log, From 4266130323bbcc31917b4f8d0448dc872bdf9f46 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Thu, 27 Jan 2022 12:53:31 +0100 Subject: [PATCH 10/36] Added missing implements field in pubspec --- packages/local_auth/local_auth_android/pubspec.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/local_auth/local_auth_android/pubspec.yaml b/packages/local_auth/local_auth_android/pubspec.yaml index e677132205f2..6b6157bfa68b 100644 --- a/packages/local_auth/local_auth_android/pubspec.yaml +++ b/packages/local_auth/local_auth_android/pubspec.yaml @@ -8,6 +8,7 @@ version: 1.0.0 flutter: plugin: + implements: local_auth platforms: android: package: io.flutter.plugins.localauth From 24765b28c105ff667637214e37e3b13e7220e34d Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Mon, 31 Jan 2022 09:42:15 +0100 Subject: [PATCH 11/36] Update doc in default method channel platform --- .../lib/default_method_channel_platform.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart b/packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart index 5256f3d6070d..1a44fcf2a5ac 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart @@ -11,6 +11,11 @@ const MethodChannel _channel = MethodChannel('plugins.flutter.io/local_auth'); /// The default interface implementation acting as a placeholder for /// the native implementation to be set. +/// +/// This implementation is not used by any of the implementations in this +/// repository, and exists only for backward compatibility with any +/// clients that were relying on internal details of the method channel +/// in the pre-federated plugin. class DefaultLocalAuthPlatform extends LocalAuthPlatform { @override Future authenticate({ From 81ba7e84a15f9daab268e844de21a5de0c97bfb8 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Mon, 31 Jan 2022 15:09:45 +0100 Subject: [PATCH 12/36] Implement PR feedback --- .../lib/default_method_channel_platform.dart | 5 ++++ .../lib/local_auth_platform_interface.dart | 23 +++++++++++-------- .../lib/types/auth_options.dart | 16 ++++++------- .../lib/types/auth_strings.dart | 2 +- .../lib/types/biometric_type.dart | 14 ++++++----- .../default_method_channel_platform_test.dart | 7 ++++++ 6 files changed, 43 insertions(+), 24 deletions(-) diff --git a/packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart b/packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart index 1a44fcf2a5ac..866ae44828e5 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart @@ -60,6 +60,11 @@ class DefaultLocalAuthPlatform extends LocalAuthPlatform { return biometrics; } + @override + Future canCheckBiometrics() async { + return (await getAvailableBiometrics()).isNotEmpty; + } + @override Future isDeviceSupported() async => (await _channel.invokeMethod('isDeviceSupported')) ?? false; diff --git a/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart b/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart index 32f039e86063..ad363601ee85 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart @@ -38,8 +38,7 @@ abstract class LocalAuthPlatform extends PlatformInterface { /// Authenticates the user with biometrics available on the device while also /// allowing the user to use device authentication - pin, pattern, passcode. /// - /// Returns a [Future] holding true, if the user successfully authenticated, - /// false otherwise. + /// Returns true if the user successfully authenticated, false otherwise. /// /// [localizedReason] is the message to show to user while prompting them /// for authentication. This is typically along the lines of: 'Please scan @@ -50,7 +49,7 @@ abstract class LocalAuthPlatform extends PlatformInterface { /// /// Provide [options] for configuring further authentication related options. /// - /// Throws an [PlatformException] if there were technical problems with local + /// Throws a [PlatformException] if there were technical problems with local /// authentication (e.g. lack of relevant hardware). This might throw /// [PlatformException] with error code [otherOperatingSystem] on the iOS /// simulator. @@ -62,12 +61,19 @@ abstract class LocalAuthPlatform extends PlatformInterface { throw UnimplementedError('authenticate() has not been implemented.'); } + /// Returns true if the device is capable of checking biometrics. + Future canCheckBiometrics() async { + throw UnimplementedError('canCheckBiometrics() has not been implemented.'); + } + /// Returns a list of enrolled biometrics. /// - /// Returns a [Future] List with the following possibilities: + /// Possible values include: /// - BiometricType.face /// - BiometricType.fingerprint /// - BiometricType.iris (not yet implemented) + /// - BiometricType.strong + /// - BiometricType.weak Future> getAvailableBiometrics() async { throw UnimplementedError( 'getAvailableBiometrics() has not been implemented.'); @@ -75,16 +81,15 @@ abstract class LocalAuthPlatform extends PlatformInterface { /// Returns true if device is capable of checking biometrics or is able to /// fail over to device credentials. - /// - /// Returns a [Future] bool true or false: Future isDeviceSupported() async { throw UnimplementedError('isDeviceSupported() has not been implemented.'); } - /// Returns true if auth was cancelled successfully. - /// Returns false if there was some error or no auth in progress. + /// Cancels any authentication currently in progress. /// - /// Returns [Future] bool true or false: + /// Returns true if auth was cancelled successfully. + /// Returns false if there was no authentication in progress, + /// or an error occurred. Future stopAuthentication() async { throw UnimplementedError('stopAuthentication() has not been implemented.'); } diff --git a/packages/local_auth/local_auth_platform_interface/lib/types/auth_options.dart b/packages/local_auth/local_auth_platform_interface/lib/types/auth_options.dart index 8a8efc6c2411..f858126dcb63 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/types/auth_options.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/types/auth_options.dart @@ -4,7 +4,7 @@ /// Options wrapper for [LocalAuthPlatform.authenticate] parameters. class AuthenticationOptions { - /// Construct a new instance. + /// Constructs a new instance. const AuthenticationOptions({ this.useErrorDialogs = true, this.stickyAuth = false, @@ -12,12 +12,12 @@ class AuthenticationOptions { this.biometricOnly = false, }); - /// Whether the system will attempt to handle user fixable issues encountered - /// while authenticating. For instance, if fingerprint reader exists on the - /// phone but there's no fingerprint registered, the plugin will attempt to + /// Whether the system will attempt to handle user-fixable issues encountered + /// while authenticating. For instance, if a fingerprint reader exists on the + /// device but there's no fingerprint registered, the plugin might attempt to /// take the user to settings to add one. Anything that is not user fixable, - /// such as no biometric sensor on device, will be returned - /// as a [PlatformException]. + /// such as no biometric sensor on device, will still result in + /// a [PlatformException]. final bool useErrorDialogs; /// Used when the application goes into background for any reason while the @@ -31,10 +31,10 @@ class AuthenticationOptions { /// Whether platform specific precautions are enabled. For instance, on face /// unlock, Android opens a confirmation dialog after the face is recognized - /// to make sure the user meant to unlock their phone. + /// to make sure the user meant to unlock their device. final bool sensitiveTransaction; /// Prevent authentications from using non-biometric local authentication - /// such as pin, passcode, and passcode. + /// such as pin, passcode, or pattern. final bool biometricOnly; } diff --git a/packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart b/packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart index be75ea1fe880..d1604cb9df1c 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart @@ -5,7 +5,7 @@ import 'package:intl/intl.dart'; /// Message shown on a button that the user can click to go to settings pages -/// from the current dialog. It is used on both Android and iOS sides. +/// from the current dialog. It is used on applicable platforms. /// Maximum 30 characters. String get goToSettings => Intl.message('Go to settings', desc: 'Message shown on a button that the user can click to go to ' diff --git a/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart b/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart index 9c7d2eb8d83e..c4efd0deb3cb 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart @@ -3,6 +3,8 @@ // found in the LICENSE file. /// Various types of biometric authentication. +/// Some platforms report specific biometric types, while others report only +/// classifications like strong and weak. enum BiometricType { /// Face authentication. face, @@ -13,13 +15,13 @@ enum BiometricType { /// Iris authentication. iris, - /// Any biometric (e.g. fingerprint, iris, or face) on the device that meets - /// or exceeds the requirements for Class 3 (formerly Strong), as defined - /// by the Android CDD. Android only. + /// Any biometric (e.g. fingerprint, iris, or face) on the device that the + /// platform API considers to be strong. For example, on Android this + /// corresponds to Class 3. strong, - /// Any biometric (e.g. fingerprint, iris, or face) on the device that meets - /// or exceeds the requirements for Class 2 (formerly Weak), as defined - /// by the Android CDD. Android only. + /// Any biometric (e.g. fingerprint, iris, or face) on the device that the + /// platform API considers to be strong. For example, on Android this + /// corresponds to Class 2. weak, } diff --git a/packages/local_auth/local_auth_platform_interface/test/default_method_channel_platform_test.dart b/packages/local_auth/local_auth_platform_interface/test/default_method_channel_platform_test.dart index d1ee3c504c40..64d8aa0284af 100644 --- a/packages/local_auth/local_auth_platform_interface/test/default_method_channel_platform_test.dart +++ b/packages/local_auth/local_auth_platform_interface/test/default_method_channel_platform_test.dart @@ -21,6 +21,13 @@ void main() { final List log = []; late LocalAuthPlatform localAuthentication; + test( + 'DefaultLocalAuthPlatform is registered as the default platform implementation', + () async { + expect(LocalAuthPlatform.instance, + const TypeMatcher()); + }); + test('getAvailableBiometrics', () async { channel.setMockMethodCallHandler((MethodCall methodCall) { log.add(methodCall); From a371a8701b67e64bbd221c16db19aaa7a1b3a7ca Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Mon, 7 Feb 2022 09:46:52 +0100 Subject: [PATCH 13/36] Move string to Android package --- .../lib/types/auth_strings_android.dart | 8 +++++++- .../lib/types/auth_strings.dart | 13 ------------- 2 files changed, 7 insertions(+), 14 deletions(-) delete mode 100644 packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart diff --git a/packages/local_auth/local_auth_android/lib/types/auth_strings_android.dart b/packages/local_auth/local_auth_android/lib/types/auth_strings_android.dart index 9d9886ce7168..303bec38b36f 100644 --- a/packages/local_auth/local_auth_android/lib/types/auth_strings_android.dart +++ b/packages/local_auth/local_auth_android/lib/types/auth_strings_android.dart @@ -3,7 +3,6 @@ // found in the LICENSE file. import 'package:intl/intl.dart'; -import 'package:local_auth_platform_interface/types/auth_strings.dart'; /// Android side authentication messages. /// @@ -92,6 +91,13 @@ class AndroidAuthMessages { // Strings for local_authentication plugin. Currently supports English. // Intl.message must be string literals. +/// Message shown on a button that the user can click to go to settings pages +/// from the current dialog. Maximum 30 characters. +String get goToSettings => Intl.message('Go to settings', + desc: 'Message shown on a button that the user can click to go to ' + 'settings pages from the current dialog. It is used on both Android ' + 'and iOS sides. Maximum 30 characters.'); + /// Hint message advising the user how to authenticate with biometrics. It is /// used on Android. Maximum 60 characters. String get androidBiometricHint => Intl.message('Verify identity', diff --git a/packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart b/packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart deleted file mode 100644 index d1604cb9df1c..000000000000 --- a/packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:intl/intl.dart'; - -/// Message shown on a button that the user can click to go to settings pages -/// from the current dialog. It is used on applicable platforms. -/// Maximum 30 characters. -String get goToSettings => Intl.message('Go to settings', - desc: 'Message shown on a button that the user can click to go to ' - 'settings pages from the current dialog. It is used on both Android ' - 'and iOS sides. Maximum 30 characters.'); From c4086e8dfd5c848f29c5325dbb9b94671cb6e03b Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Mon, 7 Feb 2022 09:47:33 +0100 Subject: [PATCH 14/36] Remove auth strings from platform interface --- .../lib/types/auth_strings.dart | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart diff --git a/packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart b/packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart deleted file mode 100644 index d1604cb9df1c..000000000000 --- a/packages/local_auth/local_auth_platform_interface/lib/types/auth_strings.dart +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:intl/intl.dart'; - -/// Message shown on a button that the user can click to go to settings pages -/// from the current dialog. It is used on applicable platforms. -/// Maximum 30 characters. -String get goToSettings => Intl.message('Go to settings', - desc: 'Message shown on a button that the user can click to go to ' - 'settings pages from the current dialog. It is used on both Android ' - 'and iOS sides. Maximum 30 characters.'); From c0a867efb44ae9961498d63e9fabcf49f5121aaf Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Mon, 7 Feb 2022 10:23:27 +0100 Subject: [PATCH 15/36] Change interface for handing platform specific messages Change interface for handling platform specific messages --- .../lib/default_method_channel_platform.dart | 7 +++++-- .../lib/local_auth_platform_interface.dart | 5 +++-- .../lib/types/auth_messages.dart | 13 +++++++++++++ .../test/default_method_channel_platform_test.dart | 9 +++++---- 4 files changed, 26 insertions(+), 8 deletions(-) create mode 100644 packages/local_auth/local_auth_platform_interface/lib/types/auth_messages.dart diff --git a/packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart b/packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart index 866ae44828e5..b239f2368b83 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart @@ -4,6 +4,7 @@ import 'package:flutter/services.dart'; import 'package:local_auth_platform_interface/local_auth_platform_interface.dart'; +import 'package:local_auth_platform_interface/types/auth_messages.dart'; import 'package:local_auth_platform_interface/types/auth_options.dart'; import 'package:local_auth_platform_interface/types/biometric_type.dart'; @@ -20,7 +21,7 @@ class DefaultLocalAuthPlatform extends LocalAuthPlatform { @override Future authenticate({ required String localizedReason, - required Map authStrings, + required Iterable authMessages, AuthenticationOptions options = const AuthenticationOptions(), }) async { assert(localizedReason.isNotEmpty); @@ -31,7 +32,9 @@ class DefaultLocalAuthPlatform extends LocalAuthPlatform { 'sensitiveTransaction': options.sensitiveTransaction, 'biometricOnly': options.biometricOnly, }; - args.addAll(authStrings); + for (final AuthMessages messages in authMessages) { + args.addAll(messages.args); + } return (await _channel.invokeMethod('authenticate', args)) ?? false; } diff --git a/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart b/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart index ad363601ee85..824725837794 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'package:local_auth_platform_interface/default_method_channel_platform.dart'; +import 'package:local_auth_platform_interface/types/auth_messages.dart'; import 'package:local_auth_platform_interface/types/auth_options.dart'; import 'package:local_auth_platform_interface/types/biometric_type.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; @@ -44,7 +45,7 @@ abstract class LocalAuthPlatform extends PlatformInterface { /// for authentication. This is typically along the lines of: 'Please scan /// your finger to access MyApp.'. This must not be empty. /// - /// Provide [authStrings] if you want to + /// Provide [authMessages] if you want to /// customize messages in the dialogs. /// /// Provide [options] for configuring further authentication related options. @@ -55,7 +56,7 @@ abstract class LocalAuthPlatform extends PlatformInterface { /// simulator. Future authenticate({ required String localizedReason, - required Map authStrings, + required Iterable authMessages, AuthenticationOptions options = const AuthenticationOptions(), }) async { throw UnimplementedError('authenticate() has not been implemented.'); diff --git a/packages/local_auth/local_auth_platform_interface/lib/types/auth_messages.dart b/packages/local_auth/local_auth_platform_interface/lib/types/auth_messages.dart new file mode 100644 index 000000000000..a08cf10325e5 --- /dev/null +++ b/packages/local_auth/local_auth_platform_interface/lib/types/auth_messages.dart @@ -0,0 +1,13 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/// Abstract class for storing platform specific strings. +abstract class AuthMessages { + + /// Constructs an instance of [AuthMessages]. + const AuthMessages(); + + /// Returns all platform specific messages as a map. + Map get args; +} diff --git a/packages/local_auth/local_auth_platform_interface/test/default_method_channel_platform_test.dart b/packages/local_auth/local_auth_platform_interface/test/default_method_channel_platform_test.dart index 64d8aa0284af..d3a7bda7effc 100644 --- a/packages/local_auth/local_auth_platform_interface/test/default_method_channel_platform_test.dart +++ b/packages/local_auth/local_auth_platform_interface/test/default_method_channel_platform_test.dart @@ -8,6 +8,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:local_auth_platform_interface/default_method_channel_platform.dart'; import 'package:local_auth_platform_interface/local_auth_platform_interface.dart'; +import 'package:local_auth_platform_interface/types/auth_messages.dart'; import 'package:local_auth_platform_interface/types/auth_options.dart'; import 'package:local_auth_platform_interface/types/biometric_type.dart'; @@ -77,7 +78,7 @@ void main() { group('authenticate with device auth fail over', () { test('authenticate with no args.', () async { await localAuthentication.authenticate( - authStrings: {}, + authMessages: [], localizedReason: 'Needs secure', options: const AuthenticationOptions(biometricOnly: true), ); @@ -100,7 +101,7 @@ void main() { test('authenticate with no sensitive transaction.', () async { await localAuthentication.authenticate( - authStrings: {}, + authMessages: [], localizedReason: 'Insecure', options: const AuthenticationOptions( sensitiveTransaction: false, @@ -129,7 +130,7 @@ void main() { group('authenticate with biometrics only', () { test('authenticate with no args.', () async { await localAuthentication.authenticate( - authStrings: {}, + authMessages: [], localizedReason: 'Needs secure', ); expect( @@ -151,7 +152,7 @@ void main() { test('authenticate with no sensitive transaction.', () async { await localAuthentication.authenticate( - authStrings: {}, + authMessages: [], localizedReason: 'Insecure', options: const AuthenticationOptions( sensitiveTransaction: false, From 939d3b3ac93d66d06483044ca1ee0726e7ae0724 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Mon, 7 Feb 2022 10:32:30 +0100 Subject: [PATCH 16/36] Implement platform interface changes --- .../local_auth_android/example/lib/main.dart | 5 ++--- .../local_auth_android/lib/local_auth_android.dart | 9 +++++++-- ...strings_android.dart => auth_messages_android.dart} | 5 +++-- .../local_auth_android/test/local_auth_test.dart | 10 +++++----- .../lib/types/auth_messages.dart | 1 - 5 files changed, 17 insertions(+), 13 deletions(-) rename packages/local_auth/local_auth_android/lib/types/{auth_strings_android.dart => auth_messages_android.dart} (98%) diff --git a/packages/local_auth/local_auth_android/example/lib/main.dart b/packages/local_auth/local_auth_android/example/lib/main.dart index d94b4ed894c9..a5de6c09c763 100644 --- a/packages/local_auth/local_auth_android/example/lib/main.dart +++ b/packages/local_auth/local_auth_android/example/lib/main.dart @@ -9,7 +9,6 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:local_auth_android/local_auth_android.dart'; -import 'package:local_auth_android/types/auth_strings_android.dart'; void main() { runApp(MyApp()); @@ -81,7 +80,7 @@ class _MyAppState extends State { }); authenticated = await auth.authenticate( localizedReason: 'Let OS determine authentication method', - authStrings: const AndroidAuthMessages().args, + authMessages: [const AndroidAuthMessages()], options: const AuthenticationOptions( useErrorDialogs: true, stickyAuth: true, @@ -116,7 +115,7 @@ class _MyAppState extends State { authenticated = await auth.authenticate( localizedReason: 'Scan your fingerprint (or face or whatever) to authenticate', - authStrings: const AndroidAuthMessages().args, + authMessages: [const AndroidAuthMessages()], options: const AuthenticationOptions( useErrorDialogs: true, stickyAuth: true, diff --git a/packages/local_auth/local_auth_android/lib/local_auth_android.dart b/packages/local_auth/local_auth_android/lib/local_auth_android.dart index 1869506035f1..57ac9b04180f 100644 --- a/packages/local_auth/local_auth_android/lib/local_auth_android.dart +++ b/packages/local_auth/local_auth_android/lib/local_auth_android.dart @@ -4,9 +4,12 @@ import 'package:flutter/services.dart'; import 'package:local_auth_platform_interface/local_auth_platform_interface.dart'; +import 'package:local_auth_platform_interface/types/auth_messages.dart'; import 'package:local_auth_platform_interface/types/auth_options.dart'; import 'package:local_auth_platform_interface/types/biometric_type.dart'; +export 'package:local_auth_android/types/auth_messages_android.dart'; +export 'package:local_auth_platform_interface/types/auth_messages.dart'; export 'package:local_auth_platform_interface/types/auth_options.dart'; export 'package:local_auth_platform_interface/types/biometric_type.dart'; @@ -23,7 +26,7 @@ class LocalAuthAndroid extends LocalAuthPlatform { @override Future authenticate({ required String localizedReason, - required Map authStrings, + required Iterable authMessages, AuthenticationOptions options = const AuthenticationOptions(), }) async { assert(localizedReason.isNotEmpty); @@ -34,7 +37,9 @@ class LocalAuthAndroid extends LocalAuthPlatform { 'sensitiveTransaction': options.sensitiveTransaction, 'biometricOnly': options.biometricOnly, }; - args.addAll(authStrings); + for (final AuthMessages messages in authMessages) { + args.addAll(messages.args); + } return (await _channel.invokeMethod('authenticate', args)) ?? false; } diff --git a/packages/local_auth/local_auth_android/lib/types/auth_strings_android.dart b/packages/local_auth/local_auth_android/lib/types/auth_messages_android.dart similarity index 98% rename from packages/local_auth/local_auth_android/lib/types/auth_strings_android.dart rename to packages/local_auth/local_auth_android/lib/types/auth_messages_android.dart index 303bec38b36f..db8e75da9f2b 100644 --- a/packages/local_auth/local_auth_android/lib/types/auth_strings_android.dart +++ b/packages/local_auth/local_auth_android/lib/types/auth_messages_android.dart @@ -3,11 +3,12 @@ // found in the LICENSE file. import 'package:intl/intl.dart'; +import 'package:local_auth_platform_interface/types/auth_messages.dart'; /// Android side authentication messages. /// /// Provides default values for all messages. -class AndroidAuthMessages { +class AndroidAuthMessages extends AuthMessages { /// Constructs a new instance. const AndroidAuthMessages({ this.biometricHint, @@ -66,7 +67,7 @@ class AndroidAuthMessages { /// Android. Maximum 60 characters. final String? signInTitle; - /// Gets the messaged stored in this class instance as a string map. + @override Map get args { return { 'biometricHint': biometricHint ?? androidBiometricHint, diff --git a/packages/local_auth/local_auth_android/test/local_auth_test.dart b/packages/local_auth/local_auth_android/test/local_auth_test.dart index 33be63657dee..c4a462507a69 100644 --- a/packages/local_auth/local_auth_android/test/local_auth_test.dart +++ b/packages/local_auth/local_auth_android/test/local_auth_test.dart @@ -7,7 +7,7 @@ import 'dart:async'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:local_auth_android/local_auth_android.dart'; -import 'package:local_auth_android/types/auth_strings_android.dart'; +import 'package:local_auth_platform_interface/types/auth_messages.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); @@ -32,7 +32,7 @@ void main() { group('With device auth fail over', () { test('authenticate with no args on Android.', () async { await localAuthentication.authenticate( - authStrings: const AndroidAuthMessages().args, + authMessages: [const AndroidAuthMessages()], localizedReason: 'Needs secure', options: const AuthenticationOptions(biometricOnly: true), ); @@ -53,7 +53,7 @@ void main() { test('authenticate with no sensitive transaction.', () async { await localAuthentication.authenticate( - authStrings: const AndroidAuthMessages().args, + authMessages: [const AndroidAuthMessages()], localizedReason: 'Insecure', options: const AuthenticationOptions( sensitiveTransaction: false, @@ -80,7 +80,7 @@ void main() { group('With biometrics only', () { test('authenticate with no args on Android.', () async { await localAuthentication.authenticate( - authStrings: const AndroidAuthMessages().args, + authMessages: [const AndroidAuthMessages()], localizedReason: 'Needs secure', ); expect( @@ -100,7 +100,7 @@ void main() { test('authenticate with no sensitive transaction.', () async { await localAuthentication.authenticate( - authStrings: const AndroidAuthMessages().args, + authMessages: [const AndroidAuthMessages()], localizedReason: 'Insecure', options: const AuthenticationOptions( sensitiveTransaction: false, diff --git a/packages/local_auth/local_auth_platform_interface/lib/types/auth_messages.dart b/packages/local_auth/local_auth_platform_interface/lib/types/auth_messages.dart index a08cf10325e5..978d2d066421 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/types/auth_messages.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/types/auth_messages.dart @@ -4,7 +4,6 @@ /// Abstract class for storing platform specific strings. abstract class AuthMessages { - /// Constructs an instance of [AuthMessages]. const AuthMessages(); From 61bd127aea353b08cd56bb8261229f0b39227804 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Mon, 7 Feb 2022 14:40:23 +0100 Subject: [PATCH 17/36] Add equality for AndroidAuthMessages --- .../lib/types/auth_messages_android.dart | 41 ++++++++++++++++--- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/packages/local_auth/local_auth_android/lib/types/auth_messages_android.dart b/packages/local_auth/local_auth_android/lib/types/auth_messages_android.dart index db8e75da9f2b..44286a308ea8 100644 --- a/packages/local_auth/local_auth_android/lib/types/auth_messages_android.dart +++ b/packages/local_auth/local_auth_android/lib/types/auth_messages_android.dart @@ -2,12 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:flutter/foundation.dart'; import 'package:intl/intl.dart'; import 'package:local_auth_platform_interface/types/auth_messages.dart'; /// Android side authentication messages. /// /// Provides default values for all messages. +@immutable class AndroidAuthMessages extends AuthMessages { /// Constructs a new instance. const AndroidAuthMessages({ @@ -77,16 +79,43 @@ class AndroidAuthMessages extends AuthMessages { 'biometricRequired': biometricRequiredTitle ?? androidBiometricRequiredTitle, 'cancelButton': cancelButton ?? androidCancelButton, - 'deviceCredentialsRequired': deviceCredentialsRequiredTitle ?? - androidDeviceCredentialsRequiredTitle, - 'deviceCredentialsSetupDescription': deviceCredentialsSetupDescription ?? - androidDeviceCredentialsSetupDescription, + 'deviceCredentialsRequired': deviceCredentialsRequiredTitle ?? androidDeviceCredentialsRequiredTitle, + 'deviceCredentialsSetupDescription': + deviceCredentialsSetupDescription ?? androidDeviceCredentialsSetupDescription, 'goToSetting': goToSettingsButton ?? goToSettings, - 'goToSettingDescription': - goToSettingsDescription ?? androidGoToSettingsDescription, + 'goToSettingDescription': goToSettingsDescription ?? androidGoToSettingsDescription, 'signInTitle': signInTitle ?? androidSignInTitle, }; } + + @override + bool operator ==(Object other) => + identical(this, other) || + other is AndroidAuthMessages && + runtimeType == other.runtimeType && + biometricHint == other.biometricHint && + biometricNotRecognized == other.biometricNotRecognized && + biometricRequiredTitle == other.biometricRequiredTitle && + biometricSuccess == other.biometricSuccess && + cancelButton == other.cancelButton && + deviceCredentialsRequiredTitle == other.deviceCredentialsRequiredTitle && + deviceCredentialsSetupDescription == other.deviceCredentialsSetupDescription && + goToSettingsButton == other.goToSettingsButton && + goToSettingsDescription == other.goToSettingsDescription && + signInTitle == other.signInTitle; + + @override + int get hashCode => + biometricHint.hashCode ^ + biometricNotRecognized.hashCode ^ + biometricRequiredTitle.hashCode ^ + biometricSuccess.hashCode ^ + cancelButton.hashCode ^ + deviceCredentialsRequiredTitle.hashCode ^ + deviceCredentialsSetupDescription.hashCode ^ + goToSettingsButton.hashCode ^ + goToSettingsDescription.hashCode ^ + signInTitle.hashCode; } // Strings for local_authentication plugin. Currently supports English. From 083689fd2ad44b1c73ecfd7031f36bf9502a8974 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Mon, 7 Feb 2022 14:43:17 +0100 Subject: [PATCH 18/36] Add equality for AuthenticationOptions --- .../lib/types/auth_messages.dart | 1 - .../lib/types/auth_options.dart | 20 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/local_auth/local_auth_platform_interface/lib/types/auth_messages.dart b/packages/local_auth/local_auth_platform_interface/lib/types/auth_messages.dart index a08cf10325e5..978d2d066421 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/types/auth_messages.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/types/auth_messages.dart @@ -4,7 +4,6 @@ /// Abstract class for storing platform specific strings. abstract class AuthMessages { - /// Constructs an instance of [AuthMessages]. const AuthMessages(); diff --git a/packages/local_auth/local_auth_platform_interface/lib/types/auth_options.dart b/packages/local_auth/local_auth_platform_interface/lib/types/auth_options.dart index f858126dcb63..c4b646c0b97a 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/types/auth_options.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/types/auth_options.dart @@ -2,7 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:flutter/foundation.dart'; + /// Options wrapper for [LocalAuthPlatform.authenticate] parameters. +@immutable class AuthenticationOptions { /// Constructs a new instance. const AuthenticationOptions({ @@ -37,4 +40,21 @@ class AuthenticationOptions { /// Prevent authentications from using non-biometric local authentication /// such as pin, passcode, or pattern. final bool biometricOnly; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is AuthenticationOptions && + runtimeType == other.runtimeType && + useErrorDialogs == other.useErrorDialogs && + stickyAuth == other.stickyAuth && + sensitiveTransaction == other.sensitiveTransaction && + biometricOnly == other.biometricOnly; + + @override + int get hashCode => + useErrorDialogs.hashCode ^ + stickyAuth.hashCode ^ + sensitiveTransaction.hashCode ^ + biometricOnly.hashCode; } From ae3480095e9b0a5cf682596d4ce3f7866f9c317f Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Mon, 7 Feb 2022 14:44:59 +0100 Subject: [PATCH 19/36] Format --- .../lib/types/auth_messages_android.dart | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/local_auth/local_auth_android/lib/types/auth_messages_android.dart b/packages/local_auth/local_auth_android/lib/types/auth_messages_android.dart index 44286a308ea8..efc15d248942 100644 --- a/packages/local_auth/local_auth_android/lib/types/auth_messages_android.dart +++ b/packages/local_auth/local_auth_android/lib/types/auth_messages_android.dart @@ -79,11 +79,13 @@ class AndroidAuthMessages extends AuthMessages { 'biometricRequired': biometricRequiredTitle ?? androidBiometricRequiredTitle, 'cancelButton': cancelButton ?? androidCancelButton, - 'deviceCredentialsRequired': deviceCredentialsRequiredTitle ?? androidDeviceCredentialsRequiredTitle, - 'deviceCredentialsSetupDescription': - deviceCredentialsSetupDescription ?? androidDeviceCredentialsSetupDescription, + 'deviceCredentialsRequired': deviceCredentialsRequiredTitle ?? + androidDeviceCredentialsRequiredTitle, + 'deviceCredentialsSetupDescription': deviceCredentialsSetupDescription ?? + androidDeviceCredentialsSetupDescription, 'goToSetting': goToSettingsButton ?? goToSettings, - 'goToSettingDescription': goToSettingsDescription ?? androidGoToSettingsDescription, + 'goToSettingDescription': + goToSettingsDescription ?? androidGoToSettingsDescription, 'signInTitle': signInTitle ?? androidSignInTitle, }; } @@ -98,8 +100,10 @@ class AndroidAuthMessages extends AuthMessages { biometricRequiredTitle == other.biometricRequiredTitle && biometricSuccess == other.biometricSuccess && cancelButton == other.cancelButton && - deviceCredentialsRequiredTitle == other.deviceCredentialsRequiredTitle && - deviceCredentialsSetupDescription == other.deviceCredentialsSetupDescription && + deviceCredentialsRequiredTitle == + other.deviceCredentialsRequiredTitle && + deviceCredentialsSetupDescription == + other.deviceCredentialsSetupDescription && goToSettingsButton == other.goToSettingsButton && goToSettingsDescription == other.goToSettingsDescription && signInTitle == other.signInTitle; From 3b1915b31b0452b6b3b8a19b13dff88a794e6705 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Mon, 7 Feb 2022 16:01:14 +0100 Subject: [PATCH 20/36] Add current implementation for canCheckBiometrics --- .../local_auth_android/lib/local_auth_android.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/local_auth/local_auth_android/lib/local_auth_android.dart b/packages/local_auth/local_auth_android/lib/local_auth_android.dart index 57ac9b04180f..fb70fff8c6ad 100644 --- a/packages/local_auth/local_auth_android/lib/local_auth_android.dart +++ b/packages/local_auth/local_auth_android/lib/local_auth_android.dart @@ -43,6 +43,11 @@ class LocalAuthAndroid extends LocalAuthPlatform { return (await _channel.invokeMethod('authenticate', args)) ?? false; } + @override + Future canCheckBiometrics() async { + return (await getAvailableBiometrics()).isNotEmpty; + } + @override Future> getAvailableBiometrics() async { final List result = (await _channel.invokeListMethod( From 92ec8bc287bd9c2744dbd8101a98f26b251fa5db Mon Sep 17 00:00:00 2001 From: Bodhi Mulders Date: Fri, 11 Feb 2022 09:36:25 +0100 Subject: [PATCH 21/36] Process PR feedback --- .../lib/default_method_channel_platform.dart | 6 +++--- .../lib/local_auth_platform_interface.dart | 6 ++++-- .../lib/types/auth_messages.dart | 2 +- .../lib/types/biometric_type.dart | 2 +- .../test/default_method_channel_platform_test.dart | 2 +- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart b/packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart index b239f2368b83..c68a3bfb8371 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/default_method_channel_platform.dart @@ -39,7 +39,7 @@ class DefaultLocalAuthPlatform extends LocalAuthPlatform { } @override - Future> getAvailableBiometrics() async { + Future> getEnrolledBiometrics() async { final List result = (await _channel.invokeListMethod( 'getAvailableBiometrics', )) ?? @@ -64,8 +64,8 @@ class DefaultLocalAuthPlatform extends LocalAuthPlatform { } @override - Future canCheckBiometrics() async { - return (await getAvailableBiometrics()).isNotEmpty; + Future deviceSupportsBiometrics() async { + return (await getEnrolledBiometrics()).isNotEmpty; } @override diff --git a/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart b/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart index 824725837794..b909ee90d12b 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart @@ -63,7 +63,9 @@ abstract class LocalAuthPlatform extends PlatformInterface { } /// Returns true if the device is capable of checking biometrics. - Future canCheckBiometrics() async { + /// + /// This will return true even if there are no biometrics currently enrolled. + Future deviceSupportsBiometrics() async { throw UnimplementedError('canCheckBiometrics() has not been implemented.'); } @@ -75,7 +77,7 @@ abstract class LocalAuthPlatform extends PlatformInterface { /// - BiometricType.iris (not yet implemented) /// - BiometricType.strong /// - BiometricType.weak - Future> getAvailableBiometrics() async { + Future> getEnrolledBiometrics() async { throw UnimplementedError( 'getAvailableBiometrics() has not been implemented.'); } diff --git a/packages/local_auth/local_auth_platform_interface/lib/types/auth_messages.dart b/packages/local_auth/local_auth_platform_interface/lib/types/auth_messages.dart index 978d2d066421..d51980d575cf 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/types/auth_messages.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/types/auth_messages.dart @@ -7,6 +7,6 @@ abstract class AuthMessages { /// Constructs an instance of [AuthMessages]. const AuthMessages(); - /// Returns all platform specific messages as a map. + /// Returns all platform-specific messages as a map. Map get args; } diff --git a/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart b/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart index c4efd0deb3cb..9c335e25624a 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/types/biometric_type.dart @@ -21,7 +21,7 @@ enum BiometricType { strong, /// Any biometric (e.g. fingerprint, iris, or face) on the device that the - /// platform API considers to be strong. For example, on Android this + /// platform API considers to be weak. For example, on Android this /// corresponds to Class 2. weak, } diff --git a/packages/local_auth/local_auth_platform_interface/test/default_method_channel_platform_test.dart b/packages/local_auth/local_auth_platform_interface/test/default_method_channel_platform_test.dart index d3a7bda7effc..3853fd84c6fc 100644 --- a/packages/local_auth/local_auth_platform_interface/test/default_method_channel_platform_test.dart +++ b/packages/local_auth/local_auth_platform_interface/test/default_method_channel_platform_test.dart @@ -36,7 +36,7 @@ void main() { }); localAuthentication = DefaultLocalAuthPlatform(); log.clear(); - await localAuthentication.getAvailableBiometrics(); + await localAuthentication.getEnrolledBiometrics(); expect( log, [ From 2652857f1f75f678c1fdee0ad5c7f5eb813105a3 Mon Sep 17 00:00:00 2001 From: Bodhi Mulders Date: Fri, 11 Feb 2022 10:11:39 +0100 Subject: [PATCH 22/36] Adjust to platform interface changes --- .../example/integration_test/local_auth_test.dart | 2 +- .../local_auth/local_auth_android/example/lib/main.dart | 8 ++++---- .../local_auth_android/lib/local_auth_android.dart | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/local_auth/local_auth_android/example/integration_test/local_auth_test.dart b/packages/local_auth/local_auth_android/example/integration_test/local_auth_test.dart index 8e4f4748f05f..1dfc0ae7a6d6 100644 --- a/packages/local_auth/local_auth_android/example/integration_test/local_auth_test.dart +++ b/packages/local_auth/local_auth_android/example/integration_test/local_auth_test.dart @@ -12,7 +12,7 @@ void main() { testWidgets('canCheckBiometrics', (WidgetTester tester) async { expect( - LocalAuthAndroid().getAvailableBiometrics(), + LocalAuthAndroid().getEnrolledBiometrics(), completion(isList), ); }); diff --git a/packages/local_auth/local_auth_android/example/lib/main.dart b/packages/local_auth/local_auth_android/example/lib/main.dart index a5de6c09c763..37199d03e1f8 100644 --- a/packages/local_auth/local_auth_android/example/lib/main.dart +++ b/packages/local_auth/local_auth_android/example/lib/main.dart @@ -40,7 +40,7 @@ class _MyAppState extends State { Future _checkBiometrics() async { late bool canCheckBiometrics; try { - canCheckBiometrics = (await auth.getAvailableBiometrics()).isNotEmpty; + canCheckBiometrics = (await auth.getEnrolledBiometrics()).isNotEmpty; } on PlatformException catch (e) { canCheckBiometrics = false; print(e); @@ -54,10 +54,10 @@ class _MyAppState extends State { }); } - Future _getAvailableBiometrics() async { + Future _getEnrolledBiometrics() async { late List availableBiometrics; try { - availableBiometrics = await auth.getAvailableBiometrics(); + availableBiometrics = await auth.getEnrolledBiometrics(); } on PlatformException catch (e) { availableBiometrics = []; print(e); @@ -178,7 +178,7 @@ class _MyAppState extends State { Text('Available biometrics: $_availableBiometrics\n'), ElevatedButton( child: const Text('Get available biometrics'), - onPressed: _getAvailableBiometrics, + onPressed: _getEnrolledBiometrics, ), const Divider(height: 100), Text('Current State: $_authorized\n'), diff --git a/packages/local_auth/local_auth_android/lib/local_auth_android.dart b/packages/local_auth/local_auth_android/lib/local_auth_android.dart index fb70fff8c6ad..9365bfd3455e 100644 --- a/packages/local_auth/local_auth_android/lib/local_auth_android.dart +++ b/packages/local_auth/local_auth_android/lib/local_auth_android.dart @@ -44,12 +44,12 @@ class LocalAuthAndroid extends LocalAuthPlatform { } @override - Future canCheckBiometrics() async { - return (await getAvailableBiometrics()).isNotEmpty; + Future deviceSupportsBiometrics() async { + return (await getEnrolledBiometrics()).isNotEmpty; } @override - Future> getAvailableBiometrics() async { + Future> getEnrolledBiometrics() async { final List result = (await _channel.invokeListMethod( 'getAvailableBiometrics', )) ?? From 6d205e5e99239d43ddcfbec7fefb9934bd839d3f Mon Sep 17 00:00:00 2001 From: Bodhi Mulders Date: Fri, 11 Feb 2022 10:24:21 +0100 Subject: [PATCH 23/36] Adjust to platform interface changes --- .../io/flutter/plugins/localauth/LocalAuthPlugin.java | 10 +++++----- .../local_auth_android/lib/local_auth_android.dart | 2 +- 2 files changed, 6 insertions(+), 6 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 49a6b788fe46..ae590cd5938a 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 @@ -101,8 +101,8 @@ public void onMethodCall(MethodCall call, @NonNull final Result result) { case "authenticate": authenticate(call, result); break; - case "getAvailableBiometrics": - getAvailableBiometrics(result); + case "getEnrolledBiometrics": + getEnrolledBiometrics(result); break; case "isDeviceSupported": isDeviceSupported(result); @@ -251,20 +251,20 @@ private void stopAuthentication(Result result) { /* * Returns biometric types available on device */ - private void getAvailableBiometrics(final Result result) { + private void getEnrolledBiometrics(final Result result) { try { if (activity == null || activity.isFinishing()) { result.error("no_activity", "local_auth plugin requires a foreground activity", null); return; } - ArrayList biometrics = getAvailableBiometrics(); + ArrayList biometrics = getEnrolledBiometrics(); result.success(biometrics); } catch (Exception e) { result.error("no_biometrics_available", e.getMessage(), null); } } - private ArrayList getAvailableBiometrics() { + private ArrayList getEnrolledBiometrics() { ArrayList biometrics = new ArrayList<>(); if (activity == null || activity.isFinishing()) { return biometrics; diff --git a/packages/local_auth/local_auth_android/lib/local_auth_android.dart b/packages/local_auth/local_auth_android/lib/local_auth_android.dart index 9365bfd3455e..e91be66430aa 100644 --- a/packages/local_auth/local_auth_android/lib/local_auth_android.dart +++ b/packages/local_auth/local_auth_android/lib/local_auth_android.dart @@ -51,7 +51,7 @@ class LocalAuthAndroid extends LocalAuthPlatform { @override Future> getEnrolledBiometrics() async { final List result = (await _channel.invokeListMethod( - 'getAvailableBiometrics', + 'getEnrolledBiometrics', )) ?? []; final List biometrics = []; From 116c79578871cc937e2efef71d93433c6251ed7b Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Mon, 14 Feb 2022 17:26:57 +0100 Subject: [PATCH 24/36] Update platform interface dependency --- packages/local_auth/local_auth_android/pubspec.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/local_auth/local_auth_android/pubspec.yaml b/packages/local_auth/local_auth_android/pubspec.yaml index 6b6157bfa68b..07b7158057d8 100644 --- a/packages/local_auth/local_auth_android/pubspec.yaml +++ b/packages/local_auth/local_auth_android/pubspec.yaml @@ -24,8 +24,7 @@ dependencies: sdk: flutter flutter_plugin_android_lifecycle: ^2.0.1 intl: ^0.17.0 - local_auth_platform_interface: - path: ../local_auth_platform_interface + local_auth_platform_interface: ^1.0.0 dev_dependencies: flutter_test: From 7c97e488f6a83bd4f23c1f0037ccf46922117118 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Mon, 14 Feb 2022 17:37:20 +0100 Subject: [PATCH 25/36] Fixed order of keys in pubspec --- packages/local_auth/local_auth_android/pubspec.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/local_auth/local_auth_android/pubspec.yaml b/packages/local_auth/local_auth_android/pubspec.yaml index 07b7158057d8..e476d74c8e6e 100644 --- a/packages/local_auth/local_auth_android/pubspec.yaml +++ b/packages/local_auth/local_auth_android/pubspec.yaml @@ -6,6 +6,10 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes version: 1.0.0 +environment: + sdk: ">=2.14.0 <3.0.0" + flutter: ">=2.8.0" + flutter: plugin: implements: local_auth @@ -15,10 +19,6 @@ flutter: pluginClass: LocalAuthPlugin dartPluginClass: LocalAuthAndroid -environment: - sdk: ">=2.14.0 <3.0.0" - flutter: ">=2.8.0" - dependencies: flutter: sdk: flutter From 222253f41e4a80fdf38a650438d5194db18c8d46 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Thu, 10 Mar 2022 15:19:44 +0100 Subject: [PATCH 26/36] Implement PR feedback (from iOS PR) --- packages/local_auth/local_auth/pubspec.yaml | 2 - .../plugins/localauth/LocalAuthPlugin.java | 10 +- .../local_auth_android/example/lib/main.dart | 16 +-- .../local_auth_android/example/pubspec.yaml | 4 +- .../lib/local_auth_android.dart | 2 +- .../lib/types/auth_messages_android.dart | 102 ++++++++---------- .../local_auth_android/pubspec.yaml | 3 +- .../test/local_auth_test.dart | 61 ++++++++++- 8 files changed, 123 insertions(+), 77 deletions(-) diff --git a/packages/local_auth/local_auth/pubspec.yaml b/packages/local_auth/local_auth/pubspec.yaml index f49c30975e7d..5a533ded7dc2 100644 --- a/packages/local_auth/local_auth/pubspec.yaml +++ b/packages/local_auth/local_auth/pubspec.yaml @@ -17,8 +17,6 @@ flutter: plugin: platforms: android: - package: io.flutter.plugins.localauth - pluginClass: LocalAuthPlugin default_package: local_auth_android ios: pluginClass: FLTLocalAuthPlugin 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 ae590cd5938a..49a6b788fe46 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 @@ -101,8 +101,8 @@ public void onMethodCall(MethodCall call, @NonNull final Result result) { case "authenticate": authenticate(call, result); break; - case "getEnrolledBiometrics": - getEnrolledBiometrics(result); + case "getAvailableBiometrics": + getAvailableBiometrics(result); break; case "isDeviceSupported": isDeviceSupported(result); @@ -251,20 +251,20 @@ private void stopAuthentication(Result result) { /* * Returns biometric types available on device */ - private void getEnrolledBiometrics(final Result result) { + private void getAvailableBiometrics(final Result result) { try { if (activity == null || activity.isFinishing()) { result.error("no_activity", "local_auth plugin requires a foreground activity", null); return; } - ArrayList biometrics = getEnrolledBiometrics(); + ArrayList biometrics = getAvailableBiometrics(); result.success(biometrics); } catch (Exception e) { result.error("no_biometrics_available", e.getMessage(), null); } } - private ArrayList getEnrolledBiometrics() { + private ArrayList getAvailableBiometrics() { ArrayList biometrics = new ArrayList<>(); if (activity == null || activity.isFinishing()) { return biometrics; diff --git a/packages/local_auth/local_auth_android/example/lib/main.dart b/packages/local_auth/local_auth_android/example/lib/main.dart index 37199d03e1f8..4c045214734d 100644 --- a/packages/local_auth/local_auth_android/example/lib/main.dart +++ b/packages/local_auth/local_auth_android/example/lib/main.dart @@ -9,6 +9,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:local_auth_android/local_auth_android.dart'; +import 'package:local_auth_platform_interface/local_auth_platform_interface.dart'; void main() { runApp(MyApp()); @@ -20,7 +21,6 @@ class MyApp extends StatefulWidget { } class _MyAppState extends State { - final LocalAuthAndroid auth = LocalAuthAndroid(); _SupportState _supportState = _SupportState.unknown; bool? _canCheckBiometrics; List? _availableBiometrics; @@ -30,7 +30,7 @@ class _MyAppState extends State { @override void initState() { super.initState(); - auth.isDeviceSupported().then( + LocalAuthPlatform.instance.isDeviceSupported().then( (bool isSupported) => setState(() => _supportState = isSupported ? _SupportState.supported : _SupportState.unsupported), @@ -40,7 +40,8 @@ class _MyAppState extends State { Future _checkBiometrics() async { late bool canCheckBiometrics; try { - canCheckBiometrics = (await auth.getEnrolledBiometrics()).isNotEmpty; + canCheckBiometrics = + (await LocalAuthPlatform.instance.getEnrolledBiometrics()).isNotEmpty; } on PlatformException catch (e) { canCheckBiometrics = false; print(e); @@ -57,7 +58,8 @@ class _MyAppState extends State { Future _getEnrolledBiometrics() async { late List availableBiometrics; try { - availableBiometrics = await auth.getEnrolledBiometrics(); + availableBiometrics = + await LocalAuthPlatform.instance.getEnrolledBiometrics(); } on PlatformException catch (e) { availableBiometrics = []; print(e); @@ -78,7 +80,7 @@ class _MyAppState extends State { _isAuthenticating = true; _authorized = 'Authenticating'; }); - authenticated = await auth.authenticate( + authenticated = await LocalAuthPlatform.instance.authenticate( localizedReason: 'Let OS determine authentication method', authMessages: [const AndroidAuthMessages()], options: const AuthenticationOptions( @@ -112,7 +114,7 @@ class _MyAppState extends State { _isAuthenticating = true; _authorized = 'Authenticating'; }); - authenticated = await auth.authenticate( + authenticated = await LocalAuthPlatform.instance.authenticate( localizedReason: 'Scan your fingerprint (or face or whatever) to authenticate', authMessages: [const AndroidAuthMessages()], @@ -145,7 +147,7 @@ class _MyAppState extends State { } Future _cancelAuthentication() async { - await auth.stopAuthentication(); + await LocalAuthPlatform.instance.stopAuthentication(); setState(() => _isAuthenticating = false); } diff --git a/packages/local_auth/local_auth_android/example/pubspec.yaml b/packages/local_auth/local_auth_android/example/pubspec.yaml index efd7c9c79f7f..92e07cd1a5a8 100644 --- a/packages/local_auth/local_auth_android/example/pubspec.yaml +++ b/packages/local_auth/local_auth_android/example/pubspec.yaml @@ -4,7 +4,7 @@ publish_to: none environment: sdk: ">=2.14.0 <3.0.0" - flutter: ">=2.5.0" + flutter: ">=2.8.0" dependencies: flutter: @@ -16,13 +16,13 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ + local_auth_platform_interface: ^1.0.0 dev_dependencies: flutter_driver: sdk: flutter integration_test: sdk: flutter - pedantic: ^1.10.0 flutter: uses-material-design: true diff --git a/packages/local_auth/local_auth_android/lib/local_auth_android.dart b/packages/local_auth/local_auth_android/lib/local_auth_android.dart index e91be66430aa..9365bfd3455e 100644 --- a/packages/local_auth/local_auth_android/lib/local_auth_android.dart +++ b/packages/local_auth/local_auth_android/lib/local_auth_android.dart @@ -51,7 +51,7 @@ class LocalAuthAndroid extends LocalAuthPlatform { @override Future> getEnrolledBiometrics() async { final List result = (await _channel.invokeListMethod( - 'getEnrolledBiometrics', + 'getAvailableBiometrics', )) ?? []; final List biometrics = []; diff --git a/packages/local_auth/local_auth_android/lib/types/auth_messages_android.dart b/packages/local_auth/local_auth_android/lib/types/auth_messages_android.dart index efc15d248942..ea61a4b06d4e 100644 --- a/packages/local_auth/local_auth_android/lib/types/auth_messages_android.dart +++ b/packages/local_auth/local_auth_android/lib/types/auth_messages_android.dart @@ -25,48 +25,49 @@ class AndroidAuthMessages extends AuthMessages { this.signInTitle, }); - /// Hint message advising the user how to authenticate with biometrics. It is - /// used on Android. Maximum 60 characters. + /// Hint message advising the user how to authenticate with biometrics. + /// Maximum 60 characters. final String? biometricHint; - /// Message to let the user know that authentication was failed. It is used - /// on Android. Maximum 60 characters.' + /// Message to let the user know that authentication was failed. + /// Maximum 60 characters. final String? biometricNotRecognized; /// Message shown as a title in a dialog which indicates the user - /// has not set up biometric authentication on their device. It is used on - /// Android. Maximum 60 characters. + /// has not set up biometric authentication on their device. + /// Maximum 60 characters. final String? biometricRequiredTitle; - /// Message to let the user know that authentication was successful. It - /// is used on Android. Maximum 60 characters + /// Message to let the user know that authentication was successful. + /// Maximum 60 characters final String? biometricSuccess; /// Message shown on a button that the user can click to leave the - /// current dialog. It is used on Android. Maximum 30 characters. + /// current dialog. + /// Maximum 30 characters. final String? cancelButton; /// Message shown as a title in a dialog which indicates the user - /// has not set up credentials authentication on their device. It is used on Android. + /// has not set up credentials authentication on their device. /// Maximum 60 characters. final String? deviceCredentialsRequiredTitle; /// Message advising the user to go to the settings and configure - /// device credentials on their device. It shows in a dialog on Android. + /// device credentials on their device. final String? deviceCredentialsSetupDescription; /// Message shown on a button that the user can click to go to settings pages - /// from the current dialog. It is used on both Android and iOS sides. + /// from the current dialog. /// Maximum 30 characters. final String? goToSettingsButton; /// Message advising the user to go to the settings and configure - /// biometric on their device. It shows in a dialog on Android. + /// biometric on their device. final String? goToSettingsDescription; /// Message shown as a title in a dialog which indicates the user - /// that they need to scan biometric to continue. It is used on - /// Android. Maximum 60 characters. + /// that they need to scan biometric to continue. + /// Maximum 60 characters. final String? signInTitle; @override @@ -122,78 +123,69 @@ class AndroidAuthMessages extends AuthMessages { signInTitle.hashCode; } -// Strings for local_authentication plugin. Currently supports English. +// Default strings for AndroidAuthMessages. Currently supports English. // Intl.message must be string literals. /// Message shown on a button that the user can click to go to settings pages -/// from the current dialog. Maximum 30 characters. +/// from the current dialog. String get goToSettings => Intl.message('Go to settings', desc: 'Message shown on a button that the user can click to go to ' - 'settings pages from the current dialog. It is used on both Android ' - 'and iOS sides. Maximum 30 characters.'); + 'settings pages from the current dialog. Maximum 30 characters.'); -/// Hint message advising the user how to authenticate with biometrics. It is -/// used on Android. Maximum 60 characters. +/// Hint message advising the user how to authenticate with biometrics. String get androidBiometricHint => Intl.message('Verify identity', - desc: - 'Hint message advising the user how to authenticate with biometrics. It is ' - 'used on Android. Maximum 60 characters.'); + desc: 'Hint message advising the user how to authenticate with biometrics. ' + 'Maximum 60 characters.'); -/// Message to let the user know that authentication was failed. It is used -/// on Android. Maximum 60 characters.' +/// Message to let the user know that authentication was failed. String get androidBiometricNotRecognized => Intl.message('Not recognized. Try again.', - desc: 'Message to let the user know that authentication was failed. It ' - 'is used on Android. Maximum 60 characters.'); + desc: 'Message to let the user know that authentication was failed. ' + 'Maximum 60 characters.'); /// Message to let the user know that authentication was successful. It -/// is used on Android. Maximum 60 characters String get androidBiometricSuccess => Intl.message('Success', - desc: 'Message to let the user know that authentication was successful. It ' - 'is used on Android. Maximum 60 characters.'); + desc: 'Message to let the user know that authentication was successful. ' + 'Maximum 60 characters.'); /// Message shown on a button that the user can click to leave the -/// current dialog. It is used on Android. Maximum 30 characters. +/// current dialog. String get androidCancelButton => Intl.message('Cancel', desc: 'Message shown on a button that the user can click to leave the ' - 'current dialog. It is used on Android. Maximum 30 characters.'); + 'current dialog. Maximum 30 characters.'); /// Message shown as a title in a dialog which indicates the user -/// that they need to scan biometric to continue. It is used on -/// Android. Maximum 60 characters. +/// that they need to scan biometric to continue. String get androidSignInTitle => Intl.message('Authentication required', desc: 'Message shown as a title in a dialog which indicates the user ' - 'that they need to scan biometric to continue. It is used on ' - 'Android. Maximum 60 characters.'); + 'that they need to scan biometric to continue. Maximum 60 characters.'); /// Message shown as a title in a dialog which indicates the user -/// has not set up biometric authentication on their device. It is used on -/// Android. Maximum 60 characters. +/// has not set up biometric authentication on their device. String get androidBiometricRequiredTitle => Intl.message('Biometric required', desc: 'Message shown as a title in a dialog which indicates the user ' - 'has not set up biometric authentication on their device. It is used on Android.' - ' Maximum 60 characters.'); + 'has not set up biometric authentication on their device. ' + 'Maximum 60 characters.'); /// Message shown as a title in a dialog which indicates the user -/// has not set up credentials authentication on their device. It is used on Android. -/// Maximum 60 characters. -String get androidDeviceCredentialsRequiredTitle => Intl.message( - 'Device credentials required', - desc: 'Message shown as a title in a dialog which indicates the user ' - 'has not set up credentials authentication on their device. It is used on Android.' - ' Maximum 60 characters.'); +/// has not set up credentials authentication on their device. +String get androidDeviceCredentialsRequiredTitle => + Intl.message('Device credentials required', + desc: 'Message shown as a title in a dialog which indicates the user ' + 'has not set up credentials authentication on their device. ' + 'Maximum 60 characters.'); /// Message advising the user to go to the settings and configure -/// device credentials on their device. It shows in a dialog on Android. -String get androidDeviceCredentialsSetupDescription => Intl.message( - 'Device credentials required', - desc: 'Message advising the user to go to the settings and configure ' - 'device credentials on their device. It shows in a dialog on Android.'); +/// device credentials on their device. +String get androidDeviceCredentialsSetupDescription => + Intl.message('Device credentials required', + desc: 'Message advising the user to go to the settings and configure ' + 'device credentials on their device.'); /// Message advising the user to go to the settings and configure -/// biometric on their device. It shows in a dialog on Android. +/// biometric on their device. String get androidGoToSettingsDescription => Intl.message( 'Biometric authentication is not set up on your device. Go to ' '\'Settings > Security\' to add biometric authentication.', desc: 'Message advising the user to go to the settings and configure ' - 'biometric on their device. It shows in a dialog on Android.'); + 'biometric on their device.'); diff --git a/packages/local_auth/local_auth_android/pubspec.yaml b/packages/local_auth/local_auth_android/pubspec.yaml index e476d74c8e6e..2988e9fa65ce 100644 --- a/packages/local_auth/local_auth_android/pubspec.yaml +++ b/packages/local_auth/local_auth_android/pubspec.yaml @@ -28,5 +28,4 @@ dependencies: dev_dependencies: flutter_test: - sdk: flutter - mockito: ^5.0.0 \ No newline at end of file + sdk: flutter \ No newline at end of file diff --git a/packages/local_auth/local_auth_android/test/local_auth_test.dart b/packages/local_auth/local_auth_android/test/local_auth_test.dart index c4a462507a69..31f5e5796445 100644 --- a/packages/local_auth/local_auth_android/test/local_auth_test.dart +++ b/packages/local_auth/local_auth_android/test/local_auth_test.dart @@ -23,14 +23,69 @@ void main() { setUp(() { channel.setMockMethodCallHandler((MethodCall methodCall) { log.add(methodCall); - return Future.value(true); + switch (methodCall.method) { + case 'getAvailableBiometrics': + return Future>.value( + ['face', 'fingerprint', 'iris', 'undefined']); + default: + return Future.value(true); + } }); localAuthentication = LocalAuthAndroid(); log.clear(); }); + test('deviceSupportsBiometrics calls getEnrolledBiometrics', () async { + final bool result = await localAuthentication.deviceSupportsBiometrics(); + + expect( + log, + [ + isMethodCall('getAvailableBiometrics', arguments: null), + ], + ); + expect(result, true); + }); + + test('getEnrolledBiometrics calls platform', () async { + final List result = + await localAuthentication.getEnrolledBiometrics(); + + expect( + log, + [ + isMethodCall('getAvailableBiometrics', arguments: null), + ], + ); + expect(result, [ + BiometricType.face, + BiometricType.fingerprint, + BiometricType.iris + ]); + }); + + test('isDeviceSupported calls platform', () async { + await localAuthentication.isDeviceSupported(); + expect( + log, + [ + isMethodCall('isDeviceSupported', arguments: null), + ], + ); + }); + + test('stopAuthentication calls platform', () async { + await localAuthentication.stopAuthentication(); + expect( + log, + [ + isMethodCall('stopAuthentication', arguments: null), + ], + ); + }); + group('With device auth fail over', () { - test('authenticate with no args on Android.', () async { + test('authenticate with no args.', () async { await localAuthentication.authenticate( authMessages: [const AndroidAuthMessages()], localizedReason: 'Needs secure', @@ -78,7 +133,7 @@ void main() { }); group('With biometrics only', () { - test('authenticate with no args on Android.', () async { + test('authenticate with no args.', () async { await localAuthentication.authenticate( authMessages: [const AndroidAuthMessages()], localizedReason: 'Needs secure', From 42f41f46c28a8763ef3cdd7a87d4fedb31c43dd0 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Mon, 28 Mar 2022 09:33:48 +0200 Subject: [PATCH 27/36] Partially process PR feedback --- packages/local_auth/local_auth_android/example/pubspec.yaml | 2 +- .../local_auth/local_auth_android/lib/local_auth_android.dart | 2 ++ packages/local_auth/local_auth_android/pubspec.yaml | 2 -- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/local_auth/local_auth_android/example/pubspec.yaml b/packages/local_auth/local_auth_android/example/pubspec.yaml index 92e07cd1a5a8..c07a81d2be3b 100644 --- a/packages/local_auth/local_auth_android/example/pubspec.yaml +++ b/packages/local_auth/local_auth_android/example/pubspec.yaml @@ -11,7 +11,7 @@ dependencies: sdk: flutter local_auth_android: # When depending on this package from a real application you should use: - # local_auth: ^x.y.z + # local_auth_android: ^x.y.z # See https://dart.dev/tools/pub/dependencies#version-constraints # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. diff --git a/packages/local_auth/local_auth_android/lib/local_auth_android.dart b/packages/local_auth/local_auth_android/lib/local_auth_android.dart index 9365bfd3455e..69aae788b4b4 100644 --- a/packages/local_auth/local_auth_android/lib/local_auth_android.dart +++ b/packages/local_auth/local_auth_android/lib/local_auth_android.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'package:flutter/services.dart'; +import 'package:local_auth_android/types/auth_messages_android.dart'; import 'package:local_auth_platform_interface/local_auth_platform_interface.dart'; import 'package:local_auth_platform_interface/types/auth_messages.dart'; import 'package:local_auth_platform_interface/types/auth_options.dart'; @@ -37,6 +38,7 @@ class LocalAuthAndroid extends LocalAuthPlatform { 'sensitiveTransaction': options.sensitiveTransaction, 'biometricOnly': options.biometricOnly, }; + args.addAll(const AndroidAuthMessages().args); for (final AuthMessages messages in authMessages) { args.addAll(messages.args); } diff --git a/packages/local_auth/local_auth_android/pubspec.yaml b/packages/local_auth/local_auth_android/pubspec.yaml index 2988e9fa65ce..ec2991db6a90 100644 --- a/packages/local_auth/local_auth_android/pubspec.yaml +++ b/packages/local_auth/local_auth_android/pubspec.yaml @@ -2,8 +2,6 @@ name: local_auth_android description: Android implementation of the local_auth plugin. repository: https://github.com/flutter/plugins/tree/master/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 -# NOTE: We strongly prefer non-breaking changes, even at the expense of a -# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes version: 1.0.0 environment: From 7d936863e74eda03158e20d889ec08699343272a Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Mon, 28 Mar 2022 09:45:57 +0200 Subject: [PATCH 28/36] Only add authentication messages for the current platform --- .../local_auth/local_auth_android/lib/local_auth_android.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/local_auth/local_auth_android/lib/local_auth_android.dart b/packages/local_auth/local_auth_android/lib/local_auth_android.dart index 69aae788b4b4..a3f314e3347b 100644 --- a/packages/local_auth/local_auth_android/lib/local_auth_android.dart +++ b/packages/local_auth/local_auth_android/lib/local_auth_android.dart @@ -40,7 +40,9 @@ class LocalAuthAndroid extends LocalAuthPlatform { }; args.addAll(const AndroidAuthMessages().args); for (final AuthMessages messages in authMessages) { - args.addAll(messages.args); + if (messages is AndroidAuthMessages) { + args.addAll(messages.args); + } } return (await _channel.invokeMethod('authenticate', args)) ?? false; } From ce6bb975934ce4e6fd163a06e5c129fc0ea2d33b Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Thu, 7 Apr 2022 16:44:53 +0200 Subject: [PATCH 29/36] Update min flutter version --- packages/local_auth/local_auth/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/local_auth/local_auth/pubspec.yaml b/packages/local_auth/local_auth/pubspec.yaml index 5a533ded7dc2..78f50b5b9569 100644 --- a/packages/local_auth/local_auth/pubspec.yaml +++ b/packages/local_auth/local_auth/pubspec.yaml @@ -11,7 +11,7 @@ publish_to: none environment: sdk: ">=2.14.0 <3.0.0" - flutter: ">=2.5.0" + flutter: ">=2.8.0" flutter: plugin: From bc24cf56b4c03deb9173309ad13c49d50aad32f7 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Thu, 7 Apr 2022 17:18:05 +0200 Subject: [PATCH 30/36] Switch over app facing package to use default method channel implementation in platform interface. --- packages/local_auth/local_auth/CHANGELOG.md | 1 + .../local_auth/lib/auth_strings.dart | 5 +- .../local_auth/local_auth/lib/local_auth.dart | 99 ++--- packages/local_auth/local_auth/pubspec.yaml | 7 +- .../local_auth/test/local_auth_test.dart | 360 ++++++------------ 5 files changed, 169 insertions(+), 303 deletions(-) diff --git a/packages/local_auth/local_auth/CHANGELOG.md b/packages/local_auth/local_auth/CHANGELOG.md index a2f93cad6286..76ac27b53b3c 100644 --- a/packages/local_auth/local_auth/CHANGELOG.md +++ b/packages/local_auth/local_auth/CHANGELOG.md @@ -1,6 +1,7 @@ ## NEXT * Adds OS version support information to README. +* Switched over to default method implementation in new platform interface. ## 1.1.11 diff --git a/packages/local_auth/local_auth/lib/auth_strings.dart b/packages/local_auth/local_auth/lib/auth_strings.dart index 3e34659b8dad..e5dd738ebd53 100644 --- a/packages/local_auth/local_auth/lib/auth_strings.dart +++ b/packages/local_auth/local_auth/lib/auth_strings.dart @@ -9,11 +9,12 @@ // ignore_for_file: public_member_api_docs import 'package:intl/intl.dart'; +import 'package:local_auth_platform_interface/types/auth_messages.dart'; /// Android side authentication messages. /// /// Provides default values for all messages. -class AndroidAuthMessages { +class AndroidAuthMessages extends AuthMessages { const AndroidAuthMessages({ this.biometricHint, this.biometricNotRecognized, @@ -62,7 +63,7 @@ class AndroidAuthMessages { /// iOS side authentication messages. /// /// Provides default values for all messages. -class IOSAuthMessages { +class IOSAuthMessages extends AuthMessages { const IOSAuthMessages({ this.lockOut, this.goToSettingsButton, diff --git a/packages/local_auth/local_auth/lib/local_auth.dart b/packages/local_auth/local_auth/lib/local_auth.dart index 3e925c00e5ae..70d41b01330f 100644 --- a/packages/local_auth/local_auth/lib/local_auth.dart +++ b/packages/local_auth/local_auth/lib/local_auth.dart @@ -12,14 +12,14 @@ import 'dart:async'; import 'package:flutter/foundation.dart' show visibleForTesting; import 'package:flutter/services.dart'; +import 'package:local_auth_platform_interface/local_auth_platform_interface.dart'; +import 'package:local_auth_platform_interface/types/auth_messages.dart'; +import 'package:local_auth_platform_interface/types/auth_options.dart'; +import 'package:local_auth_platform_interface/types/biometric_type.dart'; import 'package:platform/platform.dart'; - import 'auth_strings.dart'; -import 'error_codes.dart'; - -enum BiometricType { face, fingerprint, iris } -const MethodChannel _channel = MethodChannel('plugins.flutter.io/local_auth'); +export 'package:local_auth_platform_interface/types/biometric_type.dart'; Platform _platform = const LocalPlatform(); @@ -31,7 +31,7 @@ void setMockPathProviderPlatform(Platform platform) { /// A Flutter plugin for authenticating the user identity locally. class LocalAuthentication { /// The `authenticateWithBiometrics` method has been deprecated. - /// Use `authenticate` with `biometricOnly: true` instead + /// Use `authenticate` with `biometricOnly: true` instead. @Deprecated('Use `authenticate` with `biometricOnly: true` instead') Future authenticateWithBiometrics({ required String localizedReason, @@ -41,21 +41,21 @@ class LocalAuthentication { IOSAuthMessages iOSAuthStrings = const IOSAuthMessages(), bool sensitiveTransaction = true, }) => - authenticate( + LocalAuthPlatform.instance.authenticate( localizedReason: localizedReason, - useErrorDialogs: useErrorDialogs, - stickyAuth: stickyAuth, - androidAuthStrings: androidAuthStrings, - iOSAuthStrings: iOSAuthStrings, - sensitiveTransaction: sensitiveTransaction, - biometricOnly: true, + authMessages: [iOSAuthStrings, androidAuthStrings], + options: AuthenticationOptions( + useErrorDialogs: useErrorDialogs, + stickyAuth: stickyAuth, + sensitiveTransaction: sensitiveTransaction, + biometricOnly: true, + ), ); /// Authenticates the user with biometrics available on the device while also /// allowing the user to use device authentication - pin, pattern, passcode. /// - /// Returns a [Future] holding true, if the user successfully authenticated, - /// false otherwise. + /// Returns true, if the user successfully authenticated, false otherwise. /// /// [localizedReason] is the message to show to user while prompting them /// for authentication. This is typically along the lines of: 'Please scan @@ -91,6 +91,7 @@ class LocalAuthentication { /// authentication (e.g. lack of relevant hardware). This might throw /// [PlatformException] with error code [otherOperatingSystem] on the iOS /// simulator. + @Deprecated('Use `requestAuthentication` instead.') Future authenticate({ required String localizedReason, bool useErrorDialogs = true, @@ -99,29 +100,17 @@ class LocalAuthentication { IOSAuthMessages iOSAuthStrings = const IOSAuthMessages(), bool sensitiveTransaction = true, bool biometricOnly = false, - }) async { - assert(localizedReason.isNotEmpty); - - final Map args = { - 'localizedReason': localizedReason, - 'useErrorDialogs': useErrorDialogs, - 'stickyAuth': stickyAuth, - 'sensitiveTransaction': sensitiveTransaction, - 'biometricOnly': biometricOnly, - }; - if (_platform.isIOS) { - args.addAll(iOSAuthStrings.args); - } else if (_platform.isAndroid) { - args.addAll(androidAuthStrings.args); - } else { - throw PlatformException( - code: otherOperatingSystem, - message: 'Local authentication does not support non-Android/iOS ' - 'operating systems.', - details: 'Your operating system is ${_platform.operatingSystem}', - ); - } - return (await _channel.invokeMethod('authenticate', args)) ?? false; + }) { + return LocalAuthPlatform.instance.authenticate( + localizedReason: localizedReason, + authMessages: [iOSAuthStrings, androidAuthStrings], + options: AuthenticationOptions( + useErrorDialogs: useErrorDialogs, + stickyAuth: stickyAuth, + sensitiveTransaction: sensitiveTransaction, + biometricOnly: biometricOnly, + ), + ); } /// Returns true if auth was cancelled successfully. @@ -131,7 +120,7 @@ class LocalAuthentication { /// Returns [Future] bool true or false: Future stopAuthentication() async { if (_platform.isAndroid) { - return await _channel.invokeMethod('stopAuthentication') ?? false; + return LocalAuthPlatform.instance.stopAuthentication(); } return true; } @@ -139,16 +128,15 @@ class LocalAuthentication { /// Returns true if device is capable of checking biometrics /// /// Returns a [Future] bool true or false: - Future get canCheckBiometrics async => - (await _channel.invokeListMethod('getAvailableBiometrics'))! - .isNotEmpty; + Future get canCheckBiometrics => + LocalAuthPlatform.instance.deviceSupportsBiometrics(); /// Returns true if device is capable of checking biometrics or is able to /// fail over to device credentials. /// /// Returns a [Future] bool true or false: Future isDeviceSupported() async => - (await _channel.invokeMethod('isDeviceSupported')) ?? false; + LocalAuthPlatform.instance.isDeviceSupported(); /// Returns a list of enrolled biometrics /// @@ -156,27 +144,6 @@ class LocalAuthentication { /// - BiometricType.face /// - BiometricType.fingerprint /// - BiometricType.iris (not yet implemented) - Future> getAvailableBiometrics() async { - final List result = (await _channel.invokeListMethod( - 'getAvailableBiometrics', - )) ?? - []; - final List biometrics = []; - for (final String value in result) { - switch (value) { - case 'face': - biometrics.add(BiometricType.face); - break; - case 'fingerprint': - biometrics.add(BiometricType.fingerprint); - break; - case 'iris': - biometrics.add(BiometricType.iris); - break; - case 'undefined': - break; - } - } - return biometrics; - } + Future> getAvailableBiometrics() => + LocalAuthPlatform.instance.getEnrolledBiometrics(); } diff --git a/packages/local_auth/local_auth/pubspec.yaml b/packages/local_auth/local_auth/pubspec.yaml index 78c79f4abce4..552c6f15b659 100644 --- a/packages/local_auth/local_auth/pubspec.yaml +++ b/packages/local_auth/local_auth/pubspec.yaml @@ -5,6 +5,10 @@ repository: https://github.com/flutter/plugins/tree/main/packages/local_auth/loc issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+local_auth%22 version: 1.1.11 +# Temporarily disable publishing to allow moving Android and iOS +# implementations. +publish_to: none + environment: sdk: ">=2.14.0 <3.0.0" flutter: ">=2.5.0" @@ -23,6 +27,7 @@ dependencies: sdk: flutter flutter_plugin_android_lifecycle: ^2.0.1 intl: ^0.17.0 + local_auth_platform_interface: ^1.0.0 platform: ^3.0.0 dev_dependencies: @@ -32,4 +37,4 @@ dev_dependencies: sdk: flutter integration_test: sdk: flutter - pedantic: ^1.10.0 + mockito: ^5.1.0 diff --git a/packages/local_auth/local_auth/test/local_auth_test.dart b/packages/local_auth/local_auth/test/local_auth_test.dart index 3de9758f9d0c..b92297d90231 100644 --- a/packages/local_auth/local_auth/test/local_auth_test.dart +++ b/packages/local_auth/local_auth/test/local_auth_test.dart @@ -2,255 +2,147 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:async'; - -import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:local_auth/auth_strings.dart'; import 'package:local_auth/local_auth.dart'; +import 'package:local_auth_platform_interface/local_auth_platform_interface.dart'; +import 'package:local_auth_platform_interface/types/auth_messages.dart'; +import 'package:local_auth_platform_interface/types/auth_options.dart'; +import 'package:mockito/mockito.dart'; import 'package:platform/platform.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; void main() { - TestWidgetsFlutterBinding.ensureInitialized(); + WidgetsFlutterBinding.ensureInitialized(); + late LocalAuthentication localAuthentication; + late MockLocalAuthPlatform mockLocalAuthPlatform; + + setUp(() { + localAuthentication = LocalAuthentication(); + mockLocalAuthPlatform = MockLocalAuthPlatform(); + LocalAuthPlatform.instance = mockLocalAuthPlatform; + }); + + test('authenticateWithBiometrics calls platform implementation', () { + when(mockLocalAuthPlatform.authenticate( + localizedReason: anyNamed('localizedReason'), + authMessages: anyNamed('authMessages'), + options: anyNamed('options'), + )).thenAnswer((_) async => true); + localAuthentication.authenticateWithBiometrics( + localizedReason: 'Test Reason'); + verify(mockLocalAuthPlatform.authenticate( + localizedReason: 'Test Reason', + authMessages: [ + const IOSAuthMessages(), + const AndroidAuthMessages(), + ], + options: const AuthenticationOptions(biometricOnly: true), + )).called(1); + }); + + test('authenticate calls platform implementation', () { + when(mockLocalAuthPlatform.authenticate( + localizedReason: anyNamed('localizedReason'), + authMessages: anyNamed('authMessages'), + options: anyNamed('options'), + )).thenAnswer((_) async => true); + localAuthentication.authenticate(localizedReason: 'Test Reason'); + verify(mockLocalAuthPlatform.authenticate( + localizedReason: 'Test Reason', + authMessages: [ + const IOSAuthMessages(), + const AndroidAuthMessages(), + ], + options: const AuthenticationOptions(), + )).called(1); + }); - group('LocalAuth', () { - const MethodChannel channel = MethodChannel( - 'plugins.flutter.io/local_auth', - ); + test('isDeviceSupported calls platform implementation', () { + when(mockLocalAuthPlatform.isDeviceSupported()) + .thenAnswer((_) async => true); + localAuthentication.isDeviceSupported(); + verify(mockLocalAuthPlatform.isDeviceSupported()).called(1); + }); - final List log = []; - late LocalAuthentication localAuthentication; + test('getEnrolledBiometrics calls platform implementation', () { + when(mockLocalAuthPlatform.getEnrolledBiometrics()) + .thenAnswer((_) async => []); + localAuthentication.getAvailableBiometrics(); + verify(mockLocalAuthPlatform.getEnrolledBiometrics()).called(1); + }); - setUp(() { - channel.setMockMethodCallHandler((MethodCall methodCall) { - log.add(methodCall); - return Future.value(true); - }); - localAuthentication = LocalAuthentication(); - log.clear(); - }); + test('stopAuthentication calls platform implementation on Android', () { + when(mockLocalAuthPlatform.stopAuthentication()) + .thenAnswer((_) async => true); + setMockPathProviderPlatform(FakePlatform(operatingSystem: 'android')); + localAuthentication.stopAuthentication(); + verify(mockLocalAuthPlatform.stopAuthentication()).called(1); + }); - group('With device auth fail over', () { - test('authenticate with no args on Android.', () async { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'android')); - await localAuthentication.authenticate( - localizedReason: 'Needs secure', - biometricOnly: true, - ); - expect( - log, - [ - isMethodCall( - 'authenticate', - arguments: { - 'localizedReason': 'Needs secure', - 'useErrorDialogs': true, - 'stickyAuth': false, - 'sensitiveTransaction': true, - 'biometricOnly': true, - 'biometricHint': androidBiometricHint, - 'biometricNotRecognized': androidBiometricNotRecognized, - 'biometricSuccess': androidBiometricSuccess, - 'biometricRequired': androidBiometricRequiredTitle, - 'cancelButton': androidCancelButton, - 'deviceCredentialsRequired': - androidDeviceCredentialsRequiredTitle, - 'deviceCredentialsSetupDescription': - androidDeviceCredentialsSetupDescription, - 'goToSetting': goToSettings, - 'goToSettingDescription': androidGoToSettingsDescription, - 'signInTitle': androidSignInTitle, - }, - ), - ], - ); - }); + test('stopAuthentication does not call platform implementation on iOS', () { + setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); + localAuthentication.stopAuthentication(); + verifyNever(mockLocalAuthPlatform.stopAuthentication()); + }); - test('authenticate with no args on iOS.', () async { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); - await localAuthentication.authenticate( - localizedReason: 'Needs secure', - biometricOnly: true, - ); - expect( - log, - [ - isMethodCall('authenticate', arguments: { - 'localizedReason': 'Needs secure', - 'useErrorDialogs': true, - 'stickyAuth': false, - 'sensitiveTransaction': true, - 'biometricOnly': true, - 'lockOut': iOSLockOut, - 'goToSetting': goToSettings, - 'goToSettingDescriptionIOS': iOSGoToSettingsDescription, - 'okButton': iOSOkButton, - }), - ], - ); - }); + test('canCheckBiometrics returns correct result', () async { + when(mockLocalAuthPlatform.deviceSupportsBiometrics()) + .thenAnswer((_) async => false); + bool? result; + result = await localAuthentication.canCheckBiometrics; + expect(result, false); + when(mockLocalAuthPlatform.deviceSupportsBiometrics()) + .thenAnswer((_) async => true); + result = await localAuthentication.canCheckBiometrics; + expect(result, true); + verify(mockLocalAuthPlatform.deviceSupportsBiometrics()).called(2); + }); +} - test('authenticate with `localizedFallbackTitle` on iOS.', () async { - const IOSAuthMessages iosAuthMessages = - IOSAuthMessages(localizedFallbackTitle: 'Enter PIN'); - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); - await localAuthentication.authenticate( - localizedReason: 'Needs secure', - biometricOnly: true, - iOSAuthStrings: iosAuthMessages, - ); - expect( - log, - [ - isMethodCall('authenticate', arguments: { - 'localizedReason': 'Needs secure', - 'useErrorDialogs': true, - 'stickyAuth': false, - 'sensitiveTransaction': true, - 'biometricOnly': true, - 'lockOut': iOSLockOut, - 'goToSetting': goToSettings, - 'goToSettingDescriptionIOS': iOSGoToSettingsDescription, - 'okButton': iOSOkButton, - 'localizedFallbackTitle': 'Enter PIN', - }), - ], - ); - }); +class MockLocalAuthPlatform extends Mock + with MockPlatformInterfaceMixin + implements LocalAuthPlatform { + MockLocalAuthPlatform() { + throwOnMissingStub(this); + } - test('authenticate with no localizedReason on iOS.', () async { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); - await expectLater( - localAuthentication.authenticate( - localizedReason: '', - biometricOnly: true, - ), - throwsAssertionError, - ); - }); + @override + Future authenticate({ + String? localizedReason, + Iterable? authMessages = const [ + IOSAuthMessages(), + AndroidAuthMessages() + ], + AuthenticationOptions? options = const AuthenticationOptions(), + }) => + super.noSuchMethod( + Invocation.method(#authenticate, [], { + #localizedReason: localizedReason, + #authMessages: authMessages, + #options: options, + }), + returnValue: Future.value(false)) as Future; - test('authenticate with no sensitive transaction.', () async { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'android')); - await localAuthentication.authenticate( - localizedReason: 'Insecure', - sensitiveTransaction: false, - useErrorDialogs: false, - biometricOnly: true, - ); - expect( - log, - [ - isMethodCall('authenticate', arguments: { - 'localizedReason': 'Insecure', - 'useErrorDialogs': false, - 'stickyAuth': false, - 'sensitiveTransaction': false, - 'biometricOnly': true, - 'biometricHint': androidBiometricHint, - 'biometricNotRecognized': androidBiometricNotRecognized, - 'biometricSuccess': androidBiometricSuccess, - 'biometricRequired': androidBiometricRequiredTitle, - 'cancelButton': androidCancelButton, - 'deviceCredentialsRequired': - androidDeviceCredentialsRequiredTitle, - 'deviceCredentialsSetupDescription': - androidDeviceCredentialsSetupDescription, - 'goToSetting': goToSettings, - 'goToSettingDescription': androidGoToSettingsDescription, - 'signInTitle': androidSignInTitle, - }), - ], - ); - }); - }); + @override + Future> getEnrolledBiometrics() => + super.noSuchMethod(Invocation.method(#getEnrolledBiometrics, []), + returnValue: Future>.value([])) + as Future>; - group('With biometrics only', () { - test('authenticate with no args on Android.', () async { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'android')); - await localAuthentication.authenticate( - localizedReason: 'Needs secure', - ); - expect( - log, - [ - isMethodCall('authenticate', arguments: { - 'localizedReason': 'Needs secure', - 'useErrorDialogs': true, - 'stickyAuth': false, - 'sensitiveTransaction': true, - 'biometricOnly': false, - 'biometricHint': androidBiometricHint, - 'biometricNotRecognized': androidBiometricNotRecognized, - 'biometricSuccess': androidBiometricSuccess, - 'biometricRequired': androidBiometricRequiredTitle, - 'cancelButton': androidCancelButton, - 'deviceCredentialsRequired': - androidDeviceCredentialsRequiredTitle, - 'deviceCredentialsSetupDescription': - androidDeviceCredentialsSetupDescription, - 'goToSetting': goToSettings, - 'goToSettingDescription': androidGoToSettingsDescription, - 'signInTitle': androidSignInTitle, - }), - ], - ); - }); + @override + Future isDeviceSupported() => + super.noSuchMethod(Invocation.method(#isDeviceSupported, []), + returnValue: Future.value(false)) as Future; - test('authenticate with no args on iOS.', () async { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); - await localAuthentication.authenticate( - localizedReason: 'Needs secure', - ); - expect( - log, - [ - isMethodCall('authenticate', arguments: { - 'localizedReason': 'Needs secure', - 'useErrorDialogs': true, - 'stickyAuth': false, - 'sensitiveTransaction': true, - 'biometricOnly': false, - 'lockOut': iOSLockOut, - 'goToSetting': goToSettings, - 'goToSettingDescriptionIOS': iOSGoToSettingsDescription, - 'okButton': iOSOkButton, - }), - ], - ); - }); + @override + Future stopAuthentication() => + super.noSuchMethod(Invocation.method(#stopAuthentication, []), + returnValue: Future.value(false)) as Future; - test('authenticate with no sensitive transaction.', () async { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'android')); - await localAuthentication.authenticate( - localizedReason: 'Insecure', - sensitiveTransaction: false, - useErrorDialogs: false, - ); - expect( - log, - [ - isMethodCall('authenticate', arguments: { - 'localizedReason': 'Insecure', - 'useErrorDialogs': false, - 'stickyAuth': false, - 'sensitiveTransaction': false, - 'biometricOnly': false, - 'biometricHint': androidBiometricHint, - 'biometricNotRecognized': androidBiometricNotRecognized, - 'biometricSuccess': androidBiometricSuccess, - 'biometricRequired': androidBiometricRequiredTitle, - 'cancelButton': androidCancelButton, - 'deviceCredentialsRequired': - androidDeviceCredentialsRequiredTitle, - 'deviceCredentialsSetupDescription': - androidDeviceCredentialsSetupDescription, - 'goToSetting': goToSettings, - 'goToSettingDescription': androidGoToSettingsDescription, - 'signInTitle': androidSignInTitle, - }), - ], - ); - }); - }); - }); + @override + Future deviceSupportsBiometrics() => super.noSuchMethod( + Invocation.method(#deviceSupportsBiometrics, []), + returnValue: Future.value(false)) as Future; } From d8e3942736937ccd1f31937ec26a2f7ea785d327 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Thu, 7 Apr 2022 17:46:23 +0200 Subject: [PATCH 31/36] Remove accidental deprecation --- packages/local_auth/local_auth/lib/local_auth.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/local_auth/local_auth/lib/local_auth.dart b/packages/local_auth/local_auth/lib/local_auth.dart index 70d41b01330f..40869f386848 100644 --- a/packages/local_auth/local_auth/lib/local_auth.dart +++ b/packages/local_auth/local_auth/lib/local_auth.dart @@ -91,7 +91,6 @@ class LocalAuthentication { /// authentication (e.g. lack of relevant hardware). This might throw /// [PlatformException] with error code [otherOperatingSystem] on the iOS /// simulator. - @Deprecated('Use `requestAuthentication` instead.') Future authenticate({ required String localizedReason, bool useErrorDialogs = true, From 57cb84c15f17b6068427070c45bd032eb8323931 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Thu, 7 Apr 2022 17:49:56 +0200 Subject: [PATCH 32/36] Export externally used types from local_auth_platform_interface.dart directly. --- .../local_auth/local_auth_platform_interface/CHANGELOG.md | 4 ++++ .../lib/local_auth_platform_interface.dart | 6 +++--- .../local_auth_platform_interface/lib/types/types.dart | 3 +++ .../local_auth/local_auth_platform_interface/pubspec.yaml | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 packages/local_auth/local_auth_platform_interface/lib/types/types.dart diff --git a/packages/local_auth/local_auth_platform_interface/CHANGELOG.md b/packages/local_auth/local_auth_platform_interface/CHANGELOG.md index 0d8803f93540..d16a91ee259a 100644 --- a/packages/local_auth/local_auth_platform_interface/CHANGELOG.md +++ b/packages/local_auth/local_auth_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.1 + +* Export externally used types from local_auth_platform_interface.dart directly. + ## 1.0.0 * Initial release. diff --git a/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart b/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart index b909ee90d12b..de652b20f462 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/local_auth_platform_interface.dart @@ -3,11 +3,11 @@ // found in the LICENSE file. import 'package:local_auth_platform_interface/default_method_channel_platform.dart'; -import 'package:local_auth_platform_interface/types/auth_messages.dart'; -import 'package:local_auth_platform_interface/types/auth_options.dart'; -import 'package:local_auth_platform_interface/types/biometric_type.dart'; +import 'package:local_auth_platform_interface/types/types.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; +export 'package:local_auth_platform_interface/types/types.dart'; + /// The interface that implementations of local_auth must implement. /// /// Platform implementations should extend this class rather than implement it as `local_auth` diff --git a/packages/local_auth/local_auth_platform_interface/lib/types/types.dart b/packages/local_auth/local_auth_platform_interface/lib/types/types.dart new file mode 100644 index 000000000000..77a5f4ec099c --- /dev/null +++ b/packages/local_auth/local_auth_platform_interface/lib/types/types.dart @@ -0,0 +1,3 @@ +export 'auth_messages.dart'; +export 'auth_options.dart'; +export 'biometric_type.dart'; diff --git a/packages/local_auth/local_auth_platform_interface/pubspec.yaml b/packages/local_auth/local_auth_platform_interface/pubspec.yaml index f04268926ebd..cd12a8a2dcab 100644 --- a/packages/local_auth/local_auth_platform_interface/pubspec.yaml +++ b/packages/local_auth/local_auth_platform_interface/pubspec.yaml @@ -4,7 +4,7 @@ repository: https://github.com/flutter/plugins/tree/master/packages/local_auth/l issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+local_auth%22 # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.0.0 +version: 1.0.1 environment: sdk: ">=2.14.0 <3.0.0" From 78214fe3b1c1bf3e879afc01e77b98a354679a93 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Thu, 7 Apr 2022 17:56:11 +0200 Subject: [PATCH 33/36] Add missing license header --- .../local_auth_platform_interface/lib/types/types.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/local_auth/local_auth_platform_interface/lib/types/types.dart b/packages/local_auth/local_auth_platform_interface/lib/types/types.dart index 77a5f4ec099c..ea43b942cffd 100644 --- a/packages/local_auth/local_auth_platform_interface/lib/types/types.dart +++ b/packages/local_auth/local_auth_platform_interface/lib/types/types.dart @@ -1,3 +1,7 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + export 'auth_messages.dart'; export 'auth_options.dart'; export 'biometric_type.dart'; From d0fd4c19e2d8c77b656a29b0d71d1013eafcbafc Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Thu, 7 Apr 2022 18:10:22 +0200 Subject: [PATCH 34/36] Update imports of types from platform interface package. --- packages/local_auth/local_auth/CHANGELOG.md | 2 +- packages/local_auth/local_auth/lib/local_auth.dart | 3 --- packages/local_auth/local_auth/pubspec.yaml | 5 ++++- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/local_auth/local_auth/CHANGELOG.md b/packages/local_auth/local_auth/CHANGELOG.md index 76ac27b53b3c..1ca9fe146c7b 100644 --- a/packages/local_auth/local_auth/CHANGELOG.md +++ b/packages/local_auth/local_auth/CHANGELOG.md @@ -1,7 +1,7 @@ ## NEXT * Adds OS version support information to README. -* Switched over to default method implementation in new platform interface. +* Switches over to default method implementation in new platform interface. ## 1.1.11 diff --git a/packages/local_auth/local_auth/lib/local_auth.dart b/packages/local_auth/local_auth/lib/local_auth.dart index 40869f386848..32818b31783d 100644 --- a/packages/local_auth/local_auth/lib/local_auth.dart +++ b/packages/local_auth/local_auth/lib/local_auth.dart @@ -13,9 +13,6 @@ import 'dart:async'; import 'package:flutter/foundation.dart' show visibleForTesting; import 'package:flutter/services.dart'; import 'package:local_auth_platform_interface/local_auth_platform_interface.dart'; -import 'package:local_auth_platform_interface/types/auth_messages.dart'; -import 'package:local_auth_platform_interface/types/auth_options.dart'; -import 'package:local_auth_platform_interface/types/biometric_type.dart'; import 'package:platform/platform.dart'; import 'auth_strings.dart'; diff --git a/packages/local_auth/local_auth/pubspec.yaml b/packages/local_auth/local_auth/pubspec.yaml index 552c6f15b659..6d0b5fccf62c 100644 --- a/packages/local_auth/local_auth/pubspec.yaml +++ b/packages/local_auth/local_auth/pubspec.yaml @@ -27,7 +27,10 @@ dependencies: sdk: flutter flutter_plugin_android_lifecycle: ^2.0.1 intl: ^0.17.0 - local_auth_platform_interface: ^1.0.0 + # TODO(BeMacized): Change back to 1.0.1 once published. +# local_auth_platform_interface: ^1.0.1 + local_auth_platform_interface: + path: ../local_auth_platform_interface platform: ^3.0.0 dev_dependencies: From f54719a4f24daf769fb3576e914d445525ac7f93 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Fri, 8 Apr 2022 08:41:58 +0200 Subject: [PATCH 35/36] Update dependency on platform interface package --- packages/local_auth/local_auth/pubspec.yaml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/local_auth/local_auth/pubspec.yaml b/packages/local_auth/local_auth/pubspec.yaml index 6d0b5fccf62c..65005613aab0 100644 --- a/packages/local_auth/local_auth/pubspec.yaml +++ b/packages/local_auth/local_auth/pubspec.yaml @@ -27,10 +27,7 @@ dependencies: sdk: flutter flutter_plugin_android_lifecycle: ^2.0.1 intl: ^0.17.0 - # TODO(BeMacized): Change back to 1.0.1 once published. -# local_auth_platform_interface: ^1.0.1 - local_auth_platform_interface: - path: ../local_auth_platform_interface + local_auth_platform_interface: ^1.0.1 platform: ^3.0.0 dev_dependencies: From c77dc2151096827e0d054ba9cca8ea014fbd392c Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Fri, 8 Apr 2022 08:48:46 +0200 Subject: [PATCH 36/36] Fix analysis issues --- packages/local_auth/local_auth/lib/auth_strings.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/local_auth/local_auth/lib/auth_strings.dart b/packages/local_auth/local_auth/lib/auth_strings.dart index e5dd738ebd53..585742ac68c2 100644 --- a/packages/local_auth/local_auth/lib/auth_strings.dart +++ b/packages/local_auth/local_auth/lib/auth_strings.dart @@ -39,6 +39,7 @@ class AndroidAuthMessages extends AuthMessages { final String? goToSettingsDescription; final String? signInTitle; + @override Map get args { return { 'biometricHint': biometricHint ?? androidBiometricHint, @@ -78,6 +79,7 @@ class IOSAuthMessages extends AuthMessages { final String? cancelButton; final String? localizedFallbackTitle; + @override Map get args { return { 'lockOut': lockOut ?? iOSLockOut,