From 111e63723a5bb5d53940f32ec9c44ba871981653 Mon Sep 17 00:00:00 2001 From: Emmanuel Garcia Date: Mon, 24 Feb 2020 10:18:21 -0700 Subject: [PATCH 01/37] [flutter-plugin-android-lifecycle] Update Gradle version (#2551) --- packages/flutter_plugin_android_lifecycle/CHANGELOG.md | 4 ++++ .../android/gradle/wrapper/gradle-wrapper.properties | 2 +- packages/flutter_plugin_android_lifecycle/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/flutter_plugin_android_lifecycle/CHANGELOG.md b/packages/flutter_plugin_android_lifecycle/CHANGELOG.md index d8a04c731613..874eb461d943 100644 --- a/packages/flutter_plugin_android_lifecycle/CHANGELOG.md +++ b/packages/flutter_plugin_android_lifecycle/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.7 + +* Update Gradle version. Fixes https://github.com/flutter/flutter/issues/48724. + ## 1.0.6 * Make the pedantic dev_dependency explicit. diff --git a/packages/flutter_plugin_android_lifecycle/android/gradle/wrapper/gradle-wrapper.properties b/packages/flutter_plugin_android_lifecycle/android/gradle/wrapper/gradle-wrapper.properties index 019065d1d650..d757f3d33fcc 100644 --- a/packages/flutter_plugin_android_lifecycle/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/flutter_plugin_android_lifecycle/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip diff --git a/packages/flutter_plugin_android_lifecycle/pubspec.yaml b/packages/flutter_plugin_android_lifecycle/pubspec.yaml index 567608c3fa04..a9191be477fa 100644 --- a/packages/flutter_plugin_android_lifecycle/pubspec.yaml +++ b/packages/flutter_plugin_android_lifecycle/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_plugin_android_lifecycle description: Flutter plugin for accessing an Android Lifecycle within other plugins. -version: 1.0.6 +version: 1.0.7 homepage: https://github.com/flutter/plugins/tree/master/packages/flutter_plugin_android_lifecycle environment: From 5ce6e9b749e97a6fa93d9d26f1c83e58cda0f526 Mon Sep 17 00:00:00 2001 From: Michael Bui <25263378+MaikuB@users.noreply.github.com> Date: Tue, 25 Feb 2020 09:08:19 +1100 Subject: [PATCH 02/37] [e2e] fix flutter driver code snippet in readme and improve formatting of code snippets (#2549) * [e2e] fix flutter driver code snippet in readme and improve formatting --- packages/e2e/CHANGELOG.md | 4 ++++ packages/e2e/README.md | 9 ++++++--- packages/e2e/pubspec.yaml | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/e2e/CHANGELOG.md b/packages/e2e/CHANGELOG.md index 442b1db121f9..35d3159e05b4 100644 --- a/packages/e2e/CHANGELOG.md +++ b/packages/e2e/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.4+3 + +* Fixed code snippet in the readme under the "Using Flutter driver to run tests" section. + ## 0.2.4+2 * Make the pedantic dev_dependency explicit. diff --git a/packages/e2e/README.md b/packages/e2e/README.md index b3c19ec40027..ed892ab6e7ff 100644 --- a/packages/e2e/README.md +++ b/packages/e2e/README.md @@ -41,12 +41,15 @@ Note that the tests don't use the `FlutterDriver` API, they use `testWidgets` in Put the a file named `_e2e_test.dart` in the app' `test_driver` directory: -``` +```dart +import 'dart:async'; +import 'dart:io'; import 'package:flutter_driver/flutter_driver.dart'; Future main() async { final FlutterDriver driver = await FlutterDriver.connect(); - await driver.requestData(null, timeout: const Duration(minutes: 1)); + final String result = + await driver.requestData(null, timeout: const Duration(minutes: 1)); await driver.close(); exit(result == 'pass' ? 0 : 1); } @@ -73,7 +76,7 @@ Create an instrumentation test file in your application's com, example, and myapp with values from your app's package name). You can name this test file MainActivityTest.java or another name of your choice. -``` +```java package com.example.myapp; import androidx.test.rule.ActivityTestRule; diff --git a/packages/e2e/pubspec.yaml b/packages/e2e/pubspec.yaml index 956f5bf0cbb7..68735867218c 100644 --- a/packages/e2e/pubspec.yaml +++ b/packages/e2e/pubspec.yaml @@ -1,6 +1,6 @@ name: e2e description: Runs tests that use the flutter_test API as integration tests. -version: 0.2.4+2 +version: 0.2.4+3 homepage: https://github.com/flutter/plugins/tree/master/packages/e2e environment: From 2e14771c937788c1615be4c6d4f3ad93aa4276ab Mon Sep 17 00:00:00 2001 From: Francisco Magdaleno Date: Mon, 24 Feb 2020 16:22:53 -0800 Subject: [PATCH 03/37] [path_provider] Move package into a path_provider directory (#2542) * Move path provider to dir * Fix example * Add dart file * Rename file * Update homepage link --- packages/path_provider/example/android.iml | 12 ------------ .../example/path_provider_example.iml | 15 --------------- .../{ => path_provider}/CHANGELOG.md | 4 ++++ .../path_provider/{ => path_provider}/LICENSE | 0 .../path_provider/{ => path_provider}/README.md | 0 .../{ => path_provider}/android/build.gradle | 0 .../android/gradle.properties | 0 .../{ => path_provider}/android/settings.gradle | 0 .../android/src/main/AndroidManifest.xml | 0 .../plugins/pathprovider/PathProviderPlugin.java | 0 .../pathprovider/StorageDirectoryMapper.java | 0 .../pathprovider/StorageDirectoryMapperTest.java | 0 .../{ => path_provider}/example/README.md | 0 .../example/android/app/build.gradle | 0 .../app/gradle/wrapper/gradle-wrapper.properties | 0 .../java/EmbeddingV1ActivityTest.java | 0 .../src/androidTest/java/MainActivityTest.java | 0 .../android/app/src/main/AndroidManifest.xml | 0 .../pathproviderexample/EmbeddingV1Activity.java | 0 .../pathproviderexample/MainActivity.java | 0 .../app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin .../app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin .../src/main/res/mipmap-xxhdpi/ic_launcher.png | Bin .../src/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/ios/Flutter/AppFrameworkInfo.plist | 0 .../example/ios/Flutter/Debug.xcconfig | 0 .../example/ios/Flutter/Release.xcconfig | 0 .../example/ios/Runner.xcodeproj/project.pbxproj | 0 .../project.xcworkspace/contents.xcworkspacedata | 0 .../xcshareddata/xcschemes/Runner.xcscheme | 0 .../Runner.xcworkspace/contents.xcworkspacedata | 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 .../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 .../{ => path_provider}/example/lib/main.dart | 0 .../example/macos/Flutter/Flutter-Debug.xcconfig | 0 .../macos/Flutter/Flutter-Release.xcconfig | 0 .../Flutter/GeneratedPluginRegistrant.swift | 0 .../macos/Runner.xcodeproj/project.pbxproj | 0 .../xcshareddata/xcschemes/Runner.xcscheme | 0 .../Runner.xcworkspace/contents.xcworkspacedata | 0 .../xcshareddata/IDEWorkspaceChecks.plist | 0 .../example/macos/Runner/AppDelegate.swift | 0 .../AppIcon.appiconset/Contents.json | 0 .../AppIcon.appiconset/app_icon_1024.png | Bin .../AppIcon.appiconset/app_icon_128.png | Bin .../AppIcon.appiconset/app_icon_16.png | Bin .../AppIcon.appiconset/app_icon_256.png | Bin .../AppIcon.appiconset/app_icon_32.png | Bin .../AppIcon.appiconset/app_icon_512.png | Bin .../AppIcon.appiconset/app_icon_64.png | Bin .../example/macos/Runner/Base.lproj/MainMenu.xib | 0 .../macos/Runner/Configs/AppInfo.xcconfig | 0 .../example/macos/Runner/Configs/Debug.xcconfig | 0 .../macos/Runner/Configs/Release.xcconfig | 0 .../macos/Runner/Configs/Warnings.xcconfig | 0 .../macos/Runner/DebugProfile.entitlements | 0 .../example/macos/Runner/Info.plist | 0 .../example/macos/Runner/MainFlutterWindow.swift | 0 .../example/macos/Runner/Release.entitlements | 0 .../{ => path_provider}/example/pubspec.yaml | 2 +- .../example/test_driver/path_provider_e2e.dart | 0 .../test_driver/path_provider_e2e_test.dart | 0 .../{ => path_provider}/ios/Assets/.gitkeep | 0 .../ios/Classes/FLTPathProviderPlugin.h | 0 .../ios/Classes/FLTPathProviderPlugin.m | 0 .../ios/path_provider.podspec | 0 .../{ => path_provider}/lib/path_provider.dart | 0 .../{ => path_provider}/pubspec.yaml | 4 ++-- .../test/path_provider_e2e.dart | 0 .../test/path_provider_test.dart | 0 .../lib/path_provider_macos.dart | 3 +++ 95 files changed, 10 insertions(+), 30 deletions(-) delete mode 100644 packages/path_provider/example/android.iml delete mode 100644 packages/path_provider/example/path_provider_example.iml rename packages/path_provider/{ => path_provider}/CHANGELOG.md (98%) rename packages/path_provider/{ => path_provider}/LICENSE (100%) rename packages/path_provider/{ => path_provider}/README.md (100%) rename packages/path_provider/{ => path_provider}/android/build.gradle (100%) rename packages/path_provider/{ => path_provider}/android/gradle.properties (100%) rename packages/path_provider/{ => path_provider}/android/settings.gradle (100%) rename packages/path_provider/{ => path_provider}/android/src/main/AndroidManifest.xml (100%) rename packages/path_provider/{ => path_provider}/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java (100%) rename packages/path_provider/{ => path_provider}/android/src/main/java/io/flutter/plugins/pathprovider/StorageDirectoryMapper.java (100%) rename packages/path_provider/{ => path_provider}/android/src/test/java/io/flutter/plugins/pathprovider/StorageDirectoryMapperTest.java (100%) rename packages/path_provider/{ => path_provider}/example/README.md (100%) rename packages/path_provider/{ => path_provider}/example/android/app/build.gradle (100%) rename packages/path_provider/{ => path_provider}/example/android/app/gradle/wrapper/gradle-wrapper.properties (100%) rename packages/path_provider/{ => path_provider}/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java (100%) rename packages/path_provider/{ => path_provider}/example/android/app/src/androidTest/java/MainActivityTest.java (100%) rename packages/path_provider/{ => path_provider}/example/android/app/src/main/AndroidManifest.xml (100%) rename packages/path_provider/{ => path_provider}/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/EmbeddingV1Activity.java (100%) rename packages/path_provider/{ => path_provider}/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/MainActivity.java (100%) rename packages/path_provider/{ => path_provider}/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png (100%) rename packages/path_provider/{ => path_provider}/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png (100%) rename packages/path_provider/{ => path_provider}/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png (100%) rename packages/path_provider/{ => path_provider}/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png (100%) rename packages/path_provider/{ => path_provider}/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png (100%) rename packages/path_provider/{ => path_provider}/example/android/build.gradle (100%) rename packages/path_provider/{ => path_provider}/example/android/gradle.properties (100%) rename packages/path_provider/{ => path_provider}/example/android/gradle/wrapper/gradle-wrapper.properties (100%) rename packages/path_provider/{ => path_provider}/example/android/settings.gradle (100%) rename packages/path_provider/{ => path_provider}/example/ios/Flutter/AppFrameworkInfo.plist (100%) rename packages/path_provider/{ => path_provider}/example/ios/Flutter/Debug.xcconfig (100%) rename packages/path_provider/{ => path_provider}/example/ios/Flutter/Release.xcconfig (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner.xcodeproj/project.pbxproj (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner.xcworkspace/contents.xcworkspacedata (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner/AppDelegate.h (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner/AppDelegate.m (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner/Base.lproj/LaunchScreen.storyboard (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner/Base.lproj/Main.storyboard (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner/Info.plist (100%) rename packages/path_provider/{ => path_provider}/example/ios/Runner/main.m (100%) rename packages/path_provider/{ => path_provider}/example/lib/main.dart (100%) rename packages/path_provider/{ => path_provider}/example/macos/Flutter/Flutter-Debug.xcconfig (100%) rename packages/path_provider/{ => path_provider}/example/macos/Flutter/Flutter-Release.xcconfig (100%) rename packages/path_provider/{ => path_provider}/example/macos/Flutter/GeneratedPluginRegistrant.swift (100%) rename packages/path_provider/{ => path_provider}/example/macos/Runner.xcodeproj/project.pbxproj (100%) rename packages/path_provider/{ => path_provider}/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme (100%) rename packages/path_provider/{ => path_provider}/example/macos/Runner.xcworkspace/contents.xcworkspacedata (100%) rename packages/path_provider/{ => path_provider}/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename packages/path_provider/{ => path_provider}/example/macos/Runner/AppDelegate.swift (100%) rename packages/path_provider/{ => path_provider}/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json (100%) rename packages/path_provider/{ => path_provider}/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png (100%) rename packages/path_provider/{ => path_provider}/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png (100%) rename packages/path_provider/{ => path_provider}/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png (100%) rename packages/path_provider/{ => path_provider}/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png (100%) rename packages/path_provider/{ => path_provider}/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png (100%) rename packages/path_provider/{ => path_provider}/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png (100%) rename packages/path_provider/{ => path_provider}/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png (100%) rename packages/path_provider/{ => path_provider}/example/macos/Runner/Base.lproj/MainMenu.xib (100%) rename packages/path_provider/{ => path_provider}/example/macos/Runner/Configs/AppInfo.xcconfig (100%) rename packages/path_provider/{ => path_provider}/example/macos/Runner/Configs/Debug.xcconfig (100%) rename packages/path_provider/{ => path_provider}/example/macos/Runner/Configs/Release.xcconfig (100%) rename packages/path_provider/{ => path_provider}/example/macos/Runner/Configs/Warnings.xcconfig (100%) rename packages/path_provider/{ => path_provider}/example/macos/Runner/DebugProfile.entitlements (100%) rename packages/path_provider/{ => path_provider}/example/macos/Runner/Info.plist (100%) rename packages/path_provider/{ => path_provider}/example/macos/Runner/MainFlutterWindow.swift (100%) rename packages/path_provider/{ => path_provider}/example/macos/Runner/Release.entitlements (100%) rename packages/path_provider/{ => path_provider}/example/pubspec.yaml (90%) rename packages/path_provider/{ => path_provider}/example/test_driver/path_provider_e2e.dart (100%) rename packages/path_provider/{ => path_provider}/example/test_driver/path_provider_e2e_test.dart (100%) rename packages/path_provider/{ => path_provider}/ios/Assets/.gitkeep (100%) rename packages/path_provider/{ => path_provider}/ios/Classes/FLTPathProviderPlugin.h (100%) rename packages/path_provider/{ => path_provider}/ios/Classes/FLTPathProviderPlugin.m (100%) rename packages/path_provider/{ => path_provider}/ios/path_provider.podspec (100%) rename packages/path_provider/{ => path_provider}/lib/path_provider.dart (100%) rename packages/path_provider/{ => path_provider}/pubspec.yaml (94%) rename packages/path_provider/{ => path_provider}/test/path_provider_e2e.dart (100%) rename packages/path_provider/{ => path_provider}/test/path_provider_test.dart (100%) create mode 100644 packages/path_provider/path_provider_macos/lib/path_provider_macos.dart diff --git a/packages/path_provider/example/android.iml b/packages/path_provider/example/android.iml deleted file mode 100644 index 462b903e05b6..000000000000 --- a/packages/path_provider/example/android.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/packages/path_provider/example/path_provider_example.iml b/packages/path_provider/example/path_provider_example.iml deleted file mode 100644 index 9d5dae19540c..000000000000 --- a/packages/path_provider/example/path_provider_example.iml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/packages/path_provider/CHANGELOG.md b/packages/path_provider/path_provider/CHANGELOG.md similarity index 98% rename from packages/path_provider/CHANGELOG.md rename to packages/path_provider/path_provider/CHANGELOG.md index ba2d0a95cca1..439c0c52cdda 100644 --- a/packages/path_provider/CHANGELOG.md +++ b/packages/path_provider/path_provider/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.2 + +* Move package contents into `path_provider` for platform federation. + ## 1.6.1 * Make the pedantic dev_dependency explicit. diff --git a/packages/path_provider/LICENSE b/packages/path_provider/path_provider/LICENSE similarity index 100% rename from packages/path_provider/LICENSE rename to packages/path_provider/path_provider/LICENSE diff --git a/packages/path_provider/README.md b/packages/path_provider/path_provider/README.md similarity index 100% rename from packages/path_provider/README.md rename to packages/path_provider/path_provider/README.md diff --git a/packages/path_provider/android/build.gradle b/packages/path_provider/path_provider/android/build.gradle similarity index 100% rename from packages/path_provider/android/build.gradle rename to packages/path_provider/path_provider/android/build.gradle diff --git a/packages/path_provider/android/gradle.properties b/packages/path_provider/path_provider/android/gradle.properties similarity index 100% rename from packages/path_provider/android/gradle.properties rename to packages/path_provider/path_provider/android/gradle.properties diff --git a/packages/path_provider/android/settings.gradle b/packages/path_provider/path_provider/android/settings.gradle similarity index 100% rename from packages/path_provider/android/settings.gradle rename to packages/path_provider/path_provider/android/settings.gradle diff --git a/packages/path_provider/android/src/main/AndroidManifest.xml b/packages/path_provider/path_provider/android/src/main/AndroidManifest.xml similarity index 100% rename from packages/path_provider/android/src/main/AndroidManifest.xml rename to packages/path_provider/path_provider/android/src/main/AndroidManifest.xml diff --git a/packages/path_provider/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java b/packages/path_provider/path_provider/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java similarity index 100% rename from packages/path_provider/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java rename to packages/path_provider/path_provider/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java diff --git a/packages/path_provider/android/src/main/java/io/flutter/plugins/pathprovider/StorageDirectoryMapper.java b/packages/path_provider/path_provider/android/src/main/java/io/flutter/plugins/pathprovider/StorageDirectoryMapper.java similarity index 100% rename from packages/path_provider/android/src/main/java/io/flutter/plugins/pathprovider/StorageDirectoryMapper.java rename to packages/path_provider/path_provider/android/src/main/java/io/flutter/plugins/pathprovider/StorageDirectoryMapper.java diff --git a/packages/path_provider/android/src/test/java/io/flutter/plugins/pathprovider/StorageDirectoryMapperTest.java b/packages/path_provider/path_provider/android/src/test/java/io/flutter/plugins/pathprovider/StorageDirectoryMapperTest.java similarity index 100% rename from packages/path_provider/android/src/test/java/io/flutter/plugins/pathprovider/StorageDirectoryMapperTest.java rename to packages/path_provider/path_provider/android/src/test/java/io/flutter/plugins/pathprovider/StorageDirectoryMapperTest.java diff --git a/packages/path_provider/example/README.md b/packages/path_provider/path_provider/example/README.md similarity index 100% rename from packages/path_provider/example/README.md rename to packages/path_provider/path_provider/example/README.md diff --git a/packages/path_provider/example/android/app/build.gradle b/packages/path_provider/path_provider/example/android/app/build.gradle similarity index 100% rename from packages/path_provider/example/android/app/build.gradle rename to packages/path_provider/path_provider/example/android/app/build.gradle diff --git a/packages/path_provider/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/path_provider/path_provider/example/android/app/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from packages/path_provider/example/android/app/gradle/wrapper/gradle-wrapper.properties rename to packages/path_provider/path_provider/example/android/app/gradle/wrapper/gradle-wrapper.properties diff --git a/packages/path_provider/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java b/packages/path_provider/path_provider/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java similarity index 100% rename from packages/path_provider/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java rename to packages/path_provider/path_provider/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java diff --git a/packages/path_provider/example/android/app/src/androidTest/java/MainActivityTest.java b/packages/path_provider/path_provider/example/android/app/src/androidTest/java/MainActivityTest.java similarity index 100% rename from packages/path_provider/example/android/app/src/androidTest/java/MainActivityTest.java rename to packages/path_provider/path_provider/example/android/app/src/androidTest/java/MainActivityTest.java diff --git a/packages/path_provider/example/android/app/src/main/AndroidManifest.xml b/packages/path_provider/path_provider/example/android/app/src/main/AndroidManifest.xml similarity index 100% rename from packages/path_provider/example/android/app/src/main/AndroidManifest.xml rename to packages/path_provider/path_provider/example/android/app/src/main/AndroidManifest.xml diff --git a/packages/path_provider/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/EmbeddingV1Activity.java b/packages/path_provider/path_provider/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/EmbeddingV1Activity.java similarity index 100% rename from packages/path_provider/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/EmbeddingV1Activity.java rename to packages/path_provider/path_provider/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/EmbeddingV1Activity.java diff --git a/packages/path_provider/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/MainActivity.java b/packages/path_provider/path_provider/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/MainActivity.java similarity index 100% rename from packages/path_provider/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/MainActivity.java rename to packages/path_provider/path_provider/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/MainActivity.java diff --git a/packages/path_provider/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/packages/path_provider/path_provider/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from packages/path_provider/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png rename to packages/path_provider/path_provider/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/packages/path_provider/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/packages/path_provider/path_provider/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from packages/path_provider/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png rename to packages/path_provider/path_provider/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/packages/path_provider/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/packages/path_provider/path_provider/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from packages/path_provider/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png rename to packages/path_provider/path_provider/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/packages/path_provider/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/packages/path_provider/path_provider/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from packages/path_provider/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png rename to packages/path_provider/path_provider/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/packages/path_provider/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/packages/path_provider/path_provider/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from packages/path_provider/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png rename to packages/path_provider/path_provider/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/packages/path_provider/example/android/build.gradle b/packages/path_provider/path_provider/example/android/build.gradle similarity index 100% rename from packages/path_provider/example/android/build.gradle rename to packages/path_provider/path_provider/example/android/build.gradle diff --git a/packages/path_provider/example/android/gradle.properties b/packages/path_provider/path_provider/example/android/gradle.properties similarity index 100% rename from packages/path_provider/example/android/gradle.properties rename to packages/path_provider/path_provider/example/android/gradle.properties diff --git a/packages/path_provider/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/path_provider/path_provider/example/android/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from packages/path_provider/example/android/gradle/wrapper/gradle-wrapper.properties rename to packages/path_provider/path_provider/example/android/gradle/wrapper/gradle-wrapper.properties diff --git a/packages/path_provider/example/android/settings.gradle b/packages/path_provider/path_provider/example/android/settings.gradle similarity index 100% rename from packages/path_provider/example/android/settings.gradle rename to packages/path_provider/path_provider/example/android/settings.gradle diff --git a/packages/path_provider/example/ios/Flutter/AppFrameworkInfo.plist b/packages/path_provider/path_provider/example/ios/Flutter/AppFrameworkInfo.plist similarity index 100% rename from packages/path_provider/example/ios/Flutter/AppFrameworkInfo.plist rename to packages/path_provider/path_provider/example/ios/Flutter/AppFrameworkInfo.plist diff --git a/packages/path_provider/example/ios/Flutter/Debug.xcconfig b/packages/path_provider/path_provider/example/ios/Flutter/Debug.xcconfig similarity index 100% rename from packages/path_provider/example/ios/Flutter/Debug.xcconfig rename to packages/path_provider/path_provider/example/ios/Flutter/Debug.xcconfig diff --git a/packages/path_provider/example/ios/Flutter/Release.xcconfig b/packages/path_provider/path_provider/example/ios/Flutter/Release.xcconfig similarity index 100% rename from packages/path_provider/example/ios/Flutter/Release.xcconfig rename to packages/path_provider/path_provider/example/ios/Flutter/Release.xcconfig diff --git a/packages/path_provider/example/ios/Runner.xcodeproj/project.pbxproj b/packages/path_provider/path_provider/example/ios/Runner.xcodeproj/project.pbxproj similarity index 100% rename from packages/path_provider/example/ios/Runner.xcodeproj/project.pbxproj rename to packages/path_provider/path_provider/example/ios/Runner.xcodeproj/project.pbxproj diff --git a/packages/path_provider/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/path_provider/path_provider/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from packages/path_provider/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to packages/path_provider/path_provider/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/packages/path_provider/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/path_provider/path_provider/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme similarity index 100% rename from packages/path_provider/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme rename to packages/path_provider/path_provider/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme diff --git a/packages/path_provider/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/path_provider/path_provider/example/ios/Runner.xcworkspace/contents.xcworkspacedata similarity index 100% rename from packages/path_provider/example/ios/Runner.xcworkspace/contents.xcworkspacedata rename to packages/path_provider/path_provider/example/ios/Runner.xcworkspace/contents.xcworkspacedata diff --git a/packages/path_provider/example/ios/Runner/AppDelegate.h b/packages/path_provider/path_provider/example/ios/Runner/AppDelegate.h similarity index 100% rename from packages/path_provider/example/ios/Runner/AppDelegate.h rename to packages/path_provider/path_provider/example/ios/Runner/AppDelegate.h diff --git a/packages/path_provider/example/ios/Runner/AppDelegate.m b/packages/path_provider/path_provider/example/ios/Runner/AppDelegate.m similarity index 100% rename from packages/path_provider/example/ios/Runner/AppDelegate.m rename to packages/path_provider/path_provider/example/ios/Runner/AppDelegate.m diff --git a/packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json rename to packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png similarity index 100% rename from packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png rename to packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png diff --git a/packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png similarity index 100% rename from packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png rename to packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png diff --git a/packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png similarity index 100% rename from packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png rename to packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png diff --git a/packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png similarity index 100% rename from packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png rename to packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png diff --git a/packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png similarity index 100% rename from packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png rename to packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png diff --git a/packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png similarity index 100% rename from packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png rename to packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png diff --git a/packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png similarity index 100% rename from packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png rename to packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png diff --git a/packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png similarity index 100% rename from packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png rename to packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png diff --git a/packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png similarity index 100% rename from packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png rename to packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png diff --git a/packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png similarity index 100% rename from packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png rename to packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png diff --git a/packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png similarity index 100% rename from packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png rename to packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png diff --git a/packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png similarity index 100% rename from packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png rename to packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png diff --git a/packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png similarity index 100% rename from packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png rename to packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png diff --git a/packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png similarity index 100% rename from packages/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png rename to packages/path_provider/path_provider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png diff --git a/packages/path_provider/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/packages/path_provider/path_provider/example/ios/Runner/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from packages/path_provider/example/ios/Runner/Base.lproj/LaunchScreen.storyboard rename to packages/path_provider/path_provider/example/ios/Runner/Base.lproj/LaunchScreen.storyboard diff --git a/packages/path_provider/example/ios/Runner/Base.lproj/Main.storyboard b/packages/path_provider/path_provider/example/ios/Runner/Base.lproj/Main.storyboard similarity index 100% rename from packages/path_provider/example/ios/Runner/Base.lproj/Main.storyboard rename to packages/path_provider/path_provider/example/ios/Runner/Base.lproj/Main.storyboard diff --git a/packages/path_provider/example/ios/Runner/Info.plist b/packages/path_provider/path_provider/example/ios/Runner/Info.plist similarity index 100% rename from packages/path_provider/example/ios/Runner/Info.plist rename to packages/path_provider/path_provider/example/ios/Runner/Info.plist diff --git a/packages/path_provider/example/ios/Runner/main.m b/packages/path_provider/path_provider/example/ios/Runner/main.m similarity index 100% rename from packages/path_provider/example/ios/Runner/main.m rename to packages/path_provider/path_provider/example/ios/Runner/main.m diff --git a/packages/path_provider/example/lib/main.dart b/packages/path_provider/path_provider/example/lib/main.dart similarity index 100% rename from packages/path_provider/example/lib/main.dart rename to packages/path_provider/path_provider/example/lib/main.dart diff --git a/packages/path_provider/example/macos/Flutter/Flutter-Debug.xcconfig b/packages/path_provider/path_provider/example/macos/Flutter/Flutter-Debug.xcconfig similarity index 100% rename from packages/path_provider/example/macos/Flutter/Flutter-Debug.xcconfig rename to packages/path_provider/path_provider/example/macos/Flutter/Flutter-Debug.xcconfig diff --git a/packages/path_provider/example/macos/Flutter/Flutter-Release.xcconfig b/packages/path_provider/path_provider/example/macos/Flutter/Flutter-Release.xcconfig similarity index 100% rename from packages/path_provider/example/macos/Flutter/Flutter-Release.xcconfig rename to packages/path_provider/path_provider/example/macos/Flutter/Flutter-Release.xcconfig diff --git a/packages/path_provider/example/macos/Flutter/GeneratedPluginRegistrant.swift b/packages/path_provider/path_provider/example/macos/Flutter/GeneratedPluginRegistrant.swift similarity index 100% rename from packages/path_provider/example/macos/Flutter/GeneratedPluginRegistrant.swift rename to packages/path_provider/path_provider/example/macos/Flutter/GeneratedPluginRegistrant.swift diff --git a/packages/path_provider/example/macos/Runner.xcodeproj/project.pbxproj b/packages/path_provider/path_provider/example/macos/Runner.xcodeproj/project.pbxproj similarity index 100% rename from packages/path_provider/example/macos/Runner.xcodeproj/project.pbxproj rename to packages/path_provider/path_provider/example/macos/Runner.xcodeproj/project.pbxproj diff --git a/packages/path_provider/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/path_provider/path_provider/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme similarity index 100% rename from packages/path_provider/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme rename to packages/path_provider/path_provider/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme diff --git a/packages/path_provider/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/packages/path_provider/path_provider/example/macos/Runner.xcworkspace/contents.xcworkspacedata similarity index 100% rename from packages/path_provider/example/macos/Runner.xcworkspace/contents.xcworkspacedata rename to packages/path_provider/path_provider/example/macos/Runner.xcworkspace/contents.xcworkspacedata diff --git a/packages/path_provider/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/path_provider/path_provider/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from packages/path_provider/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to packages/path_provider/path_provider/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/packages/path_provider/example/macos/Runner/AppDelegate.swift b/packages/path_provider/path_provider/example/macos/Runner/AppDelegate.swift similarity index 100% rename from packages/path_provider/example/macos/Runner/AppDelegate.swift rename to packages/path_provider/path_provider/example/macos/Runner/AppDelegate.swift diff --git a/packages/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/path_provider/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from packages/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json rename to packages/path_provider/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/packages/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/packages/path_provider/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png similarity index 100% rename from packages/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png rename to packages/path_provider/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png diff --git a/packages/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/packages/path_provider/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png similarity index 100% rename from packages/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png rename to packages/path_provider/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png diff --git a/packages/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/packages/path_provider/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png similarity index 100% rename from packages/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png rename to packages/path_provider/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png diff --git a/packages/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/packages/path_provider/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png similarity index 100% rename from packages/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png rename to packages/path_provider/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png diff --git a/packages/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/packages/path_provider/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png similarity index 100% rename from packages/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png rename to packages/path_provider/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png diff --git a/packages/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/packages/path_provider/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png similarity index 100% rename from packages/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png rename to packages/path_provider/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png diff --git a/packages/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/packages/path_provider/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png similarity index 100% rename from packages/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png rename to packages/path_provider/path_provider/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png diff --git a/packages/path_provider/example/macos/Runner/Base.lproj/MainMenu.xib b/packages/path_provider/path_provider/example/macos/Runner/Base.lproj/MainMenu.xib similarity index 100% rename from packages/path_provider/example/macos/Runner/Base.lproj/MainMenu.xib rename to packages/path_provider/path_provider/example/macos/Runner/Base.lproj/MainMenu.xib diff --git a/packages/path_provider/example/macos/Runner/Configs/AppInfo.xcconfig b/packages/path_provider/path_provider/example/macos/Runner/Configs/AppInfo.xcconfig similarity index 100% rename from packages/path_provider/example/macos/Runner/Configs/AppInfo.xcconfig rename to packages/path_provider/path_provider/example/macos/Runner/Configs/AppInfo.xcconfig diff --git a/packages/path_provider/example/macos/Runner/Configs/Debug.xcconfig b/packages/path_provider/path_provider/example/macos/Runner/Configs/Debug.xcconfig similarity index 100% rename from packages/path_provider/example/macos/Runner/Configs/Debug.xcconfig rename to packages/path_provider/path_provider/example/macos/Runner/Configs/Debug.xcconfig diff --git a/packages/path_provider/example/macos/Runner/Configs/Release.xcconfig b/packages/path_provider/path_provider/example/macos/Runner/Configs/Release.xcconfig similarity index 100% rename from packages/path_provider/example/macos/Runner/Configs/Release.xcconfig rename to packages/path_provider/path_provider/example/macos/Runner/Configs/Release.xcconfig diff --git a/packages/path_provider/example/macos/Runner/Configs/Warnings.xcconfig b/packages/path_provider/path_provider/example/macos/Runner/Configs/Warnings.xcconfig similarity index 100% rename from packages/path_provider/example/macos/Runner/Configs/Warnings.xcconfig rename to packages/path_provider/path_provider/example/macos/Runner/Configs/Warnings.xcconfig diff --git a/packages/path_provider/example/macos/Runner/DebugProfile.entitlements b/packages/path_provider/path_provider/example/macos/Runner/DebugProfile.entitlements similarity index 100% rename from packages/path_provider/example/macos/Runner/DebugProfile.entitlements rename to packages/path_provider/path_provider/example/macos/Runner/DebugProfile.entitlements diff --git a/packages/path_provider/example/macos/Runner/Info.plist b/packages/path_provider/path_provider/example/macos/Runner/Info.plist similarity index 100% rename from packages/path_provider/example/macos/Runner/Info.plist rename to packages/path_provider/path_provider/example/macos/Runner/Info.plist diff --git a/packages/path_provider/example/macos/Runner/MainFlutterWindow.swift b/packages/path_provider/path_provider/example/macos/Runner/MainFlutterWindow.swift similarity index 100% rename from packages/path_provider/example/macos/Runner/MainFlutterWindow.swift rename to packages/path_provider/path_provider/example/macos/Runner/MainFlutterWindow.swift diff --git a/packages/path_provider/example/macos/Runner/Release.entitlements b/packages/path_provider/path_provider/example/macos/Runner/Release.entitlements similarity index 100% rename from packages/path_provider/example/macos/Runner/Release.entitlements rename to packages/path_provider/path_provider/example/macos/Runner/Release.entitlements diff --git a/packages/path_provider/example/pubspec.yaml b/packages/path_provider/path_provider/example/pubspec.yaml similarity index 90% rename from packages/path_provider/example/pubspec.yaml rename to packages/path_provider/path_provider/example/pubspec.yaml index fd4c24e51288..a82bc6e121a5 100644 --- a/packages/path_provider/example/pubspec.yaml +++ b/packages/path_provider/path_provider/example/pubspec.yaml @@ -7,7 +7,7 @@ dependencies: path_provider: path: ../ path_provider_macos: - path: ../path_provider_macos + path: ../../path_provider_macos dev_dependencies: e2e: ^0.2.1 diff --git a/packages/path_provider/example/test_driver/path_provider_e2e.dart b/packages/path_provider/path_provider/example/test_driver/path_provider_e2e.dart similarity index 100% rename from packages/path_provider/example/test_driver/path_provider_e2e.dart rename to packages/path_provider/path_provider/example/test_driver/path_provider_e2e.dart diff --git a/packages/path_provider/example/test_driver/path_provider_e2e_test.dart b/packages/path_provider/path_provider/example/test_driver/path_provider_e2e_test.dart similarity index 100% rename from packages/path_provider/example/test_driver/path_provider_e2e_test.dart rename to packages/path_provider/path_provider/example/test_driver/path_provider_e2e_test.dart diff --git a/packages/path_provider/ios/Assets/.gitkeep b/packages/path_provider/path_provider/ios/Assets/.gitkeep similarity index 100% rename from packages/path_provider/ios/Assets/.gitkeep rename to packages/path_provider/path_provider/ios/Assets/.gitkeep diff --git a/packages/path_provider/ios/Classes/FLTPathProviderPlugin.h b/packages/path_provider/path_provider/ios/Classes/FLTPathProviderPlugin.h similarity index 100% rename from packages/path_provider/ios/Classes/FLTPathProviderPlugin.h rename to packages/path_provider/path_provider/ios/Classes/FLTPathProviderPlugin.h diff --git a/packages/path_provider/ios/Classes/FLTPathProviderPlugin.m b/packages/path_provider/path_provider/ios/Classes/FLTPathProviderPlugin.m similarity index 100% rename from packages/path_provider/ios/Classes/FLTPathProviderPlugin.m rename to packages/path_provider/path_provider/ios/Classes/FLTPathProviderPlugin.m diff --git a/packages/path_provider/ios/path_provider.podspec b/packages/path_provider/path_provider/ios/path_provider.podspec similarity index 100% rename from packages/path_provider/ios/path_provider.podspec rename to packages/path_provider/path_provider/ios/path_provider.podspec diff --git a/packages/path_provider/lib/path_provider.dart b/packages/path_provider/path_provider/lib/path_provider.dart similarity index 100% rename from packages/path_provider/lib/path_provider.dart rename to packages/path_provider/path_provider/lib/path_provider.dart diff --git a/packages/path_provider/pubspec.yaml b/packages/path_provider/path_provider/pubspec.yaml similarity index 94% rename from packages/path_provider/pubspec.yaml rename to packages/path_provider/path_provider/pubspec.yaml index 0b394514143e..df26c5e06899 100644 --- a/packages/path_provider/pubspec.yaml +++ b/packages/path_provider/path_provider/pubspec.yaml @@ -1,8 +1,8 @@ name: path_provider description: Flutter plugin for getting commonly used locations on the Android & iOS file systems, such as the temp and app data directories. -homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider -version: 1.6.1 +homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider +version: 1.6.2 flutter: plugin: diff --git a/packages/path_provider/test/path_provider_e2e.dart b/packages/path_provider/path_provider/test/path_provider_e2e.dart similarity index 100% rename from packages/path_provider/test/path_provider_e2e.dart rename to packages/path_provider/path_provider/test/path_provider_e2e.dart diff --git a/packages/path_provider/test/path_provider_test.dart b/packages/path_provider/path_provider/test/path_provider_test.dart similarity index 100% rename from packages/path_provider/test/path_provider_test.dart rename to packages/path_provider/path_provider/test/path_provider_test.dart diff --git a/packages/path_provider/path_provider_macos/lib/path_provider_macos.dart b/packages/path_provider/path_provider_macos/lib/path_provider_macos.dart new file mode 100644 index 000000000000..cf440b2858af --- /dev/null +++ b/packages/path_provider/path_provider_macos/lib/path_provider_macos.dart @@ -0,0 +1,3 @@ +// Analyze will fail if there is no main.dart file. This file should +// be removed once an example app has been added to path_provider_macos. +// https://github.com/flutter/flutter/issues/51007 From df0c291b449e1ef2b581ea9734b92cabf2732b91 Mon Sep 17 00:00:00 2001 From: Francisco Magdaleno Date: Tue, 25 Feb 2020 21:56:14 -0800 Subject: [PATCH 04/37] [path_provider] Create platform interface (#2553) --- .../CHANGELOG.md | 3 + .../path_provider_platform_interface/LICENSE | 27 +++ .../README.md | 26 +++ .../lib/path_provider_platform_interface.dart | 101 +++++++++ .../lib/src/enums.dart | 49 +++++ .../lib/src/method_channel_path_provider.dart | 86 ++++++++ .../pubspec.yaml | 23 ++ .../method_channel_path_provider_test.dart | 204 ++++++++++++++++++ 8 files changed, 519 insertions(+) create mode 100644 packages/path_provider/path_provider_platform_interface/CHANGELOG.md create mode 100644 packages/path_provider/path_provider_platform_interface/LICENSE create mode 100644 packages/path_provider/path_provider_platform_interface/README.md create mode 100644 packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart create mode 100644 packages/path_provider/path_provider_platform_interface/lib/src/enums.dart create mode 100644 packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart create mode 100644 packages/path_provider/path_provider_platform_interface/pubspec.yaml create mode 100644 packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart diff --git a/packages/path_provider/path_provider_platform_interface/CHANGELOG.md b/packages/path_provider/path_provider_platform_interface/CHANGELOG.md new file mode 100644 index 000000000000..0d8803f93540 --- /dev/null +++ b/packages/path_provider/path_provider_platform_interface/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.0 + +* Initial release. diff --git a/packages/path_provider/path_provider_platform_interface/LICENSE b/packages/path_provider/path_provider_platform_interface/LICENSE new file mode 100644 index 000000000000..0c91662b3f2f --- /dev/null +++ b/packages/path_provider/path_provider_platform_interface/LICENSE @@ -0,0 +1,27 @@ +// Copyright 2020 The Chromium 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/path_provider/path_provider_platform_interface/README.md b/packages/path_provider/path_provider_platform_interface/README.md new file mode 100644 index 000000000000..50035db91482 --- /dev/null +++ b/packages/path_provider/path_provider_platform_interface/README.md @@ -0,0 +1,26 @@ +# path_provider_platform_interface + +A common platform interface for the [`path_provider`][1] plugin. + +This interface allows platform-specific implementations of the `path_provider` +plugin, as well as the plugin itself, to ensure they are supporting the +same interface. + +# Usage + +To implement a new platform-specific implementation of `path_provider`, extend +[`PathProviderPlatform`][2] with an implementation that performs the +platform-specific behavior, and when you register your plugin, set the default +`PathProviderPlatform` by calling +`PathProviderPlatform.instance = MyPlatformPathProvider()`. + +# 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]: ../ +[2]: lib/path_provider_platform_interface.dart diff --git a/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart b/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart new file mode 100644 index 000000000000..72aadf35b3e8 --- /dev/null +++ b/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart @@ -0,0 +1,101 @@ +// Copyright 2020 The Chromium 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 'src/enums.dart'; +import 'src/method_channel_path_provider.dart'; + +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +export 'src/enums.dart'; + +/// The interface that implementations of path_provider must implement. +/// +/// Platform implementations should extend this class rather than implement it as `PathProvider` +/// 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 +/// [PathProviderPlatform] methods. +abstract class PathProviderPlatform extends PlatformInterface { + /// Constructs a PathProviderPlatform. + PathProviderPlatform() : super(token: _token); + + static final Object _token = Object(); + + static PathProviderPlatform _instance = MethodChannelPathProvider(); + + /// The default instance of [PathProviderPlatform] to use. + /// + /// Defaults to [MethodChannelPathProvider]. + static PathProviderPlatform get instance => _instance; + + /// Platform-specific plugins should set this with their own platform-specific + /// class that extends [PathProviderPlatform] when they register themselves. + static set instance(PathProviderPlatform instance) { + PlatformInterface.verifyToken(instance, _token); + _instance = instance; + } + + /// Path to the temporary directory on the device that is not backed up and is + /// suitable for storing caches of downloaded files. + Future getTemporaryPath() { + throw UnimplementedError('getTemporaryPath() has not been implemented.'); + } + + /// Path to a directory where the application may place application support + /// files. + Future getApplicationSupportPath() { + throw UnimplementedError( + 'getApplicationSupportPath() has not been implemented.'); + } + + /// Path to the directory where application can store files that are persistent, + /// backed up, and not visible to the user, such as sqlite.db. + Future getLibraryPath() { + throw UnimplementedError('getLibraryPath() has not been implemented.'); + } + + /// Path to a directory where the application may place data that is + /// user-generated, or that cannot otherwise be recreated by your application. + Future getApplicationDocumentsPath() { + throw UnimplementedError( + 'getApplicationDocumentsPath() has not been implemented.'); + } + + /// Path to a directory where the application may access top level storage. + /// The current operating system should be determined before issuing this + /// function call, as this functionality is only available on Android. + Future getExternalStoragePath() { + throw UnimplementedError( + 'getExternalStoragePath() has not been implemented.'); + } + + /// Paths to directories where application specific external cache data can be + /// stored. These paths typically reside on external storage like separate + /// partitions or SD cards. Phones may have multiple storage directories + /// available. + Future> getExternalCachePaths() { + throw UnimplementedError( + 'getExternalCachePaths() has not been implemented.'); + } + + /// Paths to directories where application specific data can be stored. + /// These paths typically reside on external storage like separate partitions + /// or SD cards. Phones may have multiple storage directories available. + Future> getExternalStoragePaths({ + /// Optional parameter. See [AndroidStorageDirectory] for more informations on + /// how this type translates to Android storage directories. + AndroidStorageDirectory type, + }) { + throw UnimplementedError( + 'getExternalStoragePaths() has not been implemented.'); + } + + /// Path to the directory where downloaded files can be stored. + /// This is typically only relevant on desktop operating systems. + Future getDownloadsPath() { + throw UnimplementedError('getDownloadsPath() has not been implemented.'); + } +} diff --git a/packages/path_provider/path_provider_platform_interface/lib/src/enums.dart b/packages/path_provider/path_provider_platform_interface/lib/src/enums.dart new file mode 100644 index 000000000000..cf04a164203f --- /dev/null +++ b/packages/path_provider/path_provider_platform_interface/lib/src/enums.dart @@ -0,0 +1,49 @@ +/// Corresponds to constants defined in Androids `android.os.Environment` class. +/// +/// https://developer.android.com/reference/android/os/Environment.html#fields_1 +enum AndroidStorageDirectory { + /// Contains audio files that should be treated as music. + /// + /// See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_MUSIC. + music, + + /// Contains audio files that should be treated as podcasts. + /// + /// See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_PODCASTS. + podcasts, + + /// Contains audio files that should be treated as ringtones. + /// + /// See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_RINGTONES. + ringtones, + + /// Contains audio files that should be treated as alarm sounds. + /// + /// See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_ALARMS. + alarms, + + /// Contains audio files that should be treated as notification sounds. + /// + /// See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_NOTIFICATIONS. + notifications, + + /// Contains images. See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_PICTURES. + pictures, + + /// Contains movies. See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_MOVIES. + movies, + + /// Contains files of any type that have been downloaded by the user. + /// + /// See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_DOWNLOADS. + downloads, + + /// Used to hold both pictures and videos when the device filesystem is + /// treated like a camera's. + /// + /// See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_DCIM. + dcim, + + /// Holds user-created documents. See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_DOCUMENTS. + documents, +} diff --git a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart new file mode 100644 index 000000000000..acac9d5fe7af --- /dev/null +++ b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart @@ -0,0 +1,86 @@ +// Copyright 2020 The Chromium 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 'enums.dart'; + +import 'package:flutter/services.dart'; +import 'package:meta/meta.dart'; +import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; +import 'package:platform/platform.dart'; + +/// An implementation of [PathProviderPlatform] that uses method channels. +class MethodChannelPathProvider extends PathProviderPlatform { + /// The method channel used to interact with the native platform. + @visibleForTesting + MethodChannel methodChannel = + MethodChannel('plugins.flutter.io/path_provider'); + + // Ideally, this property shouldn't exist, and each platform should + // just implement the supported methods. Once all the platforms are + // federated, this property should be removed. + Platform _platform = const LocalPlatform(); + + /// This API is only exposed for the unit tests. It should not be used by + /// any code outside of the plugin itself. + @visibleForTesting + void setMockPathProviderPlatform(Platform platform) { + _platform = platform; + } + + Future getTemporaryPath() { + return methodChannel.invokeMethod('getTemporaryDirectory'); + } + + Future getApplicationSupportPath() { + return methodChannel.invokeMethod('getApplicationSupportDirectory'); + } + + Future getLibraryPath() { + if (!_platform.isIOS && !_platform.isMacOS) { + throw UnsupportedError('Functionality only available on iOS/macOS'); + } + return methodChannel.invokeMethod('getLibraryDirectory'); + } + + Future getApplicationDocumentsPath() { + return methodChannel + .invokeMethod('getApplicationDocumentsDirectory'); + } + + Future getExternalStoragePath() { + if (!_platform.isAndroid) { + throw UnsupportedError('Functionality only available on Android'); + } + return methodChannel.invokeMethod('getStorageDirectory'); + } + + Future> getExternalCachePaths() { + if (!_platform.isAndroid) { + throw UnsupportedError('Functionality only available on Android'); + } + return methodChannel + .invokeListMethod('getExternalCacheDirectories'); + } + + Future> getExternalStoragePaths({ + AndroidStorageDirectory type, + }) async { + if (!_platform.isAndroid) { + throw UnsupportedError('Functionality only available on Android'); + } + return methodChannel.invokeListMethod( + 'getExternalStorageDirectories', + {'type': type?.index}, + ); + } + + Future getDownloadsPath() { + if (!_platform.isMacOS) { + throw UnsupportedError('Functionality only available on macOS'); + } + return methodChannel.invokeMethod('getDownloadsDirectory'); + } +} diff --git a/packages/path_provider/path_provider_platform_interface/pubspec.yaml b/packages/path_provider/path_provider_platform_interface/pubspec.yaml new file mode 100644 index 000000000000..44bc0c2c161c --- /dev/null +++ b/packages/path_provider/path_provider_platform_interface/pubspec.yaml @@ -0,0 +1,23 @@ +name: path_provider_platform_interface +description: A common platform interface for the path_provider plugin. +homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_platform_interface +# 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 + +dependencies: + flutter: + sdk: flutter + meta: ^1.0.5 + platform: ^2.0.0 + plugin_platform_interface: ^1.0.1 + +dev_dependencies: + flutter_test: + sdk: flutter + pedantic: ^1.8.0 + test: any + +environment: + sdk: ">=2.0.0-dev.28.0 <3.0.0" + flutter: ">=1.10.0 <2.0.0" diff --git a/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart b/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart new file mode 100644 index 000000000000..c21acdb140b6 --- /dev/null +++ b/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart @@ -0,0 +1,204 @@ +// Copyright 2020 The Chromium 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:flutter_test/flutter_test.dart'; +import 'package:path_provider_platform_interface/src/enums.dart'; +import 'package:path_provider_platform_interface/src/method_channel_path_provider.dart'; +import 'package:platform/platform.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + const String kTemporaryPath = 'temporaryPath'; + const String kApplicationSupportPath = 'applicationSupportPath'; + const String kLibraryPath = 'libraryPath'; + const String kApplicationDocumentsPath = 'applicationDocumentsPath'; + const String kExternalCachePaths = 'externalCachePaths'; + const String kExternalStoragePaths = 'externalStoragePaths'; + const String kDownloadsPath = 'downloadsPath'; + + group('$MethodChannelPathProvider', () { + MethodChannelPathProvider methodChannelPathProvider; + final List log = []; + + setUp(() async { + methodChannelPathProvider = MethodChannelPathProvider(); + + methodChannelPathProvider.methodChannel + .setMockMethodCallHandler((MethodCall methodCall) async { + log.add(methodCall); + switch (methodCall.method) { + case 'getTemporaryDirectory': + return kTemporaryPath; + case 'getApplicationSupportDirectory': + return kApplicationSupportPath; + case 'getLibraryDirectory': + return kLibraryPath; + case 'getApplicationDocumentsDirectory': + return kApplicationDocumentsPath; + case 'getExternalStorageDirectories': + return [kExternalStoragePaths]; + case 'getExternalCacheDirectories': + return [kExternalCachePaths]; + case 'getDownloadsDirectory': + return kDownloadsPath; + default: + return null; + } + }); + }); + + setUp(() { + methodChannelPathProvider.setMockPathProviderPlatform( + FakePlatform(operatingSystem: 'android')); + }); + + tearDown(() { + log.clear(); + }); + + test('getTemporaryPath', () async { + final String path = await methodChannelPathProvider.getTemporaryPath(); + expect( + log, + [isMethodCall('getTemporaryDirectory', arguments: null)], + ); + expect(path, kTemporaryPath); + }); + + test('getApplicationSupportPath', () async { + final String path = + await methodChannelPathProvider.getApplicationSupportPath(); + expect( + log, + [ + isMethodCall('getApplicationSupportDirectory', arguments: null) + ], + ); + expect(path, kApplicationSupportPath); + }); + + test('getLibraryPath android fails', () async { + try { + await methodChannelPathProvider.getLibraryPath(); + fail('should throw UnsupportedError'); + } catch (e) { + expect(e, isUnsupportedError); + } + }); + + test('getLibraryPath iOS succeeds', () async { + methodChannelPathProvider + .setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); + + final String path = await methodChannelPathProvider.getLibraryPath(); + expect( + log, + [isMethodCall('getLibraryDirectory', arguments: null)], + ); + expect(path, kLibraryPath); + }); + + test('getLibraryPath macOS succeeds', () async { + methodChannelPathProvider + .setMockPathProviderPlatform(FakePlatform(operatingSystem: 'macos')); + + final String path = await methodChannelPathProvider.getLibraryPath(); + expect( + log, + [isMethodCall('getLibraryDirectory', arguments: null)], + ); + expect(path, kLibraryPath); + }); + + test('getApplicationDocumentsPath', () async { + final String path = + await methodChannelPathProvider.getApplicationDocumentsPath(); + expect( + log, + [ + isMethodCall('getApplicationDocumentsDirectory', arguments: null) + ], + ); + expect(path, kApplicationDocumentsPath); + }); + + test('getExternalCachePaths android succeeds', () async { + final List result = + await methodChannelPathProvider.getExternalCachePaths(); + expect( + log, + [isMethodCall('getExternalCacheDirectories', arguments: null)], + ); + expect(result.length, 1); + expect(result.first, kExternalCachePaths); + }); + + test('getExternalCachePaths non-android fails', () async { + methodChannelPathProvider + .setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); + + try { + await methodChannelPathProvider.getExternalCachePaths(); + fail('should throw UnsupportedError'); + } catch (e) { + expect(e, isUnsupportedError); + } + }); + + for (AndroidStorageDirectory type + in AndroidStorageDirectory.values + [null]) { + test('getExternalStoragePaths (type: $type) android succeeds', () async { + final List result = + await methodChannelPathProvider.getExternalStoragePaths(type: type); + expect( + log, + [ + isMethodCall( + 'getExternalStorageDirectories', + arguments: {'type': type?.index}, + ) + ], + ); + + expect(result.length, 1); + expect(result.first, kExternalStoragePaths); + }); + + test('getExternalStoragePaths (type: $type) non-android fails', () async { + methodChannelPathProvider + .setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); + + try { + await methodChannelPathProvider.getExternalStoragePaths(); + fail('should throw UnsupportedError'); + } catch (e) { + expect(e, isUnsupportedError); + } + }); + } // end of for-loop + + test('getDownloadsPath macos succeeds', () async { + methodChannelPathProvider + .setMockPathProviderPlatform(FakePlatform(operatingSystem: 'macos')); + final String result = await methodChannelPathProvider.getDownloadsPath(); + expect( + log, + [isMethodCall('getDownloadsDirectory', arguments: null)], + ); + expect(result, kDownloadsPath); + }); + + test('getDownloadsPath non-macos fails', () async { + methodChannelPathProvider.setMockPathProviderPlatform( + FakePlatform(operatingSystem: 'android')); + try { + await methodChannelPathProvider.getDownloadsPath(); + fail('should throw UnsupportedError'); + } catch (e) { + expect(e, isUnsupportedError); + } + }); + }); +} From fcd0f45d17a09b7d4f288ff01013dbd060276a11 Mon Sep 17 00:00:00 2001 From: Francisco Magdaleno Date: Wed, 26 Feb 2020 16:06:06 -0800 Subject: [PATCH 05/37] Exclude path_provider packages (#2558) * Exclude path_provider * Add web --- script/build_all_plugins_app.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/script/build_all_plugins_app.sh b/script/build_all_plugins_app.sh index a497cd935d81..378deb71f56b 100755 --- a/script/build_all_plugins_app.sh +++ b/script/build_all_plugins_app.sh @@ -18,6 +18,9 @@ readonly EXCLUDED_PLUGINS_LIST=( "google_sign_in_platform_interface" "google_sign_in_web" "instrumentation_adapter" + "path_provider_macos" + "path_provider_platform_interface" + "path_provider_web" "plugin_platform_interface" "shared_preferences_macos" "shared_preferences_platform_interface" From 71d5b15d04f02c0aaf53c197efe75f78fd9d9ffb Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Wed, 26 Feb 2020 17:01:00 -0800 Subject: [PATCH 06/37] [connectivity_platform_interface] Add `ConnectivityResult.unknown`. (#2560) Some platforms might not be able to determine the connectivity status of the device on which the app is running (like some desktop Web browsers). This allows users of the `connectivity` plugin to distinguish between "no connectivity" and "connectivity couldn't be determined". This requires a Major Version bump for users of the plugin who may be switch/case on ConnectivityResult values, since Dart forces users to be exhaustive in those cases (if they don't have a "default" entry, this new value becomes a compilation error in their code). This will also cause a Major Version bump in the core `connectivity` plugin itself. Note that by default, the ConnectivityResults returned by the MethodChannel implementation will now default to 'unknown' if they're not explicitly "none", so this might have some effect in your code! --- .../connectivity_platform_interface/CHANGELOG.md | 5 +++++ .../connectivity_platform_interface/lib/src/enums.dart | 5 ++++- .../connectivity_platform_interface/lib/src/utils.dart | 3 ++- .../connectivity_platform_interface/pubspec.yaml | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/connectivity/connectivity_platform_interface/CHANGELOG.md b/packages/connectivity/connectivity_platform_interface/CHANGELOG.md index d249985c65f4..3766106f9b0b 100644 --- a/packages/connectivity/connectivity_platform_interface/CHANGELOG.md +++ b/packages/connectivity/connectivity_platform_interface/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.0.0 + +* Added `ConnectivityResult.unknown`, for the cases where the plugin is unable to determine the +connectivity status of the device. _(This happens mostly in the `web` platform.)_ + ## 1.0.3 * Make the pedantic dev_dependency explicit. diff --git a/packages/connectivity/connectivity_platform_interface/lib/src/enums.dart b/packages/connectivity/connectivity_platform_interface/lib/src/enums.dart index 9d8cef9e1a66..a2d5f8d10f10 100644 --- a/packages/connectivity/connectivity_platform_interface/lib/src/enums.dart +++ b/packages/connectivity/connectivity_platform_interface/lib/src/enums.dart @@ -7,7 +7,10 @@ enum ConnectivityResult { mobile, /// None: Device not connected to any network - none + none, + + /// Unknown: The plugin wasn't able to determine the connectivity status of the device + unknown, } /// The status of the location service authorization. diff --git a/packages/connectivity/connectivity_platform_interface/lib/src/utils.dart b/packages/connectivity/connectivity_platform_interface/lib/src/utils.dart index 2ae22e1c9fc3..ae412e89c7c9 100644 --- a/packages/connectivity/connectivity_platform_interface/lib/src/utils.dart +++ b/packages/connectivity/connectivity_platform_interface/lib/src/utils.dart @@ -8,8 +8,9 @@ ConnectivityResult parseConnectivityResult(String state) { case 'mobile': return ConnectivityResult.mobile; case 'none': - default: return ConnectivityResult.none; + default: + return ConnectivityResult.unknown; } } diff --git a/packages/connectivity/connectivity_platform_interface/pubspec.yaml b/packages/connectivity/connectivity_platform_interface/pubspec.yaml index 78f9473c4452..489515cebc51 100644 --- a/packages/connectivity/connectivity_platform_interface/pubspec.yaml +++ b/packages/connectivity/connectivity_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the connectivity plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_platform_interface # 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.3 +version: 2.0.0 dependencies: flutter: From 9cc8ac16cbbd8fb6b2a8cdafc34ebbd53c80cdbd Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Thu, 27 Feb 2020 11:29:25 -0800 Subject: [PATCH 07/37] Revert "[connectivity_platform_interface] Add `ConnectivityResult.unknown`." (#2561) The previous push introduced a new major version into the connectivity_platform_interface package. That might not be the best approach. The new version has been unpublished from pub.dev, and this change restores the repo to its previous state. This reverts commit 4411247270069e8b4d4969652b6c2d1d9b694d82. --- .../connectivity_platform_interface/CHANGELOG.md | 5 ----- .../connectivity_platform_interface/lib/src/enums.dart | 5 +---- .../connectivity_platform_interface/lib/src/utils.dart | 3 +-- .../connectivity_platform_interface/pubspec.yaml | 2 +- 4 files changed, 3 insertions(+), 12 deletions(-) diff --git a/packages/connectivity/connectivity_platform_interface/CHANGELOG.md b/packages/connectivity/connectivity_platform_interface/CHANGELOG.md index 3766106f9b0b..d249985c65f4 100644 --- a/packages/connectivity/connectivity_platform_interface/CHANGELOG.md +++ b/packages/connectivity/connectivity_platform_interface/CHANGELOG.md @@ -1,8 +1,3 @@ -## 2.0.0 - -* Added `ConnectivityResult.unknown`, for the cases where the plugin is unable to determine the -connectivity status of the device. _(This happens mostly in the `web` platform.)_ - ## 1.0.3 * Make the pedantic dev_dependency explicit. diff --git a/packages/connectivity/connectivity_platform_interface/lib/src/enums.dart b/packages/connectivity/connectivity_platform_interface/lib/src/enums.dart index a2d5f8d10f10..9d8cef9e1a66 100644 --- a/packages/connectivity/connectivity_platform_interface/lib/src/enums.dart +++ b/packages/connectivity/connectivity_platform_interface/lib/src/enums.dart @@ -7,10 +7,7 @@ enum ConnectivityResult { mobile, /// None: Device not connected to any network - none, - - /// Unknown: The plugin wasn't able to determine the connectivity status of the device - unknown, + none } /// The status of the location service authorization. diff --git a/packages/connectivity/connectivity_platform_interface/lib/src/utils.dart b/packages/connectivity/connectivity_platform_interface/lib/src/utils.dart index ae412e89c7c9..2ae22e1c9fc3 100644 --- a/packages/connectivity/connectivity_platform_interface/lib/src/utils.dart +++ b/packages/connectivity/connectivity_platform_interface/lib/src/utils.dart @@ -8,9 +8,8 @@ ConnectivityResult parseConnectivityResult(String state) { case 'mobile': return ConnectivityResult.mobile; case 'none': - return ConnectivityResult.none; default: - return ConnectivityResult.unknown; + return ConnectivityResult.none; } } diff --git a/packages/connectivity/connectivity_platform_interface/pubspec.yaml b/packages/connectivity/connectivity_platform_interface/pubspec.yaml index 489515cebc51..78f9473c4452 100644 --- a/packages/connectivity/connectivity_platform_interface/pubspec.yaml +++ b/packages/connectivity/connectivity_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the connectivity plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_platform_interface # 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: 2.0.0 +version: 1.0.3 dependencies: flutter: From 82f9a8594b977fd1740d0469b728c451d3259150 Mon Sep 17 00:00:00 2001 From: Francisco Magdaleno Date: Thu, 27 Feb 2020 13:30:04 -0800 Subject: [PATCH 08/37] [path_provider_macos] Adds example app (#2559) * Add macos exmaple * Update version * Fix analyzer * Fix * space * Remove tests * Address comment * Remove show * Import * Add platform * Use right import --- .../path_provider_macos/CHANGELOG.md | 4 + .../path_provider_macos/example/README.md | 8 + .../example/android/app/build.gradle | 64 ++ .../gradle/wrapper/gradle-wrapper.properties | 5 + .../java/EmbeddingV1ActivityTest.java | 15 + .../androidTest/java/MainActivityTest.java | 13 + .../android/app/src/main/AndroidManifest.xml | 25 + .../EmbeddingV1Activity.java | 14 + .../pathproviderexample/MainActivity.java | 19 + .../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 | 5 + .../example/android/settings.gradle | 15 + .../ios/Flutter/AppFrameworkInfo.plist | 30 + .../example/ios/Flutter/Debug.xcconfig | 2 + .../example/ios/Flutter/Release.xcconfig | 2 + .../ios/Runner.xcodeproj/project.pbxproj | 490 +++++++++++++ .../contents.xcworkspacedata | 10 + .../xcshareddata/xcschemes/Runner.xcscheme | 87 +++ .../contents.xcworkspacedata | 10 + .../example/ios/Runner/AppDelegate.h | 10 + .../example/ios/Runner/AppDelegate.m | 16 + .../AppIcon.appiconset/Contents.json | 116 ++++ .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 0 -> 564 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 0 -> 1283 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 0 -> 1588 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 0 -> 1025 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 0 -> 1716 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 0 -> 1920 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 0 -> 1283 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 0 -> 1895 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 0 -> 2665 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 0 -> 2665 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 0 -> 3831 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 0 -> 1888 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 0 -> 3294 bytes .../Icon-App-83.5x83.5@2x.png | Bin 0 -> 3612 bytes .../Runner/Base.lproj/LaunchScreen.storyboard | 27 + .../ios/Runner/Base.lproj/Main.storyboard | 26 + .../example/ios/Runner/Info.plist | 49 ++ .../example/ios/Runner/main.m | 13 + .../path_provider_macos/example/lib/main.dart | 149 ++++ .../macos/Flutter/Flutter-Debug.xcconfig | 2 + .../macos/Flutter/Flutter-Release.xcconfig | 2 + .../macos/Runner.xcodeproj/project.pbxproj | 654 ++++++++++++++++++ .../xcshareddata/xcschemes/Runner.xcscheme | 101 +++ .../contents.xcworkspacedata | 10 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../example/macos/Runner/AppDelegate.swift | 9 + .../AppIcon.appiconset/Contents.json | 68 ++ .../AppIcon.appiconset/app_icon_1024.png | Bin 0 -> 46993 bytes .../AppIcon.appiconset/app_icon_128.png | Bin 0 -> 3276 bytes .../AppIcon.appiconset/app_icon_16.png | Bin 0 -> 1429 bytes .../AppIcon.appiconset/app_icon_256.png | Bin 0 -> 5933 bytes .../AppIcon.appiconset/app_icon_32.png | Bin 0 -> 1243 bytes .../AppIcon.appiconset/app_icon_512.png | Bin 0 -> 14800 bytes .../AppIcon.appiconset/app_icon_64.png | Bin 0 -> 1874 bytes .../macos/Runner/Base.lproj/MainMenu.xib | 339 +++++++++ .../macos/Runner/Configs/AppInfo.xcconfig | 14 + .../macos/Runner/Configs/Debug.xcconfig | 2 + .../macos/Runner/Configs/Release.xcconfig | 2 + .../macos/Runner/Configs/Warnings.xcconfig | 13 + .../macos/Runner/DebugProfile.entitlements | 12 + .../example/macos/Runner/Info.plist | 32 + .../macos/Runner/MainFlutterWindow.swift | 15 + .../example/macos/Runner/Release.entitlements | 8 + .../path_provider_macos/example/pubspec.yaml | 19 + .../test_driver/path_provider_e2e.dart | 51 ++ .../test_driver/path_provider_e2e_test.dart | 15 + .../path_provider_macos/pubspec.yaml | 4 +- 75 files changed, 2635 insertions(+), 2 deletions(-) create mode 100644 packages/path_provider/path_provider_macos/example/README.md create mode 100644 packages/path_provider/path_provider_macos/example/android/app/build.gradle create mode 100644 packages/path_provider/path_provider_macos/example/android/app/gradle/wrapper/gradle-wrapper.properties create mode 100644 packages/path_provider/path_provider_macos/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java create mode 100644 packages/path_provider/path_provider_macos/example/android/app/src/androidTest/java/MainActivityTest.java create mode 100644 packages/path_provider/path_provider_macos/example/android/app/src/main/AndroidManifest.xml create mode 100644 packages/path_provider/path_provider_macos/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/EmbeddingV1Activity.java create mode 100644 packages/path_provider/path_provider_macos/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/MainActivity.java create mode 100644 packages/path_provider/path_provider_macos/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 packages/path_provider/path_provider_macos/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 packages/path_provider/path_provider_macos/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 packages/path_provider/path_provider_macos/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 packages/path_provider/path_provider_macos/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 packages/path_provider/path_provider_macos/example/android/build.gradle create mode 100644 packages/path_provider/path_provider_macos/example/android/gradle.properties create mode 100644 packages/path_provider/path_provider_macos/example/android/gradle/wrapper/gradle-wrapper.properties create mode 100644 packages/path_provider/path_provider_macos/example/android/settings.gradle create mode 100644 packages/path_provider/path_provider_macos/example/ios/Flutter/AppFrameworkInfo.plist create mode 100644 packages/path_provider/path_provider_macos/example/ios/Flutter/Debug.xcconfig create mode 100644 packages/path_provider/path_provider_macos/example/ios/Flutter/Release.xcconfig create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/project.pbxproj create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/AppDelegate.h create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/AppDelegate.m create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Base.lproj/LaunchScreen.storyboard create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Base.lproj/Main.storyboard create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/Info.plist create mode 100644 packages/path_provider/path_provider_macos/example/ios/Runner/main.m create mode 100644 packages/path_provider/path_provider_macos/example/lib/main.dart create mode 100644 packages/path_provider/path_provider_macos/example/macos/Flutter/Flutter-Debug.xcconfig create mode 100644 packages/path_provider/path_provider_macos/example/macos/Flutter/Flutter-Release.xcconfig create mode 100644 packages/path_provider/path_provider_macos/example/macos/Runner.xcodeproj/project.pbxproj create mode 100644 packages/path_provider/path_provider_macos/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme create mode 100644 packages/path_provider/path_provider_macos/example/macos/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 packages/path_provider/path_provider_macos/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 packages/path_provider/path_provider_macos/example/macos/Runner/AppDelegate.swift create mode 100644 packages/path_provider/path_provider_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 packages/path_provider/path_provider_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png create mode 100644 packages/path_provider/path_provider_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png create mode 100644 packages/path_provider/path_provider_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png create mode 100644 packages/path_provider/path_provider_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png create mode 100644 packages/path_provider/path_provider_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png create mode 100644 packages/path_provider/path_provider_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png create mode 100644 packages/path_provider/path_provider_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png create mode 100644 packages/path_provider/path_provider_macos/example/macos/Runner/Base.lproj/MainMenu.xib create mode 100644 packages/path_provider/path_provider_macos/example/macos/Runner/Configs/AppInfo.xcconfig create mode 100644 packages/path_provider/path_provider_macos/example/macos/Runner/Configs/Debug.xcconfig create mode 100644 packages/path_provider/path_provider_macos/example/macos/Runner/Configs/Release.xcconfig create mode 100644 packages/path_provider/path_provider_macos/example/macos/Runner/Configs/Warnings.xcconfig create mode 100644 packages/path_provider/path_provider_macos/example/macos/Runner/DebugProfile.entitlements create mode 100644 packages/path_provider/path_provider_macos/example/macos/Runner/Info.plist create mode 100644 packages/path_provider/path_provider_macos/example/macos/Runner/MainFlutterWindow.swift create mode 100644 packages/path_provider/path_provider_macos/example/macos/Runner/Release.entitlements create mode 100644 packages/path_provider/path_provider_macos/example/pubspec.yaml create mode 100644 packages/path_provider/path_provider_macos/example/test_driver/path_provider_e2e.dart create mode 100644 packages/path_provider/path_provider_macos/example/test_driver/path_provider_e2e_test.dart diff --git a/packages/path_provider/path_provider_macos/CHANGELOG.md b/packages/path_provider/path_provider_macos/CHANGELOG.md index ef9c69f45b06..62d7cd24b00f 100644 --- a/packages/path_provider/path_provider_macos/CHANGELOG.md +++ b/packages/path_provider/path_provider_macos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.4 + +* Adds an example app to run integration tests. + ## 0.0.3+1 * Make the pedantic dev_dependency explicit. diff --git a/packages/path_provider/path_provider_macos/example/README.md b/packages/path_provider/path_provider_macos/example/README.md new file mode 100644 index 000000000000..c81750248f02 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/README.md @@ -0,0 +1,8 @@ +# path_provider_macos_example + +Demonstrates how to use the path_provider_macos plugin. + +## Getting Started + +For help getting started with Flutter, view our online +[documentation](http://flutter.io/). diff --git a/packages/path_provider/path_provider_macos/example/android/app/build.gradle b/packages/path_provider/path_provider_macos/example/android/app/build.gradle new file mode 100644 index 000000000000..0404c7203903 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/android/app/build.gradle @@ -0,0 +1,64 @@ +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 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + applicationId "io.flutter.plugins.pathproviderexample" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + androidTestImplementation 'androidx.test:runner:1.2.0' + androidTestImplementation 'androidx.test:rules:1.2.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + 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/path_provider/path_provider_macos/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/path_provider/path_provider_macos/example/android/app/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000000..9a4163a4f5ee --- /dev/null +++ b/packages/path_provider/path_provider_macos/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-4.6-all.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/packages/path_provider/path_provider_macos/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java b/packages/path_provider/path_provider_macos/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java new file mode 100644 index 000000000000..cce04b79f516 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/android/app/src/androidTest/java/EmbeddingV1ActivityTest.java @@ -0,0 +1,15 @@ + +package io.flutter.plugins.pathprovider; + +import androidx.test.rule.ActivityTestRule; +import dev.flutter.plugins.e2e.FlutterRunner; +import io.flutter.plugins.pathproviderexample.EmbeddingV1Activity; +import org.junit.Rule; +import org.junit.runner.RunWith; + +@RunWith(FlutterRunner.class) +public class EmbeddingV1ActivityTest { + @Rule + public ActivityTestRule rule = + new ActivityTestRule<>(EmbeddingV1Activity.class); +} diff --git a/packages/path_provider/path_provider_macos/example/android/app/src/androidTest/java/MainActivityTest.java b/packages/path_provider/path_provider_macos/example/android/app/src/androidTest/java/MainActivityTest.java new file mode 100644 index 000000000000..7bdd449981f5 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/android/app/src/androidTest/java/MainActivityTest.java @@ -0,0 +1,13 @@ + +package io.flutter.plugins.pathprovider; + +import androidx.test.rule.ActivityTestRule; +import dev.flutter.plugins.e2e.FlutterRunner; +import io.flutter.plugins.pathproviderexample.MainActivity; +import org.junit.Rule; +import org.junit.runner.RunWith; + +@RunWith(FlutterRunner.class) +public class MainActivityTest { + @Rule public ActivityTestRule rule = new ActivityTestRule<>(MainActivity.class); +} diff --git a/packages/path_provider/path_provider_macos/example/android/app/src/main/AndroidManifest.xml b/packages/path_provider/path_provider_macos/example/android/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000000..9e03a9373e33 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + diff --git a/packages/path_provider/path_provider_macos/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/EmbeddingV1Activity.java b/packages/path_provider/path_provider_macos/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/EmbeddingV1Activity.java new file mode 100644 index 000000000000..a826af36a9d3 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/EmbeddingV1Activity.java @@ -0,0 +1,14 @@ + +package io.flutter.plugins.pathproviderexample; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class EmbeddingV1Activity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/packages/path_provider/path_provider_macos/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/MainActivity.java b/packages/path_provider/path_provider_macos/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/MainActivity.java new file mode 100644 index 000000000000..36372960fe9c --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/android/app/src/main/java/io/flutter/plugins/pathproviderexample/MainActivity.java @@ -0,0 +1,19 @@ +// Copyright 2017 The Chromium 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.pathproviderexample; + +import dev.flutter.plugins.e2e.E2EPlugin; +import io.flutter.embedding.android.FlutterActivity; +import io.flutter.embedding.engine.FlutterEngine; +import io.flutter.plugins.pathprovider.PathProviderPlugin; + +public class MainActivity extends FlutterActivity { + // TODO(xster): Remove this once v2 of GeneratedPluginRegistrant rolls to stable. https://github.com/flutter/flutter/issues/42694 + @Override + public void configureFlutterEngine(FlutterEngine flutterEngine) { + flutterEngine.getPlugins().add(new PathProviderPlugin()); + flutterEngine.getPlugins().add(new E2EPlugin()); + } +} diff --git a/packages/path_provider/path_provider_macos/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/packages/path_provider/path_provider_macos/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/path_provider/path_provider_macos/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/packages/path_provider/path_provider_macos/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/path_provider/path_provider_macos/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/packages/path_provider/path_provider_macos/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/path_provider/path_provider_macos/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/packages/path_provider/path_provider_macos/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/path_provider/path_provider_macos/example/android/build.gradle b/packages/path_provider/path_provider_macos/example/android/build.gradle new file mode 100644 index 000000000000..541636cc492a --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.3.0' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +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/path_provider/path_provider_macos/example/android/gradle.properties b/packages/path_provider/path_provider_macos/example/android/gradle.properties new file mode 100644 index 000000000000..38c8d4544ff1 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/android/gradle.properties @@ -0,0 +1,4 @@ +org.gradle.jvmargs=-Xmx1536M +android.enableR8=true +android.useAndroidX=true +android.enableJetifier=true diff --git a/packages/path_provider/path_provider_macos/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/path_provider/path_provider_macos/example/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000000..caf54fa2801c --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip diff --git a/packages/path_provider/path_provider_macos/example/android/settings.gradle b/packages/path_provider/path_provider_macos/example/android/settings.gradle new file mode 100644 index 000000000000..6cb349eef1b6 --- /dev/null +++ b/packages/path_provider/path_provider_macos/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 +} \ No newline at end of file diff --git a/packages/path_provider/path_provider_macos/example/ios/Flutter/AppFrameworkInfo.plist b/packages/path_provider/path_provider_macos/example/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 000000000000..6c2de8086bcd --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + UIRequiredDeviceCapabilities + + arm64 + + MinimumOSVersion + 8.0 + + diff --git a/packages/path_provider/path_provider_macos/example/ios/Flutter/Debug.xcconfig b/packages/path_provider/path_provider_macos/example/ios/Flutter/Debug.xcconfig new file mode 100644 index 000000000000..9803018ca79d --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "Generated.xcconfig" +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" diff --git a/packages/path_provider/path_provider_macos/example/ios/Flutter/Release.xcconfig b/packages/path_provider/path_provider_macos/example/ios/Flutter/Release.xcconfig new file mode 100644 index 000000000000..a4a8c604e13d --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include "Generated.xcconfig" +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/project.pbxproj b/packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 000000000000..eb0222a7c9c5 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,490 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 2D9222481EC32A19007564B0 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D9222471EC32A19007564B0 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 85DDFCF6BBDEE02B9D9F8138 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C0EE60090AA5F3AAAF2175B6 /* libPods-Runner.a */; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 2D9222461EC32A19007564B0 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 2D9222471EC32A19007564B0 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 694A199F61914F41AAFD0B7F /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + C0EE60090AA5F3AAAF2175B6 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + D317CA1E83064E01753D8BB5 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + 85DDFCF6BBDEE02B9D9F8138 /* libPods-Runner.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 840012C8B5EDBCF56B0E4AC1 /* Pods */ = { + isa = PBXGroup; + children = ( + 694A199F61914F41AAFD0B7F /* Pods-Runner.debug.xcconfig */, + D317CA1E83064E01753D8BB5 /* Pods-Runner.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 840012C8B5EDBCF56B0E4AC1 /* Pods */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 2D9222461EC32A19007564B0 /* GeneratedPluginRegistrant.h */, + 2D9222471EC32A19007564B0 /* GeneratedPluginRegistrant.m */, + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */ = { + isa = PBXGroup; + children = ( + C0EE60090AA5F3AAAF2175B6 /* libPods-Runner.a */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + AB1344B0443C71CD721E1BB7 /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 95BB15E9E1769C0D146AA592 /* [CP] Embed Pods Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 95BB15E9E1769C0D146AA592 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; + AB1344B0443C71CD721E1BB7 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 2D9222481EC32A19007564B0 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.pathProviderExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.pathProviderExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000000..21a3cc14c74e --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 000000000000..3bb3697ef41c --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/path_provider/path_provider_macos/example/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000000..21a3cc14c74e --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/AppDelegate.h b/packages/path_provider/path_provider_macos/example/ios/Runner/AppDelegate.h new file mode 100644 index 000000000000..d9e18e990f2e --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/ios/Runner/AppDelegate.h @@ -0,0 +1,10 @@ +// Copyright 2017 The Chromium 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 +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/AppDelegate.m b/packages/path_provider/path_provider_macos/example/ios/Runner/AppDelegate.m new file mode 100644 index 000000000000..a4b51c88eb60 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/ios/Runner/AppDelegate.m @@ -0,0 +1,16 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000000..d22f10b2ab63 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,116 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..28c6bf03016f6c994b70f38d1b7346e5831b531f GIT binary patch literal 564 zcmV-40?Yl0P)Px$?ny*JR5%f>l)FnDQ543{x%ZCiu33$Wg!pQFfT_}?5Q|_VSlIbLC`dpoMXL}9 zHfd9&47Mo(7D231gb+kjFxZHS4-m~7WurTH&doVX2KI5sU4v(sJ1@T9eCIKPjsqSr z)C01LsCxk=72-vXmX}CQD#BD;Cthymh&~=f$Q8nn0J<}ZrusBy4PvRNE}+1ceuj8u z0mW5k8fmgeLnTbWHGwfKA3@PdZxhn|PypR&^p?weGftrtCbjF#+zk_5BJh7;0`#Wr zgDpM_;Ax{jO##IrT`Oz;MvfwGfV$zD#c2xckpcXC6oou4ML~ezCc2EtnsQTB4tWNg z?4bkf;hG7IMfhgNI(FV5Gs4|*GyMTIY0$B=_*mso9Ityq$m^S>15>-?0(zQ<8Qy<_TjHE33(?_M8oaM zyc;NxzRVK@DL6RJnX%U^xW0Gpg(lXp(!uK1v0YgHjs^ZXSQ|m#lV7ip7{`C_J2TxPmfw%h$|%acrYHt)Re^PB%O&&=~a zhS(%I#+V>J-vjIib^<+s%ludY7y^C(P8nmqn9fp!i+?vr`bziDE=bx`%2W#Xyrj|i z!XQ4v1%L`m{7KT7q+LZNB^h8Ha2e=`Wp65^0;J00)_^G=au=8Yo;1b`CV&@#=jIBo zjN^JNVfYSs)+kDdGe7`1&8!?MQYKS?DuHZf3iogk_%#9E|5S zWeHrmAo>P;ejX7mwq#*}W25m^ZI+{(Z8fI?4jM_fffY0nok=+88^|*_DwcW>mR#e+ zX$F_KMdb6sRz!~7KkyN0G(3XQ+;z3X%PZ4gh;n-%62U<*VUKNv(D&Q->Na@Xb&u5Q3`3DGf+a8O5x7c#7+R+EAYl@R5us)CIw z7sT@_y~Ao@uL#&^LIh&QceqiT^+lb0YbFZt_SHOtWA%mgPEKVNvVgCsXy{5+zl*X8 zCJe)Q@y>wH^>l4;h1l^Y*9%-23TSmE>q5nI@?mt%n;Sj4Qq`Z+ib)a*a^cJc%E9^J zB;4s+K@rARbcBLT5P=@r;IVnBMKvT*)ew*R;&8vu%?Z&S>s?8?)3*YawM0P4!q$Kv zMmKh3lgE~&w&v%wVzH3Oe=jeNT=n@Y6J6TdHWTjXfX~-=1A1Bw`EW8rn}MqeI34nh zexFeA?&C3B2(E?0{drE@DA2pu(A#ElY&6el60Rn|Qpn-FkfQ8M93AfWIr)drgDFEU zghdWK)^71EWCP(@(=c4kfH1Y(4iugD4fve6;nSUpLT%!)MUHs1!zJYy4y||C+SwQ! z)KM&$7_tyM`sljP2fz6&Z;jxRn{Wup8IOUx8D4uh&(=O zx-7$a;U><*5L^!%xRlw)vAbh;sdlR||& ze}8_8%)c2Fwy=F&H|LM+p{pZB5DKTx>Y?F1N%BlZkXf!}JeGuMZk~LPi7{cidvUGB zAJ4LVeNV%XO>LTrklB#^-;8nb;}6l;1oW&WS=Mz*Az!4cqqQzbOSFq`$Q%PfD7srM zpKgP-D_0XPTRX*hAqeq0TDkJ;5HB1%$3Np)99#16c{ zJImlNL(npL!W|Gr_kxl1GVmF5&^$^YherS7+~q$p zt}{a=*RiD2Ikv6o=IM1kgc7zqpaZ;OB)P!1zz*i3{U()Dq#jG)egvK}@uFLa`oyWZ zf~=MV)|yJn`M^$N%ul5);JuQvaU1r2wt(}J_Qgyy`qWQI`hEeRX0uC@c1(dQ2}=U$ tNIIaX+dr)NRWXcxoR{>fqI{SF_dm1Ylv~=3YHI)h002ovPDHLkV1g(pWS;;4 literal 0 HcmV?d00001 diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..f091b6b0bca859a3f474b03065bef75ba58a9e4c GIT binary patch literal 1588 zcmV-42Fv-0P)C1SqPt}wig>|5Crh^=oyX$BK<}M8eLU3e2hGT;=G|!_SP)7zNI6fqUMB=)y zRAZ>eDe#*r`yDAVgB_R*LB*MAc)8(b{g{9McCXW!lq7r(btRoB9!8B-#AI6JMb~YFBEvdsV)`mEQO^&#eRKx@b&x- z5lZm*!WfD8oCLzfHGz#u7sT0^VLMI1MqGxF^v+`4YYnVYgk*=kU?HsSz{v({E3lb9 z>+xILjBN)t6`=g~IBOelGQ(O990@BfXf(DRI5I$qN$0Gkz-FSc$3a+2fX$AedL4u{ z4V+5Ong(9LiGcIKW?_352sR;LtDPmPJXI{YtT=O8=76o9;*n%_m|xo!i>7$IrZ-{l z-x3`7M}qzHsPV@$v#>H-TpjDh2UE$9g6sysUREDy_R(a)>=eHw-WAyfIN z*qb!_hW>G)Tu8nSw9yn#3wFMiLcfc4pY0ek1}8(NqkBR@t4{~oC>ryc-h_ByH(Cg5 z>ao-}771+xE3um9lWAY1FeQFxowa1(!J(;Jg*wrg!=6FdRX+t_<%z&d&?|Bn){>zm zZQj(aA_HeBY&OC^jj*)N`8fa^ePOU72VpInJoI1?`ty#lvlNzs(&MZX+R%2xS~5Kh zX*|AU4QE#~SgPzOXe9>tRj>hjU@c1k5Y_mW*Jp3fI;)1&g3j|zDgC+}2Q_v%YfDax z!?umcN^n}KYQ|a$Lr+51Nf9dkkYFSjZZjkma$0KOj+;aQ&721~t7QUKx61J3(P4P1 zstI~7-wOACnWP4=8oGOwz%vNDqD8w&Q`qcNGGrbbf&0s9L0De{4{mRS?o0MU+nR_! zrvshUau0G^DeMhM_v{5BuLjb#Hh@r23lDAk8oF(C+P0rsBpv85EP>4CVMx#04MOfG z;P%vktHcXwTj~+IE(~px)3*MY77e}p#|c>TD?sMatC0Tu4iKKJ0(X8jxQY*gYtxsC z(zYC$g|@+I+kY;dg_dE>scBf&bP1Nc@Hz<3R)V`=AGkc;8CXqdi=B4l2k|g;2%#m& z*jfX^%b!A8#bI!j9-0Fi0bOXl(-c^AB9|nQaE`*)Hw+o&jS9@7&Gov#HbD~#d{twV zXd^Tr^mWLfFh$@Dr$e;PBEz4(-2q1FF0}c;~B5sA}+Q>TOoP+t>wf)V9Iy=5ruQa;z)y zI9C9*oUga6=hxw6QasLPnee@3^Rr*M{CdaL5=R41nLs(AHk_=Y+A9$2&H(B7!_pURs&8aNw7?`&Z&xY_Ye z)~D5Bog^td-^QbUtkTirdyK^mTHAOuptDflut!#^lnKqU md>ggs(5nOWAqO?umG&QVYK#ibz}*4>0000U6E9hRK9^#O7(mu>ETqrXGsduA8$)?`v2seloOCza43C{NQ$$gAOH**MCn0Q?+L7dl7qnbRdqZ8LSVp1ItDxhxD?t@5_yHg6A8yI zC*%Wgg22K|8E#!~cTNYR~@Y9KepMPrrB8cABapAFa=`H+UGhkXUZV1GnwR1*lPyZ;*K(i~2gp|@bzp8}og7e*#% zEnr|^CWdVV!-4*Y_7rFvlww2Ze+>j*!Z!pQ?2l->4q#nqRu9`ELo6RMS5=br47g_X zRw}P9a7RRYQ%2Vsd0Me{_(EggTnuN6j=-?uFS6j^u69elMypu?t>op*wBx<=Wx8?( ztpe^(fwM6jJX7M-l*k3kEpWOl_Vk3@(_w4oc}4YF4|Rt=2V^XU?#Yz`8(e?aZ@#li0n*=g^qOcVpd-Wbok=@b#Yw zqn8u9a)z>l(1kEaPYZ6hwubN6i<8QHgsu0oE) ziJ(p;Wxm>sf!K+cw>R-(^Y2_bahB+&KI9y^);#0qt}t-$C|Bo71lHi{_+lg#f%RFy z0um=e3$K3i6K{U_4K!EX?F&rExl^W|G8Z8;`5z-k}OGNZ0#WVb$WCpQu-_YsiqKP?BB# vzVHS-CTUF4Ozn5G+mq_~Qqto~ahA+K`|lyv3(-e}00000NkvXXu0mjfd`9t{ literal 0 HcmV?d00001 diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d0ef06e7edb86cdfe0d15b4b0d98334a86163658 GIT binary patch literal 1716 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 literal 0 HcmV?d00001 diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c8f9ed8f5cee1c98386d13b17e89f719e83555b2 GIT binary patch literal 1895 zcmV-t2blPYP)FQtfgmafE#=YDCq`qUBt#QpG%*H6QHY765~R=q zZ6iudfM}q!Pz#~9JgOi8QJ|DSu?1-*(kSi1K4#~5?#|rh?sS)(-JQqX*}ciXJ56_H zdw=^s_srbAdqxlvGyrgGet#6T7_|j;95sL%MtM;q86vOxKM$f#puR)Bjv9Zvz9-di zXOTSsZkM83)E9PYBXC<$6(|>lNLVBb&&6y{NByFCp%6+^ALR@NCTse_wqvNmSWI-m z!$%KlHFH2omF!>#%1l3LTZg(s7eof$7*xB)ZQ0h?ejh?Ta9fDv59+u#MokW+1t8Zb zgHv%K(u9G^Lv`lh#f3<6!JVTL3(dCpxHbnbA;kKqQyd1~^Xe0VIaYBSWm6nsr;dFj z4;G-RyL?cYgsN1{L4ZFFNa;8)Rv0fM0C(~Tkit94 zz#~A)59?QjD&pAPSEQ)p8gP|DS{ng)j=2ux)_EzzJ773GmQ_Cic%3JJhC0t2cx>|v zJcVusIB!%F90{+}8hG3QU4KNeKmK%T>mN57NnCZ^56=0?&3@!j>a>B43pi{!u z7JyDj7`6d)qVp^R=%j>UIY6f+3`+qzIc!Y_=+uN^3BYV|o+$vGo-j-Wm<10%A=(Yk^beI{t%ld@yhKjq0iNjqN4XMGgQtbKubPM$JWBz}YA65k%dm*awtC^+f;a-x4+ddbH^7iDWGg&N0n#MW{kA|=8iMUiFYvMoDY@sPC#t$55gn6ykUTPAr`a@!(;np824>2xJthS z*ZdmT`g5-`BuJs`0LVhz+D9NNa3<=6m;cQLaF?tCv8)zcRSh66*Z|vXhG@$I%U~2l z?`Q zykI#*+rQ=z6Jm=Bui-SfpDYLA=|vzGE(dYm=OC8XM&MDo7ux4UF1~0J1+i%aCUpRe zt3L_uNyQ*cE(38Uy03H%I*)*Bh=Lb^Xj3?I^Hnbeq72(EOK^Y93CNp*uAA{5Lc=ky zx=~RKa4{iTm{_>_vSCm?$Ej=i6@=m%@VvAITnigVg{&@!7CDgs908761meDK5azA} z4?=NOH|PdvabgJ&fW2{Mo$Q0CcD8Qc84%{JPYt5EiG{MdLIAeX%T=D7NIP4%Hw}p9 zg)==!2Lbp#j{u_}hMiao9=!VSyx0gHbeCS`;q&vzeq|fs`y&^X-lso(Ls@-706qmA z7u*T5PMo_w3{se1t2`zWeO^hOvTsohG_;>J0wVqVe+n)AbQCx)yh9;w+J6?NF5Lmo zecS@ieAKL8%bVd@+-KT{yI|S}O>pYckUFs;ry9Ow$CD@ztz5K-*D$^{i(_1llhSh^ zEkL$}tsQt5>QA^;QgjgIfBDmcOgi5YDyu?t6vSnbp=1+@6D& z5MJ}B8q;bRlVoxasyhcUF1+)o`&3r0colr}QJ3hcSdLu;9;td>kf@Tcn<@9sIx&=m z;AD;SCh95=&p;$r{Xz3iWCO^MX83AGJ(yH&eTXgv|0=34#-&WAmw{)U7OU9!Wz^!7 zZ%jZFi@JR;>Mhi7S>V7wQ176|FdW2m?&`qa(ScO^CFPR80HucLHOTy%5s*HR0^8)i h0WYBP*#0Ks^FNSabJA*5${_#%002ovPDHLkV1oKhTl@e3 literal 0 HcmV?d00001 diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d6b8609df07bf62e5100a53a01510388bd2b22 GIT binary patch literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ literal 0 HcmV?d00001 diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d6b8609df07bf62e5100a53a01510388bd2b22 GIT binary patch literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ literal 0 HcmV?d00001 diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..75b2d164a5a98e212cca15ea7bf2ab5de5108680 GIT binary patch literal 3831 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 literal 0 HcmV?d00001 diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/path_provider/path_provider_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..c4df70d39da7941ef3f6dcb7f06a192d8dcb308d GIT binary patch literal 1888 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 iW8 + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/Base.lproj/Main.storyboard b/packages/path_provider/path_provider_macos/example/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 000000000000..f3c28516fb38 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/Info.plist b/packages/path_provider/path_provider_macos/example/ios/Runner/Info.plist new file mode 100644 index 000000000000..342db6a5dcaf --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/ios/Runner/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + path_provider_example + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + arm64 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/packages/path_provider/path_provider_macos/example/ios/Runner/main.m b/packages/path_provider/path_provider_macos/example/ios/Runner/main.m new file mode 100644 index 000000000000..bec320c0bee0 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/ios/Runner/main.m @@ -0,0 +1,13 @@ +// Copyright 2017 The Chromium 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 +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/packages/path_provider/path_provider_macos/example/lib/main.dart b/packages/path_provider/path_provider_macos/example/lib/main.dart new file mode 100644 index 000000000000..473a989914f6 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/lib/main.dart @@ -0,0 +1,149 @@ +// Copyright 2019 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 'dart:io' show Directory; + +import 'package:flutter/material.dart'; +import 'package:path_provider/path_provider.dart'; + +void main() { + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Path Provider', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: MyHomePage(title: 'Path Provider'), + ); + } +} + +class MyHomePage extends StatefulWidget { + MyHomePage({Key key, this.title}) : super(key: key); + final String title; + + @override + _MyHomePageState createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State { + Future _tempDirectory; + Future _appSupportDirectory; + Future _appDocumentsDirectory; + Future _appLibraryDirectory; + Future _downloadsDirectory; + + void _requestTempDirectory() { + setState(() { + _tempDirectory = getTemporaryDirectory(); + }); + } + + Widget _buildDirectory( + BuildContext context, AsyncSnapshot snapshot) { + Text text = const Text(''); + if (snapshot.connectionState == ConnectionState.done) { + if (snapshot.hasError) { + text = Text('Error: ${snapshot.error}'); + } else if (snapshot.hasData) { + text = Text('path: ${snapshot.data.path}'); + } else { + text = const Text('path unavailable'); + } + } + return Padding(padding: const EdgeInsets.all(16.0), child: text); + } + + void _requestAppDocumentsDirectory() { + setState(() { + _appDocumentsDirectory = getApplicationDocumentsDirectory(); + }); + } + + void _requestAppSupportDirectory() { + setState(() { + _appSupportDirectory = getApplicationSupportDirectory(); + }); + } + + void _requestAppLibraryDirectory() { + setState(() { + _appLibraryDirectory = getLibraryDirectory(); + }); + } + + void _requestDownloadsDirectory() { + setState(() { + _downloadsDirectory = getDownloadsDirectory(); + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(widget.title), + ), + body: Center( + child: ListView( + children: [ + Padding( + padding: const EdgeInsets.all(16.0), + child: RaisedButton( + child: const Text('Get Temporary Directory'), + onPressed: _requestTempDirectory, + ), + ), + FutureBuilder( + future: _tempDirectory, builder: _buildDirectory), + Padding( + padding: const EdgeInsets.all(16.0), + child: RaisedButton( + child: const Text('Get Application Documents Directory'), + onPressed: _requestAppDocumentsDirectory, + ), + ), + FutureBuilder( + future: _appDocumentsDirectory, builder: _buildDirectory), + Padding( + padding: const EdgeInsets.all(16.0), + child: RaisedButton( + child: const Text('Get Application Support Directory'), + onPressed: _requestAppSupportDirectory, + ), + ), + FutureBuilder( + future: _appSupportDirectory, builder: _buildDirectory), + Padding( + padding: const EdgeInsets.all(16.0), + child: RaisedButton( + child: const Text('Get Application Library Directory'), + onPressed: _requestAppLibraryDirectory, + ), + ), + FutureBuilder( + future: _appLibraryDirectory, builder: _buildDirectory), + Padding( + padding: const EdgeInsets.all(16.0), + child: RaisedButton( + child: const Text('Get Downlads Directory'), + onPressed: _requestDownloadsDirectory, + ), + ), + FutureBuilder( + future: _downloadsDirectory, builder: _buildDirectory), + ], + ), + ), + ); + } +} diff --git a/packages/path_provider/path_provider_macos/example/macos/Flutter/Flutter-Debug.xcconfig b/packages/path_provider/path_provider_macos/example/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 000000000000..785633d3a86b --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/macos/Flutter/Flutter-Debug.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/packages/path_provider/path_provider_macos/example/macos/Flutter/Flutter-Release.xcconfig b/packages/path_provider/path_provider_macos/example/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 000000000000..5fba960c3af2 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/macos/Flutter/Flutter-Release.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner.xcodeproj/project.pbxproj b/packages/path_provider/path_provider_macos/example/macos/Runner.xcodeproj/project.pbxproj new file mode 100644 index 000000000000..1e39683e1446 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/macos/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,654 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXAggregateTarget section */ + 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; + buildPhases = ( + 33CC111E2044C6BF0003C045 /* ShellScript */, + ); + dependencies = ( + ); + name = "Flutter Assemble"; + productName = FLX; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 23F6FAA3AF82DFCF2B7DD79A /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1523F64D34B952AB303BFFA8 /* Pods_Runner.framework */; }; + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; }; + 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + D73912F022F37F9E000D13A0 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; }; + D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC111A2044C6BA0003C045; + remoteInfo = FLX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 33CC110E2044A8840003C045 /* Bundle Framework */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */, + 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */, + ); + name = "Bundle Framework"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 0A1A53CF00FD04D6ED0A8E4A /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 1523F64D34B952AB303BFFA8 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; + 33CC10ED2044A3C60003C045 /* path_provider_example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = path_provider_example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; + 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; + 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FlutterMacOS.framework; path = Flutter/ephemeral/FlutterMacOS.framework; sourceTree = SOURCE_ROOT; }; + 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; + 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; + 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 46139048DB9F59D473B61B5E /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + D73912EF22F37F9E000D13A0 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/ephemeral/App.framework; sourceTree = SOURCE_ROOT; }; + F4586DA69948E3A954A2FC9C /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D73912F022F37F9E000D13A0 /* App.framework in Frameworks */, + 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */, + 23F6FAA3AF82DFCF2B7DD79A /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 30697CBF35C100C7DD4B4699 /* Pods */ = { + isa = PBXGroup; + children = ( + 46139048DB9F59D473B61B5E /* Pods-Runner.debug.xcconfig */, + F4586DA69948E3A954A2FC9C /* Pods-Runner.release.xcconfig */, + 0A1A53CF00FD04D6ED0A8E4A /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + 33BA886A226E78AF003329D5 /* Configs */ = { + isa = PBXGroup; + children = ( + 33E5194F232828860026EE4D /* AppInfo.xcconfig */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, + ); + path = Configs; + sourceTree = ""; + }; + 33CC10E42044A3C60003C045 = { + isa = PBXGroup; + children = ( + 33FAB671232836740065AC1E /* Runner */, + 33CEB47122A05771004F2AC0 /* Flutter */, + 33CC10EE2044A3C60003C045 /* Products */, + D73912EC22F37F3D000D13A0 /* Frameworks */, + 30697CBF35C100C7DD4B4699 /* Pods */, + ); + sourceTree = ""; + }; + 33CC10EE2044A3C60003C045 /* Products */ = { + isa = PBXGroup; + children = ( + 33CC10ED2044A3C60003C045 /* path_provider_example.app */, + ); + name = Products; + sourceTree = ""; + }; + 33CC11242044D66E0003C045 /* Resources */ = { + isa = PBXGroup; + children = ( + 33CC10F22044A3C60003C045 /* Assets.xcassets */, + 33CC10F42044A3C60003C045 /* MainMenu.xib */, + 33CC10F72044A3C60003C045 /* Info.plist */, + ); + name = Resources; + path = ..; + sourceTree = ""; + }; + 33CEB47122A05771004F2AC0 /* Flutter */ = { + isa = PBXGroup; + children = ( + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, + D73912EF22F37F9E000D13A0 /* App.framework */, + 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */, + ); + path = Flutter; + sourceTree = ""; + }; + 33FAB671232836740065AC1E /* Runner */ = { + isa = PBXGroup; + children = ( + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + 33E51913231747F40026EE4D /* DebugProfile.entitlements */, + 33E51914231749380026EE4D /* Release.entitlements */, + 33CC11242044D66E0003C045 /* Resources */, + 33BA886A226E78AF003329D5 /* Configs */, + ); + path = Runner; + sourceTree = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1523F64D34B952AB303BFFA8 /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 33CC10EC2044A3C60003C045 /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 82C3ED26F2C350499338A54B /* [CP] Check Pods Manifest.lock */, + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + 3399D490228B24CF009A79C7 /* ShellScript */, + 7413A74A1ECFDFE67CD0521B /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 33CC11202044C79F0003C045 /* PBXTargetDependency */, + ); + name = Runner; + productName = Runner; + productReference = 33CC10ED2044A3C60003C045 /* path_provider_example.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 33CC10E52044A3C60003C045 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 0930; + ORGANIZATIONNAME = "The Flutter Authors"; + TargetAttributes = { + 33CC10EC2044A3C60003C045 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1100; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 1; + }; + }; + }; + 33CC111A2044C6BA0003C045 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 33CC10E42044A3C60003C045; + productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 33CC10EC2044A3C60003C045 /* Runner */, + 33CC111A2044C6BA0003C045 /* Flutter Assemble */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 33CC10EB2044A3C60003C045 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3399D490228B24CF009A79C7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename\n"; + }; + 33CC111E2044C6BF0003C045 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + Flutter/ephemeral/FlutterInputs.xcfilelist, + ); + inputPaths = ( + Flutter/ephemeral/tripwire, + ); + outputFileListPaths = ( + Flutter/ephemeral/FlutterOutputs.xcfilelist, + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh\ntouch Flutter/ephemeral/tripwire\n"; + }; + 7413A74A1ECFDFE67CD0521B /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 82C3ED26F2C350499338A54B /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 33CC10E92044A3C60003C045 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; + targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 33CC10F52044A3C60003C045 /* Base */, + ); + name = MainMenu.xib; + path = Runner; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 338D0CE9231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Profile; + }; + 338D0CEA231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter/ephemeral", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Profile; + }; + 338D0CEB231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Profile; + }; + 33CC10F92044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 33CC10FA2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 33CC10FC2044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter/ephemeral", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 33CC10FD2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter/ephemeral", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 33CC111C2044C6BA0003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 33CC111D2044C6BA0003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10F92044A3C60003C045 /* Debug */, + 33CC10FA2044A3C60003C045 /* Release */, + 338D0CE9231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10FC2044A3C60003C045 /* Debug */, + 33CC10FD2044A3C60003C045 /* Release */, + 338D0CEA231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC111C2044C6BA0003C045 /* Debug */, + 33CC111D2044C6BA0003C045 /* Release */, + 338D0CEB231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 33CC10E52044A3C60003C045 /* Project object */; +} diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/path_provider/path_provider_macos/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 000000000000..1552901c04e0 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/packages/path_provider/path_provider_macos/example/macos/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000000..21a3cc14c74e --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/path_provider/path_provider_macos/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000000..18d981003d68 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner/AppDelegate.swift b/packages/path_provider/path_provider_macos/example/macos/Runner/AppDelegate.swift new file mode 100644 index 000000000000..d53ef6437726 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/macos/Runner/AppDelegate.swift @@ -0,0 +1,9 @@ +import Cocoa +import FlutterMacOS + +@NSApplicationMain +class AppDelegate: FlutterAppDelegate { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } +} diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/path_provider/path_provider_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000000..a2ec33f19f11 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/packages/path_provider/path_provider_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 0000000000000000000000000000000000000000..3c4935a7ca84f0976aca34b7f2895d65fb94d1ea GIT binary patch literal 46993 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 literal 0 HcmV?d00001 diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/packages/path_provider/path_provider_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 0000000000000000000000000000000000000000..ed4cc16421680a50164ba74381b4b35ceaa0ccfc GIT binary patch literal 3276 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 N;OXk;vd$@?2>?>Ex^Vyi literal 0 HcmV?d00001 diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/packages/path_provider/path_provider_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png new file mode 100644 index 0000000000000000000000000000000000000000..bcbf36df2f2aaaa0a63c7dabc94e600184229d0d GIT binary patch literal 5933 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 f$KZHO*s&vt|9^w-6P?|#0pRK8NSwWJ?9znhg z3{`3j3=J&|48MRv4KElNN(~qoUL`OvSj}Ky5HFasE6@fg!ItFh?!xdN1Q+aGJ{c&& zS>O>_%)r1c48n{Iv*t(u1=&kHeO=ifbFy+6aSK)V_AxLppYn8Z42d|rc6w}vOsL55 z`t&mC&y2@JTEyg!eDiFX^k#CC!jq%>erB=yHqUP0XcDOTw6ko}L zX;EmMrq(fKk*eygEuA616;0)>@A{TK|55PV@70 z$OfzS*(VJxQev3J?yY?O=ul(v`fp}?u9z`JK3ugibK>)DyCwImZOF4d{xK%%Ks1*} zv$oa)9anR%lXIBUqYnhLmT>VOzHfNP?ZwJNZ!5$s9M08RynIvaXw>@G^T9@r9^KH1 zVy??F&uuk)bH9Y4pQY!hP58i_H6 znl-NcuCpLV6ZWU;4C zu@9exF&OZi`Bovq_m%T+WhU2kvkz@^_LpycBvqm3bMpLw8X-Or5sL>0AKE1$(k_L=_Zc=CUq#=x1-QZf)G7nHu@fmsQ1eN_N3+nTEz`4HI4Z6uVlE zJH+X&det8JU?tO?upcM4Z=cV!JV;yF>FfL5Q$M|W_2Z!P`S=}Wzp|_1^#d%e?_H`> zV@%vA$+bFVqhw9`U;TfP|5|PD{||OiYdor8P*i??|NJcb%kzT_73*7WE?Ua5hAnR2 z=7WE=PhTlJ#ZeRznjTUb;`E(wkMZrj4e|Hilz-mK>9cZHQY**5TUPw~u}k;u73KI}xAx!0m-)GVia|x^d3p~s_9gh83jA&Ra<8rM%`>U3x69t&NzbwWY}7Ar?)FK#IZ0z|d0H0EkRO w3{9;}4Xg|ebq&m|3=9_N6z8I7$jwj5OsmAL;bP(Gi$Dzwp00i_>zopr02+f8CIA2c literal 0 HcmV?d00001 diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/packages/path_provider/path_provider_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png new file mode 100644 index 0000000000000000000000000000000000000000..e71a726136a47ed24125c7efc79d68a4a01961b4 GIT binary patch literal 14800 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner/Configs/AppInfo.xcconfig b/packages/path_provider/path_provider_macos/example/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 000000000000..477d8d3d133e --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/macos/Runner/Configs/AppInfo.xcconfig @@ -0,0 +1,14 @@ +// Application-level settings for the Runner target. +// +// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the +// future. If not, the values below would default to using the project name when this becomes a +// 'flutter create' template. + +// The application's name. By default this is also the title of the Flutter window. +PRODUCT_NAME = path_provider_example + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.pathProviderExample + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2019 io.flutter.plugins. All rights reserved. diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner/Configs/Debug.xcconfig b/packages/path_provider/path_provider_macos/example/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 000000000000..36b0fd9464f4 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner/Configs/Release.xcconfig b/packages/path_provider/path_provider_macos/example/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 000000000000..dff4f49561c8 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner/Configs/Warnings.xcconfig b/packages/path_provider/path_provider_macos/example/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 000000000000..42bcbf4780b1 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/macos/Runner/Configs/Warnings.xcconfig @@ -0,0 +1,13 @@ +WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_PRAGMA_PACK = YES +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +GCC_WARN_STRICT_SELECTOR_MATCH = YES +CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES +GCC_WARN_SHADOW = YES +CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner/DebugProfile.entitlements b/packages/path_provider/path_provider_macos/example/macos/Runner/DebugProfile.entitlements new file mode 100644 index 000000000000..dddb8a30c851 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,12 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.cs.allow-jit + + com.apple.security.network.server + + + diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner/Info.plist b/packages/path_provider/path_provider_macos/example/macos/Runner/Info.plist new file mode 100644 index 000000000000..4789daa6a443 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/macos/Runner/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + $(PRODUCT_COPYRIGHT) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner/MainFlutterWindow.swift b/packages/path_provider/path_provider_macos/example/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 000000000000..2722837ec918 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,15 @@ +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController.init() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/packages/path_provider/path_provider_macos/example/macos/Runner/Release.entitlements b/packages/path_provider/path_provider_macos/example/macos/Runner/Release.entitlements new file mode 100644 index 000000000000..852fa1a4728a --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/macos/Runner/Release.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/packages/path_provider/path_provider_macos/example/pubspec.yaml b/packages/path_provider/path_provider_macos/example/pubspec.yaml new file mode 100644 index 000000000000..e3242b83ad99 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/pubspec.yaml @@ -0,0 +1,19 @@ +name: path_provider_example +description: Demonstrates how to use the path_provider plugin. + +dependencies: + flutter: + sdk: flutter + path_provider: any + path_provider_macos: + path: ../ + +dev_dependencies: + e2e: ^0.2.1 + flutter_driver: + sdk: flutter + test: any + pedantic: ^1.8.0 + +flutter: + uses-material-design: true diff --git a/packages/path_provider/path_provider_macos/example/test_driver/path_provider_e2e.dart b/packages/path_provider/path_provider_macos/example/test_driver/path_provider_e2e.dart new file mode 100644 index 000000000000..6cb8362b76d5 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/test_driver/path_provider_e2e.dart @@ -0,0 +1,51 @@ +// Copyright 2019, the Chromium project authors. Please see the AUTHORS file +// for details. 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:io'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:e2e/e2e.dart'; + +void main() { + E2EWidgetsFlutterBinding.ensureInitialized(); + + testWidgets('getTemporaryDirectory', (WidgetTester tester) async { + final Directory result = await getTemporaryDirectory(); + _verifySampleFile(result, 'temporaryDirectory'); + }); + + testWidgets('getApplicationDocumentsDirectory', (WidgetTester tester) async { + final Directory result = await getApplicationDocumentsDirectory(); + _verifySampleFile(result, 'applicationDocuments'); + }); + + testWidgets('getApplicationSupportDirectory', (WidgetTester tester) async { + final Directory result = await getApplicationSupportDirectory(); + _verifySampleFile(result, 'applicationSupport'); + }); + + testWidgets('getLibraryDirectory', (WidgetTester tester) async { + if (!Platform.isMacOS) { + return; + } + final Directory result = await getLibraryDirectory(); + _verifySampleFile(result, 'library'); + }); +} + +/// Verify a file called [name] in [directory] by recreating it with test +/// contents when necessary. +void _verifySampleFile(Directory directory, String name) { + final File file = File('${directory.path}/$name'); + + if (file.existsSync()) { + file.deleteSync(); + expect(file.existsSync(), isFalse); + } + + file.writeAsStringSync('Hello world!'); + expect(file.readAsStringSync(), 'Hello world!'); + expect(directory.listSync(), isNotEmpty); + file.deleteSync(); +} diff --git a/packages/path_provider/path_provider_macos/example/test_driver/path_provider_e2e_test.dart b/packages/path_provider/path_provider_macos/example/test_driver/path_provider_e2e_test.dart new file mode 100644 index 000000000000..f3aa9e218d82 --- /dev/null +++ b/packages/path_provider/path_provider_macos/example/test_driver/path_provider_e2e_test.dart @@ -0,0 +1,15 @@ +// Copyright 2019, the Chromium project authors. Please see the AUTHORS file +// for details. 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 'dart:io'; +import 'package:flutter_driver/flutter_driver.dart'; + +Future main() async { + final FlutterDriver driver = await FlutterDriver.connect(); + final String result = + await driver.requestData(null, timeout: const Duration(minutes: 1)); + await driver.close(); + exit(result == 'pass' ? 0 : 1); +} diff --git a/packages/path_provider/path_provider_macos/pubspec.yaml b/packages/path_provider/path_provider_macos/pubspec.yaml index ed7ef74fa609..30508428cf92 100644 --- a/packages/path_provider/path_provider_macos/pubspec.yaml +++ b/packages/path_provider/path_provider_macos/pubspec.yaml @@ -1,6 +1,6 @@ name: path_provider_macos description: macOS implementation of the path_provider plugin -version: 0.0.3+1 +version: 0.0.4 homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_macos flutter: @@ -10,7 +10,7 @@ flutter: pluginClass: PathProviderPlugin environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.1.0 <3.0.0" flutter: ">=1.10.0 <2.0.0" dependencies: From 5bc74e4f3d780304c272b667f6e96c41b7518039 Mon Sep 17 00:00:00 2001 From: Jaideep Prasad Date: Fri, 28 Feb 2020 08:28:24 +0530 Subject: [PATCH 09/37] [url_launcher] fix: url_launcher - updated _launchUniversalLinkIos and Added Tests (#2552) updated _launchUniversalLinkIos to launch the url passed. It could also be done that we remove the url argument passed and open the hardcoded url. Either of the case needs to be done. --- .../url_launcher/url_launcher/CHANGELOG.md | 4 ++ .../url_launcher/example/lib/main.dart | 6 +-- .../url_launcher/example/pubspec.yaml | 2 + .../test/url_launcher_example_test.dart | 45 +++++++++++++++++++ .../url_launcher/url_launcher/pubspec.yaml | 2 +- .../url_launcher_macos/CHANGELOG.md | 4 ++ .../url_launcher_macos/example/lib/main.dart | 6 +-- .../url_launcher_macos/pubspec.yaml | 2 +- 8 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 packages/url_launcher/url_launcher/example/test/url_launcher_example_test.dart diff --git a/packages/url_launcher/url_launcher/CHANGELOG.md b/packages/url_launcher/url_launcher/CHANGELOG.md index 0cab10180cd8..3097a2122ae1 100644 --- a/packages/url_launcher/url_launcher/CHANGELOG.md +++ b/packages/url_launcher/url_launcher/CHANGELOG.md @@ -1,3 +1,7 @@ +## 5.4.3 + +* Fixed the launchUniversalLinkIos method. + ## 5.4.2 * Make the pedantic dev_dependency explicit. diff --git a/packages/url_launcher/url_launcher/example/lib/main.dart b/packages/url_launcher/url_launcher/example/lib/main.dart index 00ab6c5b047d..f7d90c4bef65 100644 --- a/packages/url_launcher/url_launcher/example/lib/main.dart +++ b/packages/url_launcher/url_launcher/example/lib/main.dart @@ -91,15 +91,15 @@ class _MyHomePageState extends State { } Future _launchUniversalLinkIos(String url) async { - if (await canLaunch('https://youtube.com')) { + if (await canLaunch(url)) { final bool nativeAppLaunchSucceeded = await launch( - 'https://youtube.com', + url, forceSafariVC: false, universalLinksOnly: true, ); if (!nativeAppLaunchSucceeded) { await launch( - 'https://youtube.com', + url, forceSafariVC: true, ); } diff --git a/packages/url_launcher/url_launcher/example/pubspec.yaml b/packages/url_launcher/url_launcher/example/pubspec.yaml index 065693e1432c..1eb3e603696f 100644 --- a/packages/url_launcher/url_launcher/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher/example/pubspec.yaml @@ -12,6 +12,8 @@ dev_dependencies: flutter_driver: sdk: flutter pedantic: ^1.8.0 + mockito: ^4.1.1 + plugin_platform_interface: ^1.0.0 flutter: uses-material-design: true diff --git a/packages/url_launcher/url_launcher/example/test/url_launcher_example_test.dart b/packages/url_launcher/url_launcher/example/test/url_launcher_example_test.dart new file mode 100644 index 000000000000..41b9f6f5ec6c --- /dev/null +++ b/packages/url_launcher/url_launcher/example/test/url_launcher_example_test.dart @@ -0,0 +1,45 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:flutter/material.dart'; +import 'package:mockito/mockito.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; +import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; +import 'package:url_launcher_example/main.dart'; + +void main() { + final MockUrlLauncher mock = MockUrlLauncher(); + UrlLauncherPlatform.instance = mock; + + testWidgets('Can open URLs', (WidgetTester tester) async { + await tester.pumpWidget(MyApp()); + const String defaultUrl = 'https://www.cylog.org/headers/'; + when(mock.canLaunch(defaultUrl)).thenAnswer((_) => Future.value(true)); + const Map defaultHeaders = { + 'my_header_key': 'my_header_value' + }; + verifyNever(mock.launch(defaultUrl, + useSafariVC: false, + useWebView: false, + enableDomStorage: false, + enableJavaScript: false, + universalLinksOnly: false, + headers: defaultHeaders)); + + Finder browserlaunchBtn = + find.widgetWithText(RaisedButton, 'Launch in browser'); + expect(browserlaunchBtn, findsOneWidget); + await tester.tap(browserlaunchBtn); + + verify(mock.launch(defaultUrl, + useSafariVC: false, + useWebView: false, + enableDomStorage: false, + enableJavaScript: false, + universalLinksOnly: false, + headers: defaultHeaders)) + .called(1); + }); +} + +class MockUrlLauncher extends Mock + with MockPlatformInterfaceMixin + implements UrlLauncherPlatform {} diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index ba929709b01e..f0568e0029c0 100644 --- a/packages/url_launcher/url_launcher/pubspec.yaml +++ b/packages/url_launcher/url_launcher/pubspec.yaml @@ -2,7 +2,7 @@ name: url_launcher description: Flutter plugin for launching a URL on Android and iOS. Supports web, phone, SMS, and email schemes. homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher -version: 5.4.2 +version: 5.4.3 flutter: plugin: diff --git a/packages/url_launcher/url_launcher_macos/CHANGELOG.md b/packages/url_launcher/url_launcher_macos/CHANGELOG.md index 6ecac5bd9faf..fc2448201e22 100644 --- a/packages/url_launcher/url_launcher_macos/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_macos/CHANGELOG.md @@ -1,3 +1,7 @@ +# 0.0.1+5 + +* Fixed the launchUniversalLinkIos method. + # 0.0.1+4 * Make the pedantic dev_dependency explicit. diff --git a/packages/url_launcher/url_launcher_macos/example/lib/main.dart b/packages/url_launcher/url_launcher_macos/example/lib/main.dart index f079bb272663..b5cce7482d07 100644 --- a/packages/url_launcher/url_launcher_macos/example/lib/main.dart +++ b/packages/url_launcher/url_launcher_macos/example/lib/main.dart @@ -90,15 +90,15 @@ class _MyHomePageState extends State { } Future _launchUniversalLinkIos(String url) async { - if (await canLaunch('https://youtube.com')) { + if (await canLaunch(url)) { final bool nativeAppLaunchSucceeded = await launch( - 'https://youtube.com', + url, forceSafariVC: false, universalLinksOnly: true, ); if (!nativeAppLaunchSucceeded) { await launch( - 'https://youtube.com', + url, forceSafariVC: true, ); } diff --git a/packages/url_launcher/url_launcher_macos/pubspec.yaml b/packages/url_launcher/url_launcher_macos/pubspec.yaml index 3f6d5e04b026..04a6b33f1e68 100644 --- a/packages/url_launcher/url_launcher_macos/pubspec.yaml +++ b/packages/url_launcher/url_launcher_macos/pubspec.yaml @@ -1,6 +1,6 @@ name: url_launcher_macos description: macOS implementation of the url_launcher plugin. -version: 0.0.1+4 +version: 0.0.1+5 homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_macos flutter: From 3489dfd10b09035e92a242961af892260473e3ec Mon Sep 17 00:00:00 2001 From: Jaideep Prasad Date: Fri, 28 Feb 2020 08:28:41 +0530 Subject: [PATCH 10/37] [share] plugin: Update gradle version of example for Android (#2555) Fixes [TAG] Warnings and errors caused as generated on Android Studio build terminal while buidling. --- packages/share/CHANGELOG.md | 4 ++++ .../example/android/gradle/wrapper/gradle-wrapper.properties | 2 +- packages/share/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/share/CHANGELOG.md b/packages/share/CHANGELOG.md index 9bd0dec06766..7308189cbe18 100644 --- a/packages/share/CHANGELOG.md +++ b/packages/share/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.3+7 + +* Updated gradle version of example. + ## 0.6.3+6 * Make the pedantic dev_dependency explicit. diff --git a/packages/share/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/share/example/android/gradle/wrapper/gradle-wrapper.properties index 019065d1d650..d757f3d33fcc 100644 --- a/packages/share/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/share/example/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip diff --git a/packages/share/pubspec.yaml b/packages/share/pubspec.yaml index dc5f95a8afef..f7830a841249 100644 --- a/packages/share/pubspec.yaml +++ b/packages/share/pubspec.yaml @@ -2,7 +2,7 @@ name: share description: Flutter plugin for sharing content via the platform share UI, using the ACTION_SEND intent on Android and UIActivityViewController on iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/share -version: 0.6.3+6 +version: 0.6.3+7 flutter: plugin: From e87d73d1c7d099801136c1cf8d3a59b4260b45fc Mon Sep 17 00:00:00 2001 From: Francisco Magdaleno Date: Fri, 28 Feb 2020 10:34:11 -0800 Subject: [PATCH 11/37] [path_provider_platform_interface] Rename back to StorageDirectory (#2564) * Rename StorageDirectory * Update version * Update version to non-breaking * Use 1.0.1 --- .../path_provider_platform_interface/CHANGELOG.md | 4 ++++ .../lib/path_provider_platform_interface.dart | 4 ++-- .../path_provider_platform_interface/lib/src/enums.dart | 2 +- .../lib/src/method_channel_path_provider.dart | 2 +- .../path_provider_platform_interface/pubspec.yaml | 2 +- .../test/method_channel_path_provider_test.dart | 4 ++-- 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/path_provider/path_provider_platform_interface/CHANGELOG.md b/packages/path_provider/path_provider_platform_interface/CHANGELOG.md index 0d8803f93540..d577554afe2f 100644 --- a/packages/path_provider/path_provider_platform_interface/CHANGELOG.md +++ b/packages/path_provider/path_provider_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.1 + +* Rename enum to StorageDirectory for backwards compatibility. + ## 1.0.0 * Initial release. diff --git a/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart b/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart index 72aadf35b3e8..4f796aaeec33 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/path_provider_platform_interface.dart @@ -85,9 +85,9 @@ abstract class PathProviderPlatform extends PlatformInterface { /// These paths typically reside on external storage like separate partitions /// or SD cards. Phones may have multiple storage directories available. Future> getExternalStoragePaths({ - /// Optional parameter. See [AndroidStorageDirectory] for more informations on + /// Optional parameter. See [StorageDirectory] for more informations on /// how this type translates to Android storage directories. - AndroidStorageDirectory type, + StorageDirectory type, }) { throw UnimplementedError( 'getExternalStoragePaths() has not been implemented.'); diff --git a/packages/path_provider/path_provider_platform_interface/lib/src/enums.dart b/packages/path_provider/path_provider_platform_interface/lib/src/enums.dart index cf04a164203f..c97ef5d2b0f5 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/src/enums.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/src/enums.dart @@ -1,7 +1,7 @@ /// Corresponds to constants defined in Androids `android.os.Environment` class. /// /// https://developer.android.com/reference/android/os/Environment.html#fields_1 -enum AndroidStorageDirectory { +enum StorageDirectory { /// Contains audio files that should be treated as music. /// /// See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_MUSIC. diff --git a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart index acac9d5fe7af..7826fa4365be 100644 --- a/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart +++ b/packages/path_provider/path_provider_platform_interface/lib/src/method_channel_path_provider.dart @@ -66,7 +66,7 @@ class MethodChannelPathProvider extends PathProviderPlatform { } Future> getExternalStoragePaths({ - AndroidStorageDirectory type, + StorageDirectory type, }) async { if (!_platform.isAndroid) { throw UnsupportedError('Functionality only available on Android'); diff --git a/packages/path_provider/path_provider_platform_interface/pubspec.yaml b/packages/path_provider/path_provider_platform_interface/pubspec.yaml index 44bc0c2c161c..72f4b20b7e0c 100644 --- a/packages/path_provider/path_provider_platform_interface/pubspec.yaml +++ b/packages/path_provider/path_provider_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the path_provider plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_platform_interface # 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 dependencies: flutter: diff --git a/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart b/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart index c21acdb140b6..99c9349f9ae5 100644 --- a/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart +++ b/packages/path_provider/path_provider_platform_interface/test/method_channel_path_provider_test.dart @@ -147,8 +147,8 @@ void main() { } }); - for (AndroidStorageDirectory type - in AndroidStorageDirectory.values + [null]) { + for (StorageDirectory type + in StorageDirectory.values + [null]) { test('getExternalStoragePaths (type: $type) android succeeds', () async { final List result = await methodChannelPathProvider.getExternalStoragePaths(type: type); From 20d3d304c15f8e1d295d768699a736b5c5416d8f Mon Sep 17 00:00:00 2001 From: Nurhan Turgut Date: Fri, 28 Feb 2020 12:48:32 -0800 Subject: [PATCH 12/37] [web] adding a test for e2e web testing. (#2554) * adding a test for e2e web testing. * chaning the changelog. updating pubspec.yaml version. fixing analyze * merging the changelog * addressing reviewer comments * fix format. addressing reviewer comments * try to run chromedriver on the backend * chrome driver is was running as the main task, preventing test from running . use background_task to run it. use ENV for directory change * change in scripts. remove list from backfround task. change argument of driver * removed background task. it wasn't using the same path * run web tests only on browser * add test on to the web driver test as well. drive-examples are still failing * fix the imports * trying reviever suggestion for drive_example compile errors * test _ imports * Revert "test _ imports" This reverts commit 7cf24d6cb5833efa437a78cf5b843eb6b6368a81. * removing the web_test driver file upon reviewers suggestion * format fix --- .cirrus.yml | 15 ++++++++ packages/e2e/CHANGELOG.md | 4 ++ packages/e2e/README.md | 9 +++++ packages/e2e/example/lib/main.dart | 26 +------------ packages/e2e/example/lib/my_app.dart | 27 ++++++++++++++ packages/e2e/example/lib/my_web_app.dart | 28 ++++++++++++++ .../e2e/example/test_driver/example_e2e.dart | 21 ++--------- .../example/test_driver/example_e2e_io.dart | 34 +++++++++++++++++ .../example/test_driver/example_e2e_web.dart | 35 ++++++++++++++++++ packages/e2e/example/test_driver/failure.dart | 6 +-- packages/e2e/example/web/favicon.png | Bin 0 -> 917 bytes packages/e2e/example/web/icons/Icon-192.png | Bin 0 -> 5292 bytes packages/e2e/example/web/icons/Icon-512.png | Bin 0 -> 8252 bytes packages/e2e/example/web/index.html | 33 +++++++++++++++++ packages/e2e/example/web/manifest.json | 23 ++++++++++++ packages/e2e/lib/e2e.dart | 6 +++ packages/e2e/pubspec.yaml | 2 +- 17 files changed, 223 insertions(+), 46 deletions(-) create mode 100644 packages/e2e/example/lib/my_app.dart create mode 100644 packages/e2e/example/lib/my_web_app.dart create mode 100644 packages/e2e/example/test_driver/example_e2e_io.dart create mode 100644 packages/e2e/example/test_driver/example_e2e_web.dart create mode 100644 packages/e2e/example/web/favicon.png create mode 100644 packages/e2e/example/web/icons/Icon-192.png create mode 100644 packages/e2e/example/web/icons/Icon-512.png create mode 100644 packages/e2e/example/web/index.html create mode 100644 packages/e2e/example/web/manifest.json diff --git a/.cirrus.yml b/.cirrus.yml index 1236002fecd6..753bc90911ae 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -6,6 +6,8 @@ task: dockerfile: .ci/Dockerfile cpu: 8 memory: 16G + env: + E2E_PATH: "./packages/e2e" upgrade_script: - flutter channel stable - flutter upgrade @@ -45,6 +47,19 @@ task: - if [[ "$CHANNEL" -eq "stable" ]]; then find . | grep _web$ | xargs rm -rf; fi - flutter channel $CHANNEL - ./script/build_all_plugins_app.sh apk + - name: e2e_web_smoke_test + # Tests e2e example test in web. + only_if: "changesInclude('.cirrus.yml', 'packages/e2e/**') || $CIRRUS_PR == ''" + install_script: + - flutter config --enable-web + - git clone https://github.com/flutter/web_installers.git + - cd web_installers/packages/web_drivers/ + - pub get + - dart lib/web_driver_installer.dart chromedriver --install-only + - ./chromedriver/chromedriver --port=4444 & + test_script: + - cd $E2E_PATH/example/ + - flutter drive -v --target=test_driver/example_e2e.dart -d web-server --release --browser-name=chrome - name: build-apks+java-test+firebase-test-lab env: matrix: diff --git a/packages/e2e/CHANGELOG.md b/packages/e2e/CHANGELOG.md index 35d3159e05b4..86f37b291549 100644 --- a/packages/e2e/CHANGELOG.md +++ b/packages/e2e/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.4+4 + +* Fixed a hang that occurred on platforms that don't have a `MethodChannel` listener registered.. + ## 0.2.4+3 * Fixed code snippet in the readme under the "Using Flutter driver to run tests" section. diff --git a/packages/e2e/README.md b/packages/e2e/README.md index ed892ab6e7ff..3e27ff36afa3 100644 --- a/packages/e2e/README.md +++ b/packages/e2e/README.md @@ -69,6 +69,15 @@ cd example flutter drive --driver=test_driver/_test.dart test/_e2e.dart ``` +You can run tests on web on release mode. + +First you need to make sure you have downloaded the driver for the browser. + +``` +cd example +flutter drive -v --target=test_driver/dart -d web-server --release --browser-name=chrome +``` + ## Android device testing Create an instrumentation test file in your application's diff --git a/packages/e2e/example/lib/main.dart b/packages/e2e/example/lib/main.dart index 2509fb390ff4..1f33324acd01 100644 --- a/packages/e2e/example/lib/main.dart +++ b/packages/e2e/example/lib/main.dart @@ -1,27 +1,5 @@ -import 'dart:io' show Platform; -import 'package:flutter/material.dart'; +import 'my_app.dart' if (dart.library.html) 'my_web_app.dart'; // ignore_for_file: public_member_api_docs -void main() => runApp(MyApp()); - -class MyApp extends StatefulWidget { - @override - _MyAppState createState() => _MyAppState(); -} - -class _MyAppState extends State { - @override - Widget build(BuildContext context) { - return MaterialApp( - home: Scaffold( - appBar: AppBar( - title: const Text('Plugin example app'), - ), - body: Center( - child: Text('Platform: ${Platform.operatingSystem}\n'), - ), - ), - ); - } -} +void main() => startApp(); diff --git a/packages/e2e/example/lib/my_app.dart b/packages/e2e/example/lib/my_app.dart new file mode 100644 index 000000000000..bfbdb860c76d --- /dev/null +++ b/packages/e2e/example/lib/my_app.dart @@ -0,0 +1,27 @@ +import 'dart:io' show Platform; +import 'package:flutter/material.dart'; + +// ignore_for_file: public_member_api_docs + +void startApp() => runApp(MyApp()); + +class MyApp extends StatefulWidget { + @override + _MyAppState createState() => _MyAppState(); +} + +class _MyAppState extends State { + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + appBar: AppBar( + title: const Text('Plugin example app'), + ), + body: Center( + child: Text('Platform: ${Platform.operatingSystem}\n'), + ), + ), + ); + } +} diff --git a/packages/e2e/example/lib/my_web_app.dart b/packages/e2e/example/lib/my_web_app.dart new file mode 100644 index 000000000000..c2ced1af97ae --- /dev/null +++ b/packages/e2e/example/lib/my_web_app.dart @@ -0,0 +1,28 @@ +import 'dart:html' as html; +import 'package:flutter/material.dart'; + +// ignore_for_file: public_member_api_docs + +void startApp() => runApp(MyWebApp()); + +class MyWebApp extends StatefulWidget { + @override + _MyWebAppState createState() => _MyWebAppState(); +} + +class _MyWebAppState extends State { + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + appBar: AppBar( + title: const Text('Plugin example app'), + ), + body: Center( + key: Key('mainapp'), + child: Text('Platform: ${html.window.navigator.platform}\n'), + ), + ), + ); + } +} diff --git a/packages/e2e/example/test_driver/example_e2e.dart b/packages/e2e/example/test_driver/example_e2e.dart index e91dd4d0ce9f..d97702d5d7cf 100644 --- a/packages/e2e/example/test_driver/example_e2e.dart +++ b/packages/e2e/example/test_driver/example_e2e.dart @@ -5,27 +5,12 @@ // gestures. You can also use WidgetTester to find child widgets in the widget // tree, read text, and verify that the values of widget properties are correct. -import 'dart:io' show Platform; -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; import 'package:e2e/e2e.dart'; -import 'package:e2e_example/main.dart'; +import 'example_e2e_io.dart' if (dart.library.html) 'example_e2e_web.dart' + as tests; void main() { E2EWidgetsFlutterBinding.ensureInitialized(); - testWidgets('verify text', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that platform version is retrieved. - expect( - find.byWidgetPredicate( - (Widget widget) => - widget is Text && - widget.data.startsWith('Platform: ${Platform.operatingSystem}'), - ), - findsOneWidget, - ); - }); + tests.main(); } diff --git a/packages/e2e/example/test_driver/example_e2e_io.dart b/packages/e2e/example/test_driver/example_e2e_io.dart new file mode 100644 index 000000000000..9766f568b654 --- /dev/null +++ b/packages/e2e/example/test_driver/example_e2e_io.dart @@ -0,0 +1,34 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'dart:io' show Platform; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:e2e/e2e.dart'; + +import 'package:e2e_example/main.dart' as app; + +void main() { + E2EWidgetsFlutterBinding.ensureInitialized(); + testWidgets('verify text', (WidgetTester tester) async { + // Build our app and trigger a frame. + app.main(); + + // Trigger a frame. + await tester.pumpAndSettle(); + + // Verify that platform version is retrieved. + expect( + find.byWidgetPredicate( + (Widget widget) => + widget is Text && + widget.data.startsWith('Platform: ${Platform.operatingSystem}'), + ), + findsOneWidget, + ); + }); +} diff --git a/packages/e2e/example/test_driver/example_e2e_web.dart b/packages/e2e/example/test_driver/example_e2e_web.dart new file mode 100644 index 000000000000..24c3f2cbb2a4 --- /dev/null +++ b/packages/e2e/example/test_driver/example_e2e_web.dart @@ -0,0 +1,35 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'dart:html' as html; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:e2e/e2e.dart'; + +import 'package:e2e_example/main.dart' as app; + +void main() { + E2EWidgetsFlutterBinding.ensureInitialized(); + testWidgets('verify text', (WidgetTester tester) async { + // Build our app and trigger a frame. + app.main(); + + // Trigger a frame. + await tester.pumpAndSettle(); + + // Verify that platform is retrieved. + expect( + find.byWidgetPredicate( + (Widget widget) => + widget is Text && + widget.data + .startsWith('Platform: ${html.window.navigator.platform}\n'), + ), + findsOneWidget, + ); + }); +} diff --git a/packages/e2e/example/test_driver/failure.dart b/packages/e2e/example/test_driver/failure.dart index 64d83bf5c13b..ddeeb800bb06 100644 --- a/packages/e2e/example/test_driver/failure.dart +++ b/packages/e2e/example/test_driver/failure.dart @@ -6,7 +6,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:e2e/e2e.dart'; -import 'package:e2e_example/main.dart'; +import 'package:e2e_example/main.dart' as app; // Tests the failure behavior of the E2EWidgetsFlutterBinding // @@ -21,10 +21,10 @@ void main() { testWidgets('failure 1', (WidgetTester tester) async { // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); + app.main(); // Verify that platform version is retrieved. - expect( + await expectLater( find.byWidgetPredicate( (Widget widget) => widget is Text && widget.data.startsWith('This should fail'), diff --git a/packages/e2e/example/web/favicon.png b/packages/e2e/example/web/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..8aaa46ac1ae21512746f852a42ba87e4165dfdd1 GIT binary patch literal 917 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|I14-?iy0X7 zltGxWVyS%@P(fs7NJL45ua8x7ey(0(N`6wRUPW#JP&EUCO@$SZnVVXYs8ErclUHn2 zVXFjIVFhG^g!Ppaz)DK8ZIvQ?0~DO|i&7O#^-S~(l1AfjnEK zjFOT9D}DX)@^Za$W4-*MbbUihOG|wNBYh(yU7!lx;>x^|#0uTKVr7USFmqf|i<65o z3raHc^AtelCMM;Vme?vOfh>Xph&xL%(-1c06+^uR^q@XSM&D4+Kp$>4P^%3{)XKjo zGZknv$b36P8?Z_gF{nK@`XI}Z90TzwSQO}0J1!f2c(B=V`5aP@1P1a|PZ!4!3&Gl8 zTYqUsf!gYFyJnXpu0!n&N*SYAX-%d(5gVjrHJWqXQshj@!Zm{!01WsQrH~9=kTxW#6SvuapgMqt>$=j#%eyGrQzr zP{L-3gsMA^$I1&gsBAEL+vxi1*Igl=8#8`5?A-T5=z-sk46WA1IUT)AIZHx1rdUrf zVJrJn<74DDw`j)Ki#gt}mIT-Q`XRa2-jQXQoI%w`nb|XblvzK${ZzlV)m-XcwC(od z71_OEC5Bt9GEXosOXaPTYOia#R4ID2TiU~`zVMl08TV_C%DnU4^+HE>9(CE4D6?Fz oujB08i7adh9xk7*FX66dWH6F5TM;?E2b5PlUHx3vIVCg!0Dx9vYXATM literal 0 HcmV?d00001 diff --git a/packages/e2e/example/web/icons/Icon-192.png b/packages/e2e/example/web/icons/Icon-192.png new file mode 100644 index 0000000000000000000000000000000000000000..b749bfef07473333cf1dd31e9eed89862a5d52aa GIT binary patch literal 5292 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 literal 0 HcmV?d00001 diff --git a/packages/e2e/example/web/icons/Icon-512.png b/packages/e2e/example/web/icons/Icon-512.png new file mode 100644 index 0000000000000000000000000000000000000000..88cfd48dff1169879ba46840804b412fe02fefd6 GIT binary patch literal 8252 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 literal 0 HcmV?d00001 diff --git a/packages/e2e/example/web/index.html b/packages/e2e/example/web/index.html new file mode 100644 index 000000000000..96629657328f --- /dev/null +++ b/packages/e2e/example/web/index.html @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + example + + + + + + + + diff --git a/packages/e2e/example/web/manifest.json b/packages/e2e/example/web/manifest.json new file mode 100644 index 000000000000..c63800102369 --- /dev/null +++ b/packages/e2e/example/web/manifest.json @@ -0,0 +1,23 @@ +{ + "name": "example", + "short_name": "example", + "start_url": ".", + "display": "minimal-ui", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + } + ] +} diff --git a/packages/e2e/lib/e2e.dart b/packages/e2e/lib/e2e.dart index afcbeb0d703e..eef594a6f99e 100644 --- a/packages/e2e/lib/e2e.dart +++ b/packages/e2e/lib/e2e.dart @@ -19,6 +19,12 @@ class E2EWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding { // TODO(jackson): Report test results as they arrive tearDownAll(() async { try { + // For web integration tests we are not using the + // `plugins.flutter.io/e2e`. Mark the tests as complete before invoking + // the channel. + if (kIsWeb) { + if (!_allTestsPassed.isCompleted) _allTestsPassed.complete(true); + } await _channel.invokeMethod( 'allTestsFinished', {'results': _results}); } on MissingPluginException { diff --git a/packages/e2e/pubspec.yaml b/packages/e2e/pubspec.yaml index 68735867218c..21e1210bd23e 100644 --- a/packages/e2e/pubspec.yaml +++ b/packages/e2e/pubspec.yaml @@ -1,6 +1,6 @@ name: e2e description: Runs tests that use the flutter_test API as integration tests. -version: 0.2.4+3 +version: 0.2.4+4 homepage: https://github.com/flutter/plugins/tree/master/packages/e2e environment: From 122a11e4883ac4186d207c39a9861f2dca15c6af Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Mon, 2 Mar 2020 07:08:46 -0800 Subject: [PATCH 13/37] Connectivity deprecation fix --- .../plugins/connectivity/ConnectivityBroadcastReceiver.java | 2 +- packages/connectivity/connectivity/lib/connectivity.dart | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityBroadcastReceiver.java b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityBroadcastReceiver.java index be8b47eff944..db3f79595e63 100644 --- a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityBroadcastReceiver.java +++ b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityBroadcastReceiver.java @@ -33,7 +33,7 @@ class ConnectivityBroadcastReceiver extends BroadcastReceiver @Override public void onListen(Object arguments, EventChannel.EventSink events) { this.events = events; - context.registerReceiver(this, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); + context.registerReceiver(this, new IntentFilter(ConnectivityManager.CONNECTIVITY_CHANGE)); } @Override diff --git a/packages/connectivity/connectivity/lib/connectivity.dart b/packages/connectivity/connectivity/lib/connectivity.dart index a5d9f25089cf..51363c93e7ea 100644 --- a/packages/connectivity/connectivity/lib/connectivity.dart +++ b/packages/connectivity/connectivity/lib/connectivity.dart @@ -33,6 +33,8 @@ class Connectivity { static ConnectivityPlatform get _platform => ConnectivityPlatform.instance; /// Fires whenever the connectivity state changes. + /// + /// Apps targeting Android N do not receive notifications in the background. Stream get onConnectivityChanged { return _platform.onConnectivityChanged; } From a53b5e1a7be2a1f599ac24bcaa9dc3697714c8d7 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Mon, 2 Mar 2020 07:11:33 -0800 Subject: [PATCH 14/37] Revert "Connectivity deprecation fix" This reverts commit 7d62e8c076c0b35042e125b26ad4e97410170209 which landed on the wrong branch. --- .../plugins/connectivity/ConnectivityBroadcastReceiver.java | 2 +- packages/connectivity/connectivity/lib/connectivity.dart | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityBroadcastReceiver.java b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityBroadcastReceiver.java index db3f79595e63..be8b47eff944 100644 --- a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityBroadcastReceiver.java +++ b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityBroadcastReceiver.java @@ -33,7 +33,7 @@ class ConnectivityBroadcastReceiver extends BroadcastReceiver @Override public void onListen(Object arguments, EventChannel.EventSink events) { this.events = events; - context.registerReceiver(this, new IntentFilter(ConnectivityManager.CONNECTIVITY_CHANGE)); + context.registerReceiver(this, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); } @Override diff --git a/packages/connectivity/connectivity/lib/connectivity.dart b/packages/connectivity/connectivity/lib/connectivity.dart index 51363c93e7ea..a5d9f25089cf 100644 --- a/packages/connectivity/connectivity/lib/connectivity.dart +++ b/packages/connectivity/connectivity/lib/connectivity.dart @@ -33,8 +33,6 @@ class Connectivity { static ConnectivityPlatform get _platform => ConnectivityPlatform.instance; /// Fires whenever the connectivity state changes. - /// - /// Apps targeting Android N do not receive notifications in the background. Stream get onConnectivityChanged { return _platform.onConnectivityChanged; } From 0fd6b865dd5c329972bc8e2430ce54abe66a6309 Mon Sep 17 00:00:00 2001 From: Francisco Magdaleno Date: Mon, 2 Mar 2020 11:21:59 -0800 Subject: [PATCH 15/37] [path_provider] Use platform interface (#2557) * Add dart file * Rename file * add interface, rename files, add methods to class * Add to method channel, not done * Add dart file * Rename file * Adds method channel test * Remove prints * Fix imports and version * Format and commentas * Space * Rename apis to path and provide only the string from the platform * Add test and remove null * Format * Add export * Add imports * Completed apis * Fix and works * Improve tests * Remove asyncs * Add imports * Completed apis * Fix and works * Update version * Finish test * Make results per test * Fix * Add dependency * Fix typo nad enum * Change interface version * Address comments * Remove mock call * Typo and import * Remove file --- .../path_provider/path_provider/CHANGELOG.md | 4 + .../contents.xcworkspacedata | 7 - .../path_provider/lib/path_provider.dart | 112 +------ .../path_provider/path_provider/pubspec.yaml | 7 +- .../test/path_provider_test.dart | 289 +++++------------- 5 files changed, 102 insertions(+), 317 deletions(-) delete mode 100644 packages/path_provider/path_provider/example/macos/Runner.xcworkspace/contents.xcworkspacedata diff --git a/packages/path_provider/path_provider/CHANGELOG.md b/packages/path_provider/path_provider/CHANGELOG.md index 439c0c52cdda..3540e20e5141 100644 --- a/packages/path_provider/path_provider/CHANGELOG.md +++ b/packages/path_provider/path_provider/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.3 + +* Use `path_provider_platform_interface` in core plugin. + ## 1.6.2 * Move package contents into `path_provider` for platform federation. diff --git a/packages/path_provider/path_provider/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/packages/path_provider/path_provider/example/macos/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 1d526a16ed0f..000000000000 --- a/packages/path_provider/path_provider/example/macos/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/packages/path_provider/path_provider/lib/path_provider.dart b/packages/path_provider/path_provider/lib/path_provider.dart index b27cc4bc3fcb..a7643264d52a 100644 --- a/packages/path_provider/path_provider/lib/path_provider.dart +++ b/packages/path_provider/path_provider/lib/path_provider.dart @@ -5,21 +5,12 @@ import 'dart:async'; import 'dart:io' show Directory; -import 'package:flutter/services.dart'; -import 'package:meta/meta.dart'; -import 'package:platform/platform.dart'; +import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; -const MethodChannel _channel = - MethodChannel('plugins.flutter.io/path_provider'); +export 'package:path_provider_platform_interface/path_provider_platform_interface.dart' + show StorageDirectory; -Platform _platform = const LocalPlatform(); - -/// This API is only exposed for the unit tests. It should not be used by -/// any code outside of the plugin itself. -@visibleForTesting -void setMockPathProviderPlatform(Platform platform) { - _platform = platform; -} +PathProviderPlatform get _platform => PathProviderPlatform.instance; /// Path to the temporary directory on the device that is not backed up and is /// suitable for storing caches of downloaded files. @@ -33,8 +24,7 @@ void setMockPathProviderPlatform(Platform platform) { /// /// On Android, this uses the `getCacheDir` API on the context. Future getTemporaryDirectory() async { - final String path = - await _channel.invokeMethod('getTemporaryDirectory'); + final String path = await _platform.getTemporaryPath(); if (path == null) { return null; } @@ -52,8 +42,7 @@ Future getTemporaryDirectory() async { /// /// On Android, this function uses the `getFilesDir` API on the context. Future getApplicationSupportDirectory() async { - final String path = - await _channel.invokeMethod('getApplicationSupportDirectory'); + final String path = await _platform.getApplicationSupportPath(); if (path == null) { return null; } @@ -67,11 +56,7 @@ Future getApplicationSupportDirectory() async { /// On Android, this function throws an [UnsupportedError] as no equivalent /// path exists. Future getLibraryDirectory() async { - if (_platform.isAndroid) { - throw UnsupportedError('Functionality not available on Android'); - } - final String path = - await _channel.invokeMethod('getLibraryDirectory'); + final String path = await _platform.getLibraryPath(); if (path == null) { return null; } @@ -88,8 +73,7 @@ Future getLibraryDirectory() async { /// using [getExternalStorageDirectory] instead if data is intended to be visible /// to the user. Future getApplicationDocumentsDirectory() async { - final String path = - await _channel.invokeMethod('getApplicationDocumentsDirectory'); + final String path = await _platform.getApplicationDocumentsPath(); if (path == null) { return null; } @@ -105,11 +89,7 @@ Future getApplicationDocumentsDirectory() async { /// /// On Android this uses the `getExternalFilesDir(null)`. Future getExternalStorageDirectory() async { - if (_platform.isIOS) { - throw UnsupportedError('Functionality not available on iOS'); - } - final String path = - await _channel.invokeMethod('getStorageDirectory'); + final String path = await _platform.getExternalStoragePath(); if (path == null) { return null; } @@ -130,65 +110,11 @@ Future getExternalStorageDirectory() async { /// On Android this returns Context.getExternalCacheDirs() or /// Context.getExternalCacheDir() on API levels below 19. Future> getExternalCacheDirectories() async { - if (_platform.isIOS) { - throw UnsupportedError('Functionality not available on iOS'); - } - final List paths = - await _channel.invokeListMethod('getExternalCacheDirectories'); + final List paths = await _platform.getExternalCachePaths(); return paths.map((String path) => Directory(path)).toList(); } -/// Corresponds to constants defined in Androids `android.os.Environment` class. -/// -/// https://developer.android.com/reference/android/os/Environment.html#fields_1 -enum StorageDirectory { - /// Contains audio files that should be treated as music. - /// - /// See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_MUSIC. - music, - - /// Contains audio files that should be treated as podcasts. - /// - /// See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_PODCASTS. - podcasts, - - /// Contains audio files that should be treated as ringtones. - /// - /// See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_RINGTONES. - ringtones, - - /// Contains audio files that should be treated as alarm sounds. - /// - /// See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_ALARMS. - alarms, - - /// Contains audio files that should be treated as notification sounds. - /// - /// See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_NOTIFICATIONS. - notifications, - - /// Contains images. See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_PICTURES. - pictures, - - /// Contains movies. See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_MOVIES. - movies, - - /// Contains files of any type that have been downloaded by the user. - /// - /// See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_DOWNLOADS. - downloads, - - /// Used to hold both pictures and videos when the device filesystem is - /// treated like a camera's. - /// - /// See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_DCIM. - dcim, - - /// Holds user-created documents. See https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_DOCUMENTS. - documents, -} - /// Paths to directories where application specific data can be stored. /// These paths typically reside on external storage like separate partitions /// or SD cards. Phones may have multiple storage directories available. @@ -206,13 +132,8 @@ Future> getExternalStorageDirectories({ /// how this type translates to Android storage directories. StorageDirectory type, }) async { - if (_platform.isIOS) { - throw UnsupportedError('Functionality not available on iOS'); - } - final List paths = await _channel.invokeListMethod( - 'getExternalStorageDirectories', - {'type': type?.index}, - ); + final List paths = + await _platform.getExternalStoragePaths(type: type); return paths.map((String path) => Directory(path)).toList(); } @@ -223,14 +144,7 @@ Future> getExternalStorageDirectories({ /// On Android and on iOS, this function throws an [UnsupportedError] as no equivalent /// path exists. Future getDownloadsDirectory() async { - if (_platform.isAndroid) { - throw UnsupportedError('Functionality not available on Android'); - } - if (_platform.isIOS) { - throw UnsupportedError('Functionality not available on iOS'); - } - final String path = - await _channel.invokeMethod('getDownloadsDirectory'); + final String path = await _platform.getDownloadsPath(); if (path == null) { return null; } diff --git a/packages/path_provider/path_provider/pubspec.yaml b/packages/path_provider/path_provider/pubspec.yaml index df26c5e06899..c20d83b32542 100644 --- a/packages/path_provider/path_provider/pubspec.yaml +++ b/packages/path_provider/path_provider/pubspec.yaml @@ -2,7 +2,7 @@ name: path_provider description: Flutter plugin for getting commonly used locations on the Android & iOS file systems, such as the temp and app data directories. homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider -version: 1.6.2 +version: 1.6.3 flutter: plugin: @@ -16,8 +16,7 @@ flutter: dependencies: flutter: sdk: flutter - platform: ^2.0.0 - meta: ^1.0.5 + path_provider_platform_interface: ^1.0.1 dev_dependencies: e2e: ^0.2.1 @@ -28,6 +27,8 @@ dev_dependencies: test: any uuid: "^1.0.0" pedantic: ^1.8.0 + mockito: ^4.1.1 + plugin_platform_interface: ^1.0.0 environment: sdk: ">=2.0.0-dev.28.0 <3.0.0" diff --git a/packages/path_provider/path_provider/test/path_provider_test.dart b/packages/path_provider/path_provider/test/path_provider_test.dart index 5b875e3bc51e..eb17178b9975 100644 --- a/packages/path_provider/path_provider/test/path_provider_test.dart +++ b/packages/path_provider/path_provider/test/path_provider_test.dart @@ -2,236 +2,109 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:io'; +import 'dart:io' show Directory; +import 'dart:async'; -import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; import 'package:path_provider/path_provider.dart'; -import 'package:platform/platform.dart'; +import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; -void main() { - TestWidgetsFlutterBinding.ensureInitialized(); - - const MethodChannel channel = - MethodChannel('plugins.flutter.io/path_provider'); - final List log = []; - dynamic response; - - channel.setMockMethodCallHandler((MethodCall methodCall) async { - log.add(methodCall); - return response; - }); - - setUp(() { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'android')); - }); - - tearDown(() { - log.clear(); - }); - - test('getTemporaryDirectory test', () async { - response = null; - final Directory directory = await getTemporaryDirectory(); - expect( - log, - [isMethodCall('getTemporaryDirectory', arguments: null)], - ); - expect(directory, isNull); - }); - - test('getApplicationSupportDirectory test', () async { - response = null; - final Directory directory = await getApplicationSupportDirectory(); - expect( - log, - [ - isMethodCall('getApplicationSupportDirectory', arguments: null) - ], - ); - expect(directory, isNull); - }); - - test('getApplicationDocumentsDirectory test', () async { - response = null; - final Directory directory = await getApplicationDocumentsDirectory(); - expect( - log, - [ - isMethodCall('getApplicationDocumentsDirectory', arguments: null) - ], - ); - expect(directory, isNull); - }); - - test('getApplicationSupportDirectory test', () async { - response = null; - final Directory directory = await getApplicationSupportDirectory(); - expect( - log, - [ - isMethodCall('getApplicationSupportDirectory', arguments: null) - ], - ); - expect(directory, isNull); - }); +const String kTemporaryPath = 'temporaryPath'; +const String kApplicationSupportPath = 'applicationSupportPath'; +const String kDownloadsPath = 'downloadsPath'; +const String kLibraryPath = 'libraryPath'; +const String kApplicationDocumentsPath = 'applicationDocumentsPath'; +const String kExternalCachePath = 'externalCachePath'; +const String kExternalStoragePath = 'externalStoragePath'; - test('getExternalStorageDirectory test', () async { - response = null; - final Directory directory = await getExternalStorageDirectory(); - expect( - log, - [isMethodCall('getStorageDirectory', arguments: null)], - ); - expect(directory, isNull); - }); - - test('getLibraryDirectory Android test', () async { - try { - await getLibraryDirectory(); - fail('should throw UnsupportedError'); - } catch (e) { - expect(e, isUnsupportedError); - } - }); - test('getLibraryDirectory iOS test', () async { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); - - final Directory directory = await getLibraryDirectory(); - expect( - log, - [isMethodCall('getLibraryDirectory', arguments: null)], - ); - expect(directory, isNull); - }); - - test('getExternalStorageDirectory iOS test', () async { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); +void main() { + group('PathProvider', () { + TestWidgetsFlutterBinding.ensureInitialized(); - try { - await getExternalStorageDirectory(); - fail('should throw UnsupportedError'); - } catch (e) { - expect(e, isUnsupportedError); - } - }); + setUp(() async { + PathProviderPlatform.instance = MockPathProviderPlatform(); + }); - test('getExternalCacheDirectories test', () async { - response = []; - final List directories = await getExternalCacheDirectories(); - expect( - log, - [isMethodCall('getExternalCacheDirectories', arguments: null)], - ); - expect(directories, []); - }); + test('getTemporaryDirectory', () async { + Directory result = await getTemporaryDirectory(); + expect(result.path, kTemporaryPath); + }); - test('getExternalCacheDirectories iOS test', () async { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); + test('getApplicationSupportDirectory', () async { + Directory result = await getApplicationSupportDirectory(); + expect(result.path, kApplicationSupportPath); + }); - try { - await getExternalCacheDirectories(); - fail('should throw UnsupportedError'); - } catch (e) { - expect(e, isUnsupportedError); - } - }); + test('getLibraryDirectory', () async { + Directory result = await getLibraryDirectory(); + expect(result.path, kLibraryPath); + }); - for (StorageDirectory type - in StorageDirectory.values + [null]) { - test('getExternalStorageDirectories test (type: $type)', () async { - response = []; - final List directories = - await getExternalStorageDirectories(type: type); - expect( - log, - [ - isMethodCall( - 'getExternalStorageDirectories', - arguments: {'type': type?.index}, - ) - ], - ); - expect(directories, []); + test('getApplicationDocumentsDirectory', () async { + Directory result = await getApplicationDocumentsDirectory(); + expect(result.path, kApplicationDocumentsPath); }); - } - test('getExternalStorageDirectories iOS test', () async { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); + test('getExternalStorageDirectory', () async { + Directory result = await getExternalStorageDirectory(); + expect(result.path, kExternalStoragePath); + }); - try { - await getExternalStorageDirectories(type: StorageDirectory.music); - fail('should throw UnsupportedError'); - } catch (e) { - expect(e, isUnsupportedError); - } - }); + test('getExternalCacheDirectories', () async { + List result = await getExternalCacheDirectories(); + expect(result.length, 1); + expect(result.first.path, kExternalCachePath); + }); - test('TemporaryDirectory path test', () async { - final String fakePath = "/foo/bar/baz"; - response = fakePath; - final Directory directory = await getTemporaryDirectory(); - expect(directory.path, equals(fakePath)); - }); + test('getExternalStorageDirectories', () async { + List result = await getExternalStorageDirectories(); + expect(result.length, 1); + expect(result.first.path, kExternalStoragePath); + }); - test('ApplicationSupportDirectory path test', () async { - final String fakePath = "/foo/bar/baz"; - response = fakePath; - final Directory directory = await getApplicationSupportDirectory(); - expect(directory.path, equals(fakePath)); + test('getDownloadsDirectory', () async { + Directory result = await getDownloadsDirectory(); + expect(result.path, kDownloadsPath); + }); }); +} - test('ApplicationDocumentsDirectory path test', () async { - final String fakePath = "/foo/bar/baz"; - response = fakePath; - final Directory directory = await getApplicationDocumentsDirectory(); - expect(directory.path, equals(fakePath)); - }); +class MockPathProviderPlatform extends Mock + with MockPlatformInterfaceMixin + implements PathProviderPlatform { + Future getTemporaryPath() async { + return kTemporaryPath; + } - test('ApplicationSupportDirectory path test', () async { - final String fakePath = "/foo/bar/baz"; - response = fakePath; - final Directory directory = await getApplicationSupportDirectory(); - expect(directory.path, equals(fakePath)); - }); + Future getApplicationSupportPath() async { + return kApplicationSupportPath; + } - test('ApplicationLibraryDirectory path test', () async { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'ios')); + Future getLibraryPath() async { + return kLibraryPath; + } - final String fakePath = "/foo/bar/baz"; - response = fakePath; - final Directory directory = await getLibraryDirectory(); - expect(directory.path, equals(fakePath)); - }); + Future getApplicationDocumentsPath() async { + return kApplicationDocumentsPath; + } - test('ExternalStorageDirectory path test', () async { - final String fakePath = "/foo/bar/baz"; - response = fakePath; - final Directory directory = await getExternalStorageDirectory(); - expect(directory.path, equals(fakePath)); - }); + Future getExternalStoragePath() async { + return kExternalStoragePath; + } - test('ExternalCacheDirectories path test', () async { - final List paths = ["/foo/bar/baz", "/foo/bar/baz2"]; - response = paths; - final List directories = await getExternalCacheDirectories(); - expect(directories.map((Directory d) => d.path).toList(), equals(paths)); - }); + Future> getExternalCachePaths() async { + return [kExternalCachePath]; + } - test('ExternalStorageDirectories path test', () async { - final List paths = ["/foo/bar/baz", "/foo/bar/baz2"]; - response = paths; - final List directories = await getExternalStorageDirectories( - type: StorageDirectory.music, - ); - expect(directories.map((Directory d) => d.path).toList(), equals(paths)); - }); + Future> getExternalStoragePaths({ + StorageDirectory type, + }) async { + return [kExternalStoragePath]; + } - test('DownloadsDirectory path macos test', () async { - setMockPathProviderPlatform(FakePlatform(operatingSystem: 'macos')); - final String fakePath = "/foo/bar/baz"; - response = fakePath; - final Directory directory = await getDownloadsDirectory(); - expect(directory.path, equals(fakePath)); - }); + Future getDownloadsPath() async { + return kDownloadsPath; + } } From 6dfb311d9f43a47883962e85bee75705fb0de349 Mon Sep 17 00:00:00 2001 From: Francisco Magdaleno Date: Mon, 2 Mar 2020 13:04:43 -0800 Subject: [PATCH 16/37] [path_provider] Endorse macOS implementation (#2566) --- .../path_provider/path_provider/CHANGELOG.md | 4 ++++ .../contents.xcworkspacedata | 10 +++++++++ .../path_provider/example/pubspec.yaml | 2 -- .../path_provider/macos/path_provider.podspec | 22 +++++++++++++++++++ .../path_provider/path_provider/pubspec.yaml | 7 +++++- 5 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 packages/path_provider/path_provider/example/macos/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 packages/path_provider/path_provider/macos/path_provider.podspec diff --git a/packages/path_provider/path_provider/CHANGELOG.md b/packages/path_provider/path_provider/CHANGELOG.md index 3540e20e5141..622d28d46693 100644 --- a/packages/path_provider/path_provider/CHANGELOG.md +++ b/packages/path_provider/path_provider/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.4 + +* Endorsed macOS implementation. + ## 1.6.3 * Use `path_provider_platform_interface` in core plugin. diff --git a/packages/path_provider/path_provider/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/packages/path_provider/path_provider/example/macos/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000000..21a3cc14c74e --- /dev/null +++ b/packages/path_provider/path_provider/example/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/packages/path_provider/path_provider/example/pubspec.yaml b/packages/path_provider/path_provider/example/pubspec.yaml index a82bc6e121a5..1d6a50c2ca0f 100644 --- a/packages/path_provider/path_provider/example/pubspec.yaml +++ b/packages/path_provider/path_provider/example/pubspec.yaml @@ -6,8 +6,6 @@ dependencies: sdk: flutter path_provider: path: ../ - path_provider_macos: - path: ../../path_provider_macos dev_dependencies: e2e: ^0.2.1 diff --git a/packages/path_provider/path_provider/macos/path_provider.podspec b/packages/path_provider/path_provider/macos/path_provider.podspec new file mode 100644 index 000000000000..9f3f01f2f858 --- /dev/null +++ b/packages/path_provider/path_provider/macos/path_provider.podspec @@ -0,0 +1,22 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# +Pod::Spec.new do |s| + s.name = 'path_provider' + s.version = '0.0.1' + s.summary = 'No-op implementation of the macos path_provider to avoid build issues on macos' + s.description = <<-DESC + No-op implementation of the path_provider plugin to avoid build issues on macos. + https://github.com/flutter/flutter/issues/46618 + DESC + s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/path_provider' + s.license = { :file => '../LICENSE' } + s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.public_header_files = 'Classes/**/*.h' + + s.platform = :osx + s.osx.deployment_target = '10.11' +end + diff --git a/packages/path_provider/path_provider/pubspec.yaml b/packages/path_provider/path_provider/pubspec.yaml index c20d83b32542..48fc688110b6 100644 --- a/packages/path_provider/path_provider/pubspec.yaml +++ b/packages/path_provider/path_provider/pubspec.yaml @@ -2,7 +2,7 @@ name: path_provider description: Flutter plugin for getting commonly used locations on the Android & iOS file systems, such as the temp and app data directories. homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider -version: 1.6.3 +version: 1.6.4 flutter: plugin: @@ -12,11 +12,16 @@ flutter: pluginClass: PathProviderPlugin ios: pluginClass: FLTPathProviderPlugin + macos: + pluginClass: FLTPathProviderPlugin + default_package: path_provider_macos + dependencies: flutter: sdk: flutter path_provider_platform_interface: ^1.0.1 + path_provider_macos: ^0.0.4 dev_dependencies: e2e: ^0.2.1 From 036a6e13e9017b979fe68f311cbf55d38d6d2e03 Mon Sep 17 00:00:00 2001 From: Francisco Magdaleno Date: Mon, 2 Mar 2020 14:05:20 -0800 Subject: [PATCH 17/37] Remove plugin class (#2569) --- packages/path_provider/path_provider/CHANGELOG.md | 4 ++++ packages/path_provider/path_provider/pubspec.yaml | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/path_provider/path_provider/CHANGELOG.md b/packages/path_provider/path_provider/CHANGELOG.md index 622d28d46693..99e088ec268b 100644 --- a/packages/path_provider/path_provider/CHANGELOG.md +++ b/packages/path_provider/path_provider/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.5 + +* Remove unused class name in pubspec. + ## 1.6.4 * Endorsed macOS implementation. diff --git a/packages/path_provider/path_provider/pubspec.yaml b/packages/path_provider/path_provider/pubspec.yaml index 48fc688110b6..9f081ca927d9 100644 --- a/packages/path_provider/path_provider/pubspec.yaml +++ b/packages/path_provider/path_provider/pubspec.yaml @@ -2,7 +2,7 @@ name: path_provider description: Flutter plugin for getting commonly used locations on the Android & iOS file systems, such as the temp and app data directories. homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider -version: 1.6.4 +version: 1.6.5 flutter: plugin: @@ -13,7 +13,6 @@ flutter: ios: pluginClass: FLTPathProviderPlugin macos: - pluginClass: FLTPathProviderPlugin default_package: path_provider_macos From 6ee6c5d476852d8b33ee59da89d916fd5a7380e8 Mon Sep 17 00:00:00 2001 From: EricEnslen <61600502+EricEnslen@users.noreply.github.com> Date: Mon, 2 Mar 2020 16:46:02 -0800 Subject: [PATCH 18/37] [device_info] add PackageManager's SystemFeatures to AndroidDeviceInfo (#2567) There's a variety of scenarios where checking at runtime which system features are available is useful. System features are device capabilities that do not change at runtime (for example, FEATURE_BLUETOOTH is always present if the device has a bluetooth radio, even if Bluetooth is presently disabled), so DeviceInfo seems like the right place to put this. --- packages/device_info/CHANGELOG.md | 4 ++++ .../plugins/deviceinfo/DeviceInfoPlugin.java | 12 +++++----- .../deviceinfo/MethodCallHandlerImpl.java | 24 ++++++++++++++++--- packages/device_info/example/lib/main.dart | 3 ++- packages/device_info/lib/device_info.dart | 21 +++++++++++++++- packages/device_info/pubspec.yaml | 2 +- 6 files changed, 54 insertions(+), 12 deletions(-) diff --git a/packages/device_info/CHANGELOG.md b/packages/device_info/CHANGELOG.md index 00dcd2988bba..68aeed8c2cbf 100644 --- a/packages/device_info/CHANGELOG.md +++ b/packages/device_info/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.2 + +* Add systemFeatures to AndroidDeviceInfo. + ## 0.4.1+5 * Make the pedantic dev_dependency explicit. diff --git a/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java b/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java index 8ad0f5db1851..a0435a46e837 100644 --- a/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java +++ b/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java @@ -4,7 +4,7 @@ package io.flutter.plugins.deviceinfo; -import android.content.ContentResolver; +import android.content.Context; import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MethodChannel; @@ -18,14 +18,13 @@ public class DeviceInfoPlugin implements FlutterPlugin { /** Plugin registration. */ public static void registerWith(Registrar registrar) { DeviceInfoPlugin plugin = new DeviceInfoPlugin(); - plugin.setupMethodChannel(registrar.messenger(), registrar.context().getContentResolver()); + plugin.setupMethodChannel(registrar.messenger(), registrar.context()); } @Override public void onAttachedToEngine(FlutterPlugin.FlutterPluginBinding binding) { setupMethodChannel( - binding.getFlutterEngine().getDartExecutor(), - binding.getApplicationContext().getContentResolver()); + binding.getFlutterEngine().getDartExecutor(), binding.getApplicationContext()); } @Override @@ -33,9 +32,10 @@ public void onDetachedFromEngine(FlutterPlugin.FlutterPluginBinding binding) { tearDownChannel(); } - private void setupMethodChannel(BinaryMessenger messenger, ContentResolver contentResolver) { + private void setupMethodChannel(BinaryMessenger messenger, Context context) { channel = new MethodChannel(messenger, "plugins.flutter.io/device_info"); - final MethodCallHandlerImpl handler = new MethodCallHandlerImpl(contentResolver); + final MethodCallHandlerImpl handler = + new MethodCallHandlerImpl(context.getContentResolver(), context.getPackageManager()); channel.setMethodCallHandler(handler); } diff --git a/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java b/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java index 22ea1f0ec85e..800ca6dcddb7 100644 --- a/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java +++ b/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java @@ -6,6 +6,8 @@ import android.annotation.SuppressLint; import android.content.ContentResolver; +import android.content.pm.FeatureInfo; +import android.content.pm.PackageManager; import android.os.Build; import android.provider.Settings; import io.flutter.plugin.common.MethodCall; @@ -20,14 +22,16 @@ */ class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler { - private ContentResolver contentResolver; + private final ContentResolver contentResolver; + private final PackageManager packageManager; /** Substitute for missing values. */ private static final String[] EMPTY_STRING_LIST = new String[] {}; - /** Constructs DeviceInfo. The {@code contentResolver} must not be null. */ - MethodCallHandlerImpl(ContentResolver contentResolver) { + /** Constructs DeviceInfo. {@code contentResolver} and {@code packageManager} must not be null. */ + MethodCallHandlerImpl(ContentResolver contentResolver, PackageManager packageManager) { this.contentResolver = contentResolver; + this.packageManager = packageManager; } @Override @@ -60,6 +64,8 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) { build.put("isPhysicalDevice", !isEmulator()); build.put("androidId", getAndroidId()); + build.put("systemFeatures", Arrays.asList(getSystemFeatures())); + Map version = new HashMap<>(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { version.put("baseOS", Build.VERSION.BASE_OS); @@ -78,6 +84,18 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) { } } + private String[] getSystemFeatures() { + FeatureInfo[] featureInfos = packageManager.getSystemAvailableFeatures(); + if (featureInfos == null) { + return EMPTY_STRING_LIST; + } + String[] features = new String[featureInfos.length]; + for (int i = 0; i < featureInfos.length; i++) { + features[i] = featureInfos[i].name; + } + return features; + } + /** * Returns the Android hardware device ID that is unique between the device + user and app * signing. This key will change if the app is uninstalled or its data is cleared. Device factory diff --git a/packages/device_info/example/lib/main.dart b/packages/device_info/example/lib/main.dart index 528604b661b0..1c1064aa09ee 100644 --- a/packages/device_info/example/lib/main.dart +++ b/packages/device_info/example/lib/main.dart @@ -85,6 +85,7 @@ class _MyAppState extends State { 'type': build.type, 'isPhysicalDevice': build.isPhysicalDevice, 'androidId': build.androidId, + 'systemFeatures': build.systemFeatures, }; } @@ -114,7 +115,6 @@ class _MyAppState extends State { Platform.isAndroid ? 'Android Device Info' : 'iOS Device Info'), ), body: ListView( - shrinkWrap: true, children: _deviceData.keys.map((String property) { return Row( children: [ @@ -132,6 +132,7 @@ class _MyAppState extends State { padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0), child: Text( '${_deviceData[property]}', + maxLines: 10, overflow: TextOverflow.ellipsis, ), )), diff --git a/packages/device_info/lib/device_info.dart b/packages/device_info/lib/device_info.dart index e775227d96d1..25b7d46cdb11 100644 --- a/packages/device_info/lib/device_info.dart +++ b/packages/device_info/lib/device_info.dart @@ -62,9 +62,11 @@ class AndroidDeviceInfo { this.type, this.isPhysicalDevice, this.androidId, + List systemFeatures, }) : supported32BitAbis = List.unmodifiable(supported32BitAbis), supported64BitAbis = List.unmodifiable(supported64BitAbis), - supportedAbis = List.unmodifiable(supportedAbis); + supportedAbis = List.unmodifiable(supportedAbis), + systemFeatures = List.unmodifiable(systemFeatures); /// Android operating system version values derived from `android.os.Build.VERSION`. final AndroidBuildVersion version; @@ -126,6 +128,22 @@ class AndroidDeviceInfo { /// The Android hardware device ID that is unique between the device + user and app signing. final String androidId; + /// Describes what features are available on the current device. + /// + /// This can be used to check if the device has, for example, a front-facing + /// camera, or a touchscreen. However, in many cases this is not the best + /// API to use. For example, if you are interested in bluetooth, this API + /// can tell you if the device has a bluetooth radio, but it cannot tell you + /// if bluetooth is currently enabled, or if you have been granted the + /// necessary permissions to use it. Please *only* use this if there is no + /// other way to determine if a feature is supported. + /// + /// This data comes from Android's PackageManager.getSystemAvailableFeatures, + /// and many of the common feature strings to look for are available in + /// PackageManager's public documentation: + /// https://developer.android.com/reference/android/content/pm/PackageManager + final List systemFeatures; + /// Deserializes from the message received from [_kChannel]. static AndroidDeviceInfo _fromMap(Map map) { return AndroidDeviceInfo._( @@ -150,6 +168,7 @@ class AndroidDeviceInfo { type: map['type'], isPhysicalDevice: map['isPhysicalDevice'], androidId: map['androidId'], + systemFeatures: _fromList(map['systemFeatures']), ); } diff --git a/packages/device_info/pubspec.yaml b/packages/device_info/pubspec.yaml index b862a7de4452..06a530bcaab7 100644 --- a/packages/device_info/pubspec.yaml +++ b/packages/device_info/pubspec.yaml @@ -2,7 +2,7 @@ name: device_info description: Flutter plugin providing detailed information about the device (make, model, etc.), and Android or iOS version the app is running on. homepage: https://github.com/flutter/plugins/tree/master/packages/device_info -version: 0.4.1+5 +version: 0.4.2 flutter: plugin: From 15ea1905ad0933d282190c320d4183d6cac1f64c Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Wed, 4 Mar 2020 10:54:02 -0800 Subject: [PATCH 19/37] [webview_flkutter] remove ios workspace setting --- packages/webview_flutter/CHANGELOG.md | 4 ++++ .../xcshareddata/WorkspaceSettings.xcsettings | 8 -------- packages/webview_flutter/pubspec.yaml | 2 +- 3 files changed, 5 insertions(+), 9 deletions(-) delete mode 100644 packages/webview_flutter/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md index cec384d73f0c..693213425161 100644 --- a/packages/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.19+9 + +* Remove example app's iOS workspace settings. + ## 0.3.19+8 * Make the pedantic dev_dependency explicit. diff --git a/packages/webview_flutter/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/webview_flutter/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index 949b67898200..000000000000 --- a/packages/webview_flutter/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - BuildSystemType - Original - - diff --git a/packages/webview_flutter/pubspec.yaml b/packages/webview_flutter/pubspec.yaml index d19ed4776778..a3091ce7fcd2 100644 --- a/packages/webview_flutter/pubspec.yaml +++ b/packages/webview_flutter/pubspec.yaml @@ -1,6 +1,6 @@ name: webview_flutter description: A Flutter plugin that provides a WebView widget on Android and iOS. -version: 0.3.19+8 +version: 0.3.19+9 homepage: https://github.com/flutter/plugins/tree/master/packages/webview_flutter environment: From 9d02b1faf87dbdb4741045c10248c0238d8ebd23 Mon Sep 17 00:00:00 2001 From: Sebastian Roth Date: Thu, 5 Mar 2020 10:32:49 +0000 Subject: [PATCH 20/37] [android_intent] Make action optional, as Intents can also resolve with just the component name (#2575) * An intent takes an action, component or both, but at least one of them. * Extend the tests and enforce the new assertion on the private constructor as well * Extends unit test to cover no-action, but component name case. * Improves unit test even more by writing literal values in the code --- packages/android_intent/CHANGELOG.md | 5 +++ .../plugins/androidintent/IntentSender.java | 9 +++-- .../androidintent/MethodCallHandlerImpl.java | 4 ++ .../MethodCallHandlerImplTest.java | 30 +++++++++++++- .../android_intent/lib/android_intent.dart | 16 +++++--- packages/android_intent/pubspec.yaml | 2 +- .../test/android_intent_test.dart | 40 ++++++++++++++++--- 7 files changed, 89 insertions(+), 17 deletions(-) diff --git a/packages/android_intent/CHANGELOG.md b/packages/android_intent/CHANGELOG.md index 3d16c1422441..47f1917e3e8a 100644 --- a/packages/android_intent/CHANGELOG.md +++ b/packages/android_intent/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.3.6 + +* Marks the `action` parameter as optional +* Adds an assertion to ensure the intent receives an action, component or both. + ## 0.3.5+1 * Make the pedantic dev_dependency explicit. diff --git a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/IntentSender.java b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/IntentSender.java index aac9226b9465..5aa7919699da 100644 --- a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/IntentSender.java +++ b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/IntentSender.java @@ -42,7 +42,7 @@ public IntentSender(@Nullable Activity activity, @Nullable Context applicationCo * back to {@code applicationContext} and adds {@link Intent#FLAG_ACTIVITY_NEW_TASK} to the intent * before launching it. * - * @param action the Intent action, such as {@code ACTION_VIEW}. + * @param action the Intent action, such as {@code ACTION_VIEW} if non-null. * @param flags forwarded to {@link Intent#addFlags(int)} if non-null. * @param category forwarded to {@link Intent#addCategory(String)} if non-null. * @param data forwarded to {@link Intent#setData(Uri)} if non-null and 'type' parameter is null. @@ -57,7 +57,7 @@ public IntentSender(@Nullable Activity activity, @Nullable Context applicationCo * Intent#setDataAndType(Uri, String)} */ void send( - String action, + @Nullable String action, @Nullable Integer flags, @Nullable String category, @Nullable Uri data, @@ -70,8 +70,11 @@ void send( return; } - Intent intent = new Intent(action); + Intent intent = new Intent(); + if (action != null) { + intent.setAction(action); + } if (flags != null) { intent.addFlags(flags); } diff --git a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/MethodCallHandlerImpl.java b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/MethodCallHandlerImpl.java index a77d181015de..09846d5e51ef 100644 --- a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/MethodCallHandlerImpl.java +++ b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/MethodCallHandlerImpl.java @@ -91,6 +91,10 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) { } private static String convertAction(String action) { + if (action == null) { + return null; + } + switch (action) { case "action_view": return Intent.ACTION_VIEW; diff --git a/packages/android_intent/android/src/test/java/io/flutter/plugins/androidintent/MethodCallHandlerImplTest.java b/packages/android_intent/android/src/test/java/io/flutter/plugins/androidintent/MethodCallHandlerImplTest.java index 4ce7ddc3718e..cf0a28e822d4 100644 --- a/packages/android_intent/android/src/test/java/io/flutter/plugins/androidintent/MethodCallHandlerImplTest.java +++ b/packages/android_intent/android/src/test/java/io/flutter/plugins/androidintent/MethodCallHandlerImplTest.java @@ -217,8 +217,34 @@ public void onMethodCall_setsComponentName() { Intent intent = shadowOf((Application) context).getNextStartedActivity(); assertNotNull(intent); assertNotNull(intent.getComponent()); - assertEquals(expectedComponent.getPackageName(), intent.getPackage()); - assertEquals(expectedComponent.flattenToString(), intent.getComponent().flattenToString()); + assertEquals("foo", intent.getAction()); + assertEquals("io.flutter.plugins.androidintent", intent.getPackage()); + assertEquals( + "io.flutter.plugins.androidintent/MainActivity", intent.getComponent().flattenToString()); + } + + @Test + public void onMethodCall_setsOnlyComponentName() { + sender.setApplicationContext(context); + Map args = new HashMap<>(); + ComponentName expectedComponent = + new ComponentName("io.flutter.plugins.androidintent", "MainActivity"); + args.put("package", expectedComponent.getPackageName()); + args.put("componentName", expectedComponent.getClassName()); + Result result = mock(Result.class); + ShadowPackageManager shadowPm = + shadowOf(ApplicationProvider.getApplicationContext().getPackageManager()); + shadowPm.addActivityIfNotPresent(expectedComponent); + + methodCallHandler.onMethodCall(new MethodCall("launch", args), result); + + verify(result, times(1)).success(null); + Intent intent = shadowOf((Application) context).getNextStartedActivity(); + assertNotNull(intent); + assertNotNull(intent.getComponent()); + assertEquals("io.flutter.plugins.androidintent", intent.getPackage()); + assertEquals( + "io.flutter.plugins.androidintent/MainActivity", intent.getComponent().flattenToString()); } @Test diff --git a/packages/android_intent/lib/android_intent.dart b/packages/android_intent/lib/android_intent.dart index eb2f486408cc..26e270a3a79b 100644 --- a/packages/android_intent/lib/android_intent.dart +++ b/packages/android_intent/lib/android_intent.dart @@ -29,7 +29,7 @@ class AndroidIntent { /// If not null, then [package] but also be provided. /// [type] refers to the type of the intent, can be null. const AndroidIntent({ - @required this.action, + this.action, this.flags, this.category, this.data, @@ -38,7 +38,8 @@ class AndroidIntent { this.componentName, Platform platform, this.type, - }) : assert(action != null), + }) : assert(action != null || componentName != null, + 'action or component (or both) must be specified'), _channel = const MethodChannel(_kChannelName), _platform = platform ?? const LocalPlatform(); @@ -46,9 +47,9 @@ class AndroidIntent { /// app code, it may break without warning. @visibleForTesting AndroidIntent.private({ - @required this.action, @required Platform platform, @required MethodChannel channel, + this.action, this.flags, this.category, this.data, @@ -56,7 +57,9 @@ class AndroidIntent { this.package, this.componentName, this.type, - }) : _channel = channel, + }) : assert(action != null || componentName != null, + 'action or component (or both) must be specified'), + _channel = channel, _platform = platform; /// This is the general verb that the intent should attempt to do. This @@ -131,7 +134,10 @@ class AndroidIntent { if (!_platform.isAndroid) { return; } - final Map args = {'action': action}; + final Map args = {}; + if (action != null) { + args['action'] = action; + } if (flags != null) { args['flags'] = convertFlags(flags); } diff --git a/packages/android_intent/pubspec.yaml b/packages/android_intent/pubspec.yaml index c6e38bc0d93b..2faf45e915f6 100644 --- a/packages/android_intent/pubspec.yaml +++ b/packages/android_intent/pubspec.yaml @@ -1,7 +1,7 @@ name: android_intent description: Flutter plugin for launching Android Intents. Not supported on iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/android_intent -version: 0.3.5+1 +version: 0.3.6 flutter: plugin: diff --git a/packages/android_intent/test/android_intent_test.dart b/packages/android_intent/test/android_intent_test.dart index e36a8b7827c9..60cf3b58a507 100644 --- a/packages/android_intent/test/android_intent_test.dart +++ b/packages/android_intent/test/android_intent_test.dart @@ -15,6 +15,7 @@ void main() { setUp(() { mockChannel = MockMethodChannel(); }); + group('AndroidIntent', () { test('pass right params', () async { androidIntent = AndroidIntent.private( @@ -32,26 +33,53 @@ void main() { 'type': 'video/*', })); }); - test('pass null value to action param', () async { + + test('raises error if neither an action nor a component is provided', () { + try { + androidIntent = AndroidIntent(data: 'https://flutter.io'); + fail('should raise an AssertionError'); + } on AssertionError catch (e) { + expect(e.message, 'action or component (or both) must be specified'); + } catch (e) { + fail('should raise an AssertionError'); + } + }); + test('can send Intent with an action and no component', () async { androidIntent = AndroidIntent.private( - action: null, - channel: mockChannel, - platform: FakePlatform(operatingSystem: 'android')); + action: 'action_view', + channel: mockChannel, + platform: FakePlatform(operatingSystem: 'android'), + ); await androidIntent.launch(); verify(mockChannel.invokeMethod('launch', { - 'action': null, + 'action': 'action_view', + })); + }); + + test('can send Intent with a component and no action', () async { + androidIntent = AndroidIntent.private( + package: 'packageName', + componentName: 'componentName', + channel: mockChannel, + platform: FakePlatform(operatingSystem: 'android'), + ); + await androidIntent.launch(); + verify(mockChannel.invokeMethod('launch', { + 'package': 'packageName', + 'componentName': 'componentName', })); }); test('call in ios platform', () async { androidIntent = AndroidIntent.private( - action: null, + action: 'action_view', channel: mockChannel, platform: FakePlatform(operatingSystem: 'ios')); await androidIntent.launch(); verifyZeroInteractions(mockChannel); }); }); + group('convertFlags ', () { androidIntent = const AndroidIntent( action: 'action_view', From da00443a9344acd3baea6585e789cfc3ddca9ea9 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Thu, 5 Mar 2020 20:01:22 -0800 Subject: [PATCH 21/37] Remove Swift dependency (#2580) --- packages/espresso/CHANGELOG.md | 4 ++++ .../espresso/ios/Classes/SwiftEspressoPlugin.swift | 14 -------------- packages/espresso/ios/espresso.podspec | 2 +- packages/espresso/pubspec.yaml | 2 +- 4 files changed, 6 insertions(+), 16 deletions(-) delete mode 100644 packages/espresso/ios/Classes/SwiftEspressoPlugin.swift diff --git a/packages/espresso/CHANGELOG.md b/packages/espresso/CHANGELOG.md index 0fbb332ebcbf..7aab8f468bdc 100644 --- a/packages/espresso/CHANGELOG.md +++ b/packages/espresso/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.1+4 + +* Remove Swift dependency. + ## 0.0.1+3 * Make the pedantic dev_dependency explicit. diff --git a/packages/espresso/ios/Classes/SwiftEspressoPlugin.swift b/packages/espresso/ios/Classes/SwiftEspressoPlugin.swift deleted file mode 100644 index 2ff3024ce33a..000000000000 --- a/packages/espresso/ios/Classes/SwiftEspressoPlugin.swift +++ /dev/null @@ -1,14 +0,0 @@ -import Flutter -import UIKit - -public class SwiftEspressoPlugin: NSObject, FlutterPlugin { - public static func register(with registrar: FlutterPluginRegistrar) { - let channel = FlutterMethodChannel(name: "espresso", binaryMessenger: registrar.messenger()) - let instance = SwiftEspressoPlugin() - registrar.addMethodCallDelegate(instance, channel: channel) - } - - public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { - result("iOS " + UIDevice.current.systemVersion) - } -} diff --git a/packages/espresso/ios/espresso.podspec b/packages/espresso/ios/espresso.podspec index cd64afa1d3c5..8c35525d66cf 100644 --- a/packages/espresso/ios/espresso.podspec +++ b/packages/espresso/ios/espresso.podspec @@ -14,10 +14,10 @@ A new flutter plugin project. s.author = { 'Your Company' => 'email@example.com' } s.source = { :path => '.' } s.source_files = 'Classes/**/*' + s.public_header_files = 'Classes/**/*.h' s.dependency 'Flutter' s.platform = :ios, '8.0' # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } - s.swift_version = '5.0' end diff --git a/packages/espresso/pubspec.yaml b/packages/espresso/pubspec.yaml index f59b4140d676..50f613af6c84 100644 --- a/packages/espresso/pubspec.yaml +++ b/packages/espresso/pubspec.yaml @@ -1,6 +1,6 @@ name: espresso description: Java classes for testing Flutter apps using Espresso. -version: 0.0.1+3 +version: 0.0.1+4 homepage: https://github.com/flutter/plugins/espresso environment: From d0c998583d2aa2f8573420d9df1ebf543ad67f1c Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Fri, 6 Mar 2020 11:11:28 -0800 Subject: [PATCH 22/37] Make FlutterRunner launch deterministic when running other tests. (#2584) * Make FlutterRunner launch deterministic when running other tests. * Switch to using FlutterTestRunner --- packages/e2e/CHANGELOG.md | 6 ++++++ packages/e2e/README.md | 4 ++-- ...tterRunner.java => FlutterTestRunner.java} | 21 +++++++++++++++---- .../e2e_example/EmbedderV1ActivityTest.java | 6 +++--- .../example/e2e_example/MainActivityTest.java | 8 ++++--- packages/e2e/pubspec.yaml | 2 +- 6 files changed, 34 insertions(+), 13 deletions(-) rename packages/e2e/android/src/main/java/dev/flutter/plugins/e2e/{FlutterRunner.java => FlutterTestRunner.java} (74%) diff --git a/packages/e2e/CHANGELOG.md b/packages/e2e/CHANGELOG.md index 86f37b291549..ab17150d7448 100644 --- a/packages/e2e/CHANGELOG.md +++ b/packages/e2e/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.3.0 + +* Updates documentation to instruct developers not to launch the activity since + we are doing it for them. +* Renames `FlutterRunner` to `FlutterTestRunner` to avoid conflict with Fuchsia. + ## 0.2.4+4 * Fixed a hang that occurred on platforms that don't have a `MethodChannel` listener registered.. diff --git a/packages/e2e/README.md b/packages/e2e/README.md index 3e27ff36afa3..7d571a522057 100644 --- a/packages/e2e/README.md +++ b/packages/e2e/README.md @@ -93,10 +93,10 @@ import dev.flutter.plugins.e2e.FlutterRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class MainActivityTest { @Rule - public ActivityTestRule rule = new ActivityTestRule<>(MainActivity.class); + public ActivityTestRule rule = new ActivityTestRule<>(MainActivity.class, true, false); } ``` diff --git a/packages/e2e/android/src/main/java/dev/flutter/plugins/e2e/FlutterRunner.java b/packages/e2e/android/src/main/java/dev/flutter/plugins/e2e/FlutterTestRunner.java similarity index 74% rename from packages/e2e/android/src/main/java/dev/flutter/plugins/e2e/FlutterRunner.java rename to packages/e2e/android/src/main/java/dev/flutter/plugins/e2e/FlutterTestRunner.java index 31f3e8431cad..f214cd7ce3fe 100644 --- a/packages/e2e/android/src/main/java/dev/flutter/plugins/e2e/FlutterRunner.java +++ b/packages/e2e/android/src/main/java/dev/flutter/plugins/e2e/FlutterTestRunner.java @@ -5,6 +5,7 @@ package dev.flutter.plugins.e2e; import android.app.Activity; +import android.util.Log; import androidx.test.rule.ActivityTestRule; import java.lang.reflect.Field; import java.util.Map; @@ -15,11 +16,13 @@ import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunNotifier; -public class FlutterRunner extends Runner { +public class FlutterTestRunner extends Runner { + private static final String TAG = "FlutterTestRunner"; final Class testClass; + ActivityTestRule rule = null; - public FlutterRunner(Class testClass) { + public FlutterTestRunner(Class testClass) { super(); this.testClass = testClass; @@ -29,8 +32,7 @@ public FlutterRunner(Class testClass) { if (field.isAnnotationPresent(Rule.class)) { try { Object instance = testClass.newInstance(); - ActivityTestRule rule = (ActivityTestRule) field.get(instance); - rule.launchActivity(null); + rule = (ActivityTestRule) field.get(instance); } catch (InstantiationException | IllegalAccessException e) { // This might occur if the developer did not make the rule public. // We could call field.setAccessible(true) but it seems better to throw. @@ -47,6 +49,17 @@ public Description getDescription() { @Override public void run(RunNotifier notifier) { + if (rule == null) { + throw new RuntimeException("Unable to run tests due to missing activity rule"); + } + try { + rule.launchActivity(null); + } catch (RuntimeException e) { + Log.v(TAG, "launchActivity failed, possibly because the activity was already running. " + e); + Log.v( + TAG, + "Try disabling auto-launch of the activity, e.g. ActivityTestRule<>(MainActivity.class, true, false);"); + } Map results = null; try { results = E2EPlugin.testResults.get(); diff --git a/packages/e2e/example/android/app/src/androidTest/java/com/example/e2e_example/EmbedderV1ActivityTest.java b/packages/e2e/example/android/app/src/androidTest/java/com/example/e2e_example/EmbedderV1ActivityTest.java index a526c1c8422e..eedde293eb6c 100644 --- a/packages/e2e/example/android/app/src/androidTest/java/com/example/e2e_example/EmbedderV1ActivityTest.java +++ b/packages/e2e/example/android/app/src/androidTest/java/com/example/e2e_example/EmbedderV1ActivityTest.java @@ -1,13 +1,13 @@ package com.example.e2e_example; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.e2e.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class EmbedderV1ActivityTest { @Rule public ActivityTestRule rule = - new ActivityTestRule<>(EmbedderV1Activity.class); + new ActivityTestRule<>(EmbedderV1Activity.class, true, false); } diff --git a/packages/e2e/example/android/app/src/androidTest/java/com/example/e2e_example/MainActivityTest.java b/packages/e2e/example/android/app/src/androidTest/java/com/example/e2e_example/MainActivityTest.java index b61c056e176d..93b1f923ee05 100644 --- a/packages/e2e/example/android/app/src/androidTest/java/com/example/e2e_example/MainActivityTest.java +++ b/packages/e2e/example/android/app/src/androidTest/java/com/example/e2e_example/MainActivityTest.java @@ -1,11 +1,13 @@ package com.example.e2e_example; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.e2e.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class MainActivityTest { - @Rule public ActivityTestRule rule = new ActivityTestRule<>(MainActivity.class); + @Rule + public ActivityTestRule rule = + new ActivityTestRule<>(MainActivity.class, true, false); } diff --git a/packages/e2e/pubspec.yaml b/packages/e2e/pubspec.yaml index 21e1210bd23e..e05bc1b560d8 100644 --- a/packages/e2e/pubspec.yaml +++ b/packages/e2e/pubspec.yaml @@ -1,6 +1,6 @@ name: e2e description: Runs tests that use the flutter_test API as integration tests. -version: 0.2.4+4 +version: 0.3.0 homepage: https://github.com/flutter/plugins/tree/master/packages/e2e environment: From 6ceda31e56c0f5d7e50d7b34647ceeaec28cd398 Mon Sep 17 00:00:00 2001 From: Ben Konyi Date: Fri, 6 Mar 2020 14:29:53 -0800 Subject: [PATCH 23/37] [android_alarm_manager] Added Espresso test for background execution (#2482) * Added test for android_alarm_manager background execution Co-authored-by: Collin Jackson --- packages/android_alarm_manager/CHANGELOG.md | 4 + .../example/android/app/build.gradle | 2 + .../BackgroundExecutionTest.java | 64 +++++++ .../DriverExtensionActivity.java | 15 ++ .../androidalarmmanager/MainActivityTest.java | 8 +- .../android/app/src/debug/AndroidManifest.xml | 21 +++ .../MainActivity.java | 2 + .../example/lib/main.dart | 164 +++++++++++++++--- .../example/pubspec.yaml | 5 +- .../android_alarm_manager_e2e.dart | 9 +- packages/android_alarm_manager/pubspec.yaml | 2 +- 11 files changed, 268 insertions(+), 28 deletions(-) create mode 100644 packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/BackgroundExecutionTest.java create mode 100644 packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/DriverExtensionActivity.java create mode 100644 packages/android_alarm_manager/example/android/app/src/debug/AndroidManifest.xml diff --git a/packages/android_alarm_manager/CHANGELOG.md b/packages/android_alarm_manager/CHANGELOG.md index cf935b566e20..d04ca962d7ad 100644 --- a/packages/android_alarm_manager/CHANGELOG.md +++ b/packages/android_alarm_manager/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.5+5 + +* Added an Espresso test. + ## 0.4.5+4 * Make the pedantic dev_dependency explicit. diff --git a/packages/android_alarm_manager/example/android/app/build.gradle b/packages/android_alarm_manager/example/android/app/build.gradle index d296cafa8e7c..f066040810c2 100644 --- a/packages/android_alarm_manager/example/android/app/build.gradle +++ b/packages/android_alarm_manager/example/android/app/build.gradle @@ -55,6 +55,8 @@ flutter { dependencies { testImplementation 'junit:junit:4.12' + testImplementation "com.google.truth:truth:1.0" androidTestImplementation 'androidx.test:runner:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' + api 'androidx.test:core:1.2.0' } diff --git a/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/BackgroundExecutionTest.java b/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/BackgroundExecutionTest.java new file mode 100644 index 000000000000..ce34b25ec505 --- /dev/null +++ b/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/BackgroundExecutionTest.java @@ -0,0 +1,64 @@ +// Copyright 2020 The Chromium 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.androidalarmmanagerexample; + +import static androidx.test.espresso.Espresso.pressBackUnconditionally; +import static androidx.test.espresso.flutter.EspressoFlutter.onFlutterWidget; +import static androidx.test.espresso.flutter.action.FlutterActions.click; +import static androidx.test.espresso.flutter.matcher.FlutterMatchers.withValueKey; +import static org.junit.Assert.assertEquals; + +import android.content.Context; +import android.content.SharedPreferences; +import androidx.test.InstrumentationRegistry; +import androidx.test.core.app.ActivityScenario; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.rule.ActivityTestRule; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class BackgroundExecutionTest { + private SharedPreferences prefs; + static final String COUNT_KEY = "flutter.count"; + + @Rule + public ActivityTestRule myActivityTestRule = + new ActivityTestRule<>(DriverExtensionActivity.class, true, false); + + @Before + public void setUp() throws Exception { + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + prefs = context.getSharedPreferences("FlutterSharedPreferences", Context.MODE_PRIVATE); + prefs.edit().putLong(COUNT_KEY, 0).apply(); + + ActivityScenario.launch(DriverExtensionActivity.class); + } + + @Test + public void startBackgroundIsolate() throws Exception { + + // Register a one shot alarm which will go off in ~5 seconds. + onFlutterWidget(withValueKey("RegisterOneShotAlarm")).perform(click()); + + // The alarm count should be 0 after installation. + assertEquals(prefs.getLong(COUNT_KEY, -1), 0); + + // Close the application to background it. + pressBackUnconditionally(); + + // The alarm should eventually fire, wake up the application, create a + // background isolate, and then increment the counter in the shared + // preferences. Timeout after 20s, just to be safe. + int tries = 0; + while ((prefs.getLong(COUNT_KEY, -1) == 0) && (tries < 200)) { + Thread.sleep(100); + ++tries; + } + assertEquals(prefs.getLong(COUNT_KEY, -1), 1); + } +} diff --git a/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/DriverExtensionActivity.java b/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/DriverExtensionActivity.java new file mode 100644 index 000000000000..c51a3c0d8a55 --- /dev/null +++ b/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/DriverExtensionActivity.java @@ -0,0 +1,15 @@ +// Copyright 2019 The Chromium 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.androidalarmmanagerexample; + +import androidx.annotation.NonNull; + +public class DriverExtensionActivity extends MainActivity { + @Override + @NonNull + public String getDartEntrypointFunctionName() { + return "appMain"; + } +} diff --git a/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/MainActivityTest.java b/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/MainActivityTest.java index 6b69d39de003..86bb25cccff2 100644 --- a/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/MainActivityTest.java +++ b/packages/android_alarm_manager/example/android/app/src/androidTest/java/io/plugins/androidalarmmanager/MainActivityTest.java @@ -5,11 +5,13 @@ package io.flutter.plugins.androidalarmmanagerexample; import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; +import dev.flutter.plugins.e2e.FlutterTestRunner; import org.junit.Rule; import org.junit.runner.RunWith; -@RunWith(FlutterRunner.class) +@RunWith(FlutterTestRunner.class) public class MainActivityTest { - @Rule public ActivityTestRule rule = new ActivityTestRule<>(MainActivity.class); + @Rule + public ActivityTestRule rule = + new ActivityTestRule<>(MainActivity.class, true, false); } diff --git a/packages/android_alarm_manager/example/android/app/src/debug/AndroidManifest.xml b/packages/android_alarm_manager/example/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 000000000000..e826cdd83ac7 --- /dev/null +++ b/packages/android_alarm_manager/example/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/android_alarm_manager/example/android/app/src/main/java/io/flutter/plugins/androidalarmmanagerexample/MainActivity.java b/packages/android_alarm_manager/example/android/app/src/main/java/io/flutter/plugins/androidalarmmanagerexample/MainActivity.java index 2c80708c4e94..efe9064317cd 100644 --- a/packages/android_alarm_manager/example/android/app/src/main/java/io/flutter/plugins/androidalarmmanagerexample/MainActivity.java +++ b/packages/android_alarm_manager/example/android/app/src/main/java/io/flutter/plugins/androidalarmmanagerexample/MainActivity.java @@ -10,6 +10,7 @@ import io.flutter.embedding.engine.plugins.shim.ShimPluginRegistry; import io.flutter.plugins.androidalarmmanager.AndroidAlarmManagerPlugin; import io.flutter.plugins.pathprovider.PathProviderPlugin; +import io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin; public class MainActivity extends FlutterActivity { // TODO(bkonyi): Remove this once v2 of GeneratedPluginRegistrant rolls to stable. https://github.com/flutter/flutter/issues/42694 @@ -18,6 +19,7 @@ public void configureFlutterEngine(FlutterEngine flutterEngine) { ShimPluginRegistry shimPluginRegistry = new ShimPluginRegistry(flutterEngine); flutterEngine.getPlugins().add(new AndroidAlarmManagerPlugin()); flutterEngine.getPlugins().add(new E2EPlugin()); + flutterEngine.getPlugins().add(new SharedPreferencesPlugin()); PathProviderPlugin.registerWith( shimPluginRegistry.registrarFor("io.flutter.plugins.pathprovider.PathProviderPlugin")); } diff --git a/packages/android_alarm_manager/example/lib/main.dart b/packages/android_alarm_manager/example/lib/main.dart index 12aad9b001a9..4ba697744dbf 100644 --- a/packages/android_alarm_manager/example/lib/main.dart +++ b/packages/android_alarm_manager/example/lib/main.dart @@ -4,32 +4,156 @@ // ignore_for_file: public_member_api_docs -import 'dart:async'; +import 'dart:isolate'; +import 'dart:math'; +import 'dart:ui'; import 'package:android_alarm_manager/android_alarm_manager.dart'; -import 'package:flutter/widgets.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:flutter/material.dart'; -void printMessage(String msg) => print('[${DateTime.now()}] $msg'); +/// The [SharedPreferences] key to access the alarm fire count. +const String countKey = 'count'; -void printPeriodic() => printMessage("Periodic!"); -void printOneShot() => printMessage("One shot!"); +/// The name associated with the UI isolate's [SendPort]. +const String isolateName = 'isolate'; -Future main() async { - final int periodicID = 0; - final int oneShotID = 1; +/// A port used to communicate from a background isolate to the UI isolate. +final ReceivePort port = ReceivePort(); + +/// Global [SharedPreferences] object. +SharedPreferences prefs; +Future main() async { + // TODO(bkonyi): uncomment WidgetsFlutterBinding.ensureInitialized(); - // Start the AlarmManager service. - await AndroidAlarmManager.initialize(); - - printMessage("main run"); - runApp(const Center( - child: - Text('See device log for output', textDirection: TextDirection.ltr))); - await AndroidAlarmManager.periodic( - const Duration(seconds: 5), periodicID, printPeriodic, - wakeup: true, exact: true); - await AndroidAlarmManager.oneShot( - const Duration(seconds: 5), oneShotID, printOneShot); + // Register the UI isolate's SendPort to allow for communication from the + // background isolate. + IsolateNameServer.registerPortWithName( + port.sendPort, + isolateName, + ); + prefs = await SharedPreferences.getInstance(); + if (!prefs.containsKey(countKey)) { + await prefs.setInt(countKey, 0); + } + runApp(AlarmManagerExampleApp()); +} + +/// Example app for Espresso plugin. +class AlarmManagerExampleApp extends StatelessWidget { + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + home: _AlarmHomePage(title: 'Flutter Demo Home Page'), + ); + } +} + +class _AlarmHomePage extends StatefulWidget { + _AlarmHomePage({Key key, this.title}) : super(key: key); + final String title; + + @override + _AlarmHomePageState createState() => _AlarmHomePageState(); +} + +class _AlarmHomePageState extends State<_AlarmHomePage> { + int _counter = 0; + + @override + void initState() { + super.initState(); + AndroidAlarmManager.initialize(); + + // Register for events from the background isolate. These messages will + // always coincide with an alarm firing. + port.listen((_) async => await _incrementCounter()); + } + + Future _incrementCounter() async { + print('Increment counter!'); + + // Ensure we've loaded the updated count from the background isolate. + await prefs.reload(); + + setState(() { + _counter++; + }); + } + + // The background + static SendPort uiSendPort; + + // The callback for our alarm + static Future callback() async { + print('Alarm fired!'); + + // Get the previous cached count and increment it. + final prefs = await SharedPreferences.getInstance(); + int currentCount = prefs.getInt(countKey); + await prefs.setInt(countKey, currentCount + 1); + + // This will be null if we're running in the background. + uiSendPort ??= IsolateNameServer.lookupPortByName(isolateName); + uiSendPort?.send(null); + } + + @override + Widget build(BuildContext context) { + // TODO(jackson): This has been deprecated and should be replaced + // with `headline4` when it's available on all the versions of + // Flutter that we test. + // ignore: deprecated_member_use + final textStyle = Theme.of(context).textTheme.display1; + return Scaffold( + appBar: AppBar( + title: Text(widget.title), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Alarm fired $_counter times', + style: textStyle, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Total alarms fired: ', + style: textStyle, + ), + Text( + prefs.getInt(countKey).toString(), + key: ValueKey('BackgroundCountText'), + style: textStyle, + ), + ], + ), + RaisedButton( + child: Text( + 'Schedule OneShot Alarm', + ), + key: ValueKey('RegisterOneShotAlarm'), + onPressed: () async { + await AndroidAlarmManager.oneShot( + const Duration(seconds: 5), + // Ensure we have a unique alarm ID. + Random().nextInt(pow(2, 31)), + callback, + exact: true, + wakeup: true, + ); + }, + ), + ], + ), + ), + ); + } } diff --git a/packages/android_alarm_manager/example/pubspec.yaml b/packages/android_alarm_manager/example/pubspec.yaml index dbcf2c02b817..2fc191881c10 100644 --- a/packages/android_alarm_manager/example/pubspec.yaml +++ b/packages/android_alarm_manager/example/pubspec.yaml @@ -6,11 +6,12 @@ dependencies: sdk: flutter android_alarm_manager: path: ../ - e2e: ^0.2.1 + shared_preferences: ^0.5.6 + e2e: 0.3.0 path_provider: ^1.3.1 - dev_dependencies: + espresso: ^0.0.1+3 flutter_driver: sdk: flutter flutter_test: diff --git a/packages/android_alarm_manager/example/test_driver/android_alarm_manager_e2e.dart b/packages/android_alarm_manager/example/test_driver/android_alarm_manager_e2e.dart index 8359bfd59ef2..a5bc1ac0ba48 100644 --- a/packages/android_alarm_manager/example/test_driver/android_alarm_manager_e2e.dart +++ b/packages/android_alarm_manager/example/test_driver/android_alarm_manager_e2e.dart @@ -4,9 +4,11 @@ import 'dart:async'; import 'dart:io'; +import 'package:android_alarm_manager_example/main.dart' as app; import 'package:android_alarm_manager/android_alarm_manager.dart'; import 'package:e2e/e2e.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:flutter_driver/driver_extension.dart'; import 'package:path_provider/path_provider.dart'; // From https://flutter.dev/docs/cookbook/persistence/reading-writing-files @@ -44,14 +46,17 @@ Future readCounter() async { Future incrementCounter() async { final int value = await readCounter(); - print('incrementCounter to: ${value + 1}'); await writeCounter(value + 1); } +void appMain() { + enableFlutterDriverExtension(); + app.main(); +} + void main() { E2EWidgetsFlutterBinding.ensureInitialized(); - print('main'); setUp(() async { await AndroidAlarmManager.initialize(); }); diff --git a/packages/android_alarm_manager/pubspec.yaml b/packages/android_alarm_manager/pubspec.yaml index 3efcbb439816..7bdf68f393bd 100644 --- a/packages/android_alarm_manager/pubspec.yaml +++ b/packages/android_alarm_manager/pubspec.yaml @@ -1,7 +1,7 @@ name: android_alarm_manager description: Flutter plugin for accessing the Android AlarmManager service, and running Dart code in the background when alarms fire. -version: 0.4.5+4 +version: 0.4.5+5 homepage: https://github.com/flutter/plugins/tree/master/packages/android_alarm_manager dependencies: From 536add25e5b7b5ce5c2d841b010726795f164a4c Mon Sep 17 00:00:00 2001 From: Tan Jay Jun Date: Mon, 9 Mar 2020 01:24:38 +0800 Subject: [PATCH 24/37] Remove unused variable (#2352) --- packages/google_sign_in/google_sign_in/CHANGELOG.md | 4 ++++ .../google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m | 1 - packages/google_sign_in/google_sign_in/pubspec.yaml | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/google_sign_in/google_sign_in/CHANGELOG.md b/packages/google_sign_in/google_sign_in/CHANGELOG.md index c3dab069e738..b5d7d8f02d56 100644 --- a/packages/google_sign_in/google_sign_in/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in/CHANGELOG.md @@ -1,3 +1,7 @@ +## 4.1.5 + +* Remove unused variable. + ## 4.1.4 * Make the pedantic dev_dependency explicit. diff --git a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m index dff3481ec16f..0790c1b8cf65 100644 --- a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m +++ b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m @@ -138,7 +138,6 @@ - (BOOL)setAccountRequest:(FlutterResult)request { } - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { - NSString *sourceApplication = options[UIApplicationOpenURLOptionsSourceApplicationKey]; return [[GIDSignIn sharedInstance] handleURL:url]; } diff --git a/packages/google_sign_in/google_sign_in/pubspec.yaml b/packages/google_sign_in/google_sign_in/pubspec.yaml index 70363f049f15..99cdef99e3a5 100644 --- a/packages/google_sign_in/google_sign_in/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in/pubspec.yaml @@ -2,7 +2,7 @@ name: google_sign_in description: Flutter plugin for Google Sign-In, a secure authentication system for signing in with a Google account on Android and iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/google_sign_in/google_sign_in -version: 4.1.4 +version: 4.1.5 flutter: plugin: From 1eba1a29debae287718ac16b506ef8a3a09bee38 Mon Sep 17 00:00:00 2001 From: Sebastian Roth Date: Sun, 8 Mar 2020 21:18:42 +0000 Subject: [PATCH 25/37] [android_intent] Bump to Flutter stable, remove deprecation warnings (#2586) * Bumps Flutter & Dart dependencies to stable * Uses spread operator to concisely build arguments * Refactors and cleans up the plugin a bit --- packages/android_intent/CHANGELOG.md | 8 ++++ packages/android_intent/android/build.gradle | 26 ----------- .../androidintent/AndroidIntentPlugin.java | 2 +- .../android/app/src/main/AndroidManifest.xml | 20 +++++---- .../EmbeddingV1Activity.java | 5 ++- .../androidintentexample/MainActivity.java | 12 ----- packages/android_intent/example/pubspec.yaml | 3 -- .../android_intent/lib/android_intent.dart | 44 ++++++++----------- packages/android_intent/pubspec.yaml | 6 +-- 9 files changed, 44 insertions(+), 82 deletions(-) delete mode 100644 packages/android_intent/example/android/app/src/main/java/io/flutter/plugins/androidintentexample/MainActivity.java diff --git a/packages/android_intent/CHANGELOG.md b/packages/android_intent/CHANGELOG.md index 47f1917e3e8a..6160ba54b003 100644 --- a/packages/android_intent/CHANGELOG.md +++ b/packages/android_intent/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.3.6+1 + +* Bump the minimum Flutter version to 1.12.13+hotfix.5. +* Bump the minimum Dart version to 2.3.0. +* Uses Darts spread operator to build plugin arguments internally. +* Remove deprecated API usage warning in AndroidIntentPlugin.java. +* Migrates the Android example to V2 embedding. + ## 0.3.6 * Marks the `action` parameter as optional diff --git a/packages/android_intent/android/build.gradle b/packages/android_intent/android/build.gradle index 008b49ff7719..d261dac7df1c 100644 --- a/packages/android_intent/android/build.gradle +++ b/packages/android_intent/android/build.gradle @@ -43,29 +43,3 @@ dependencies { testImplementation 'androidx.test:core:1.0.0' testImplementation 'org.robolectric:robolectric:4.3' } - -// TODO(mklim): Remove this hack once androidx.lifecycle is included on stable. https://github.com/flutter/flutter/issues/42348 -afterEvaluate { - def containsEmbeddingDependencies = false - for (def configuration : configurations.all) { - for (def dependency : configuration.dependencies) { - if (dependency.group == 'io.flutter' && - dependency.name.startsWith('flutter_embedding') && - dependency.isTransitive()) - { - containsEmbeddingDependencies = true - break - } - } - } - if (!containsEmbeddingDependencies) { - android { - dependencies { - def lifecycle_version = "1.1.1" - compileOnly "android.arch.lifecycle:runtime:$lifecycle_version" - compileOnly "android.arch.lifecycle:common:$lifecycle_version" - compileOnly "android.arch.lifecycle:common-java8:$lifecycle_version" - } - } - } -} diff --git a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/AndroidIntentPlugin.java b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/AndroidIntentPlugin.java index 10c807979162..2f35dfcf0372 100644 --- a/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/AndroidIntentPlugin.java +++ b/packages/android_intent/android/src/main/java/io/flutter/plugins/androidintent/AndroidIntentPlugin.java @@ -42,7 +42,7 @@ public static void registerWith(Registrar registrar) { public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { sender.setApplicationContext(binding.getApplicationContext()); sender.setActivity(null); - impl.startListening(binding.getFlutterEngine().getDartExecutor()); + impl.startListening(binding.getBinaryMessenger()); } @Override diff --git a/packages/android_intent/example/android/app/src/main/AndroidManifest.xml b/packages/android_intent/example/android/app/src/main/AndroidManifest.xml index 7d6fcd44834f..761c35fd64d8 100644 --- a/packages/android_intent/example/android/app/src/main/AndroidManifest.xml +++ b/packages/android_intent/example/android/app/src/main/AndroidManifest.xml @@ -11,25 +11,27 @@ android:label="android_intent_example" android:name="io.flutter.app.FlutterApplication"> - + + + + + diff --git a/packages/android_intent/example/android/app/src/main/java/io/flutter/plugins/androidintentexample/EmbeddingV1Activity.java b/packages/android_intent/example/android/app/src/main/java/io/flutter/plugins/androidintentexample/EmbeddingV1Activity.java index 95dc41a02ef7..1bbe89a4a4cb 100644 --- a/packages/android_intent/example/android/app/src/main/java/io/flutter/plugins/androidintentexample/EmbeddingV1Activity.java +++ b/packages/android_intent/example/android/app/src/main/java/io/flutter/plugins/androidintentexample/EmbeddingV1Activity.java @@ -6,12 +6,13 @@ import android.os.Bundle; import io.flutter.app.FlutterActivity; -import io.flutter.plugins.GeneratedPluginRegistrant; +import io.flutter.plugins.androidintent.AndroidIntentPlugin; public class EmbeddingV1Activity extends FlutterActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - GeneratedPluginRegistrant.registerWith(this); + AndroidIntentPlugin.registerWith( + registrarFor("io.flutter.plugins.androidintent.AndroidIntentPlugin")); } } diff --git a/packages/android_intent/example/android/app/src/main/java/io/flutter/plugins/androidintentexample/MainActivity.java b/packages/android_intent/example/android/app/src/main/java/io/flutter/plugins/androidintentexample/MainActivity.java deleted file mode 100644 index 56e0bab207d4..000000000000 --- a/packages/android_intent/example/android/app/src/main/java/io/flutter/plugins/androidintentexample/MainActivity.java +++ /dev/null @@ -1,12 +0,0 @@ -package io.flutter.plugins.androidintentexample; - -import io.flutter.embedding.android.FlutterActivity; -import io.flutter.embedding.engine.FlutterEngine; -import io.flutter.plugins.androidintent.AndroidIntentPlugin; - -public class MainActivity extends FlutterActivity { - @Override - public void configureFlutterEngine(FlutterEngine flutterEngine) { - flutterEngine.getPlugins().add(new AndroidIntentPlugin()); - } -} diff --git a/packages/android_intent/example/pubspec.yaml b/packages/android_intent/example/pubspec.yaml index 4418e9fb82c6..22ff833f8198 100644 --- a/packages/android_intent/example/pubspec.yaml +++ b/packages/android_intent/example/pubspec.yaml @@ -16,6 +16,3 @@ dev_dependencies: # The following section is specific to Flutter. flutter: uses-material-design: true - -environment: - flutter: ">=1.9.1+hotfix.2 <2.0.0" \ No newline at end of file diff --git a/packages/android_intent/lib/android_intent.dart b/packages/android_intent/lib/android_intent.dart index 26e270a3a79b..ff95299a93fd 100644 --- a/packages/android_intent/lib/android_intent.dart +++ b/packages/android_intent/lib/android_intent.dart @@ -134,31 +134,23 @@ class AndroidIntent { if (!_platform.isAndroid) { return; } - final Map args = {}; - if (action != null) { - args['action'] = action; - } - if (flags != null) { - args['flags'] = convertFlags(flags); - } - if (category != null) { - args['category'] = category; - } - if (data != null) { - args['data'] = data; - } - if (arguments != null) { - args['arguments'] = arguments; - } - if (package != null) { - args['package'] = package; - if (componentName != null) { - args['componentName'] = componentName; - } - } - if (type != null) { - args['type'] = type; - } - await _channel.invokeMethod('launch', args); + + await _channel.invokeMethod('launch', _buildArguments()); + } + + /// Constructs the map of arguments which is passed to the plugin. + Map _buildArguments() { + return { + if (action != null) 'action': action, + if (flags != null) 'flags': convertFlags(flags), + if (category != null) 'category': category, + if (data != null) 'data': data, + if (arguments != null) 'arguments': arguments, + if (package != null) ...{ + 'package': package, + if (componentName != null) 'componentName': componentName, + }, + if (type != null) 'type': type, + }; } } diff --git a/packages/android_intent/pubspec.yaml b/packages/android_intent/pubspec.yaml index 2faf45e915f6..82f6e187ace5 100644 --- a/packages/android_intent/pubspec.yaml +++ b/packages/android_intent/pubspec.yaml @@ -1,7 +1,7 @@ name: android_intent description: Flutter plugin for launching Android Intents. Not supported on iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/android_intent -version: 0.3.6 +version: 0.3.6+1 flutter: plugin: @@ -23,5 +23,5 @@ dev_dependencies: pedantic: ^1.8.0 environment: - sdk: ">=2.0.0-dev.28.0 <3.0.0" - flutter: ">=1.10.0 <2.0.0" + sdk: ">=2.3.0 <3.0.0" + flutter: ">=1.12.13+hotfix.5 <2.0.0" \ No newline at end of file From 467c7dbaec85522c45bd4e18e071766d06e4e439 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Mon, 9 Mar 2020 12:39:09 -0700 Subject: [PATCH 26/37] [in_app_purchase] Android: fix potential crash when casting in v1 embedding. (#2585) --- packages/in_app_purchase/CHANGELOG.md | 5 +++ .../inapppurchase/InAppPurchasePlugin.java | 2 +- .../InAppPurchasePluginTest.java | 40 +++++++++++++++++++ .../xcshareddata/WorkspaceSettings.xcsettings | 8 ---- packages/in_app_purchase/pubspec.yaml | 2 +- 5 files changed, 47 insertions(+), 10 deletions(-) create mode 100644 packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/InAppPurchasePluginTest.java delete mode 100644 packages/in_app_purchase/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/packages/in_app_purchase/CHANGELOG.md b/packages/in_app_purchase/CHANGELOG.md index d78df4f3f06f..9c454a8ee71c 100644 --- a/packages/in_app_purchase/CHANGELOG.md +++ b/packages/in_app_purchase/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.3.1+2 + +* Fix potential casting crash on Android v1 embedding when registering life cycle callbacks. +* Remove hard-coded legacy xcode build setting. + ## 0.3.1+1 * Add `pedantic` to dev_dependency. diff --git a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/InAppPurchasePlugin.java b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/InAppPurchasePlugin.java index b7edcfbcf5d5..de2080cfebf2 100644 --- a/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/InAppPurchasePlugin.java +++ b/packages/in_app_purchase/android/src/main/java/io/flutter/plugins/inapppurchase/InAppPurchasePlugin.java @@ -50,7 +50,7 @@ static final class MethodNames { public static void registerWith(Registrar registrar) { InAppPurchasePlugin plugin = new InAppPurchasePlugin(); plugin.setupMethodChannel(registrar.activity(), registrar.messenger(), registrar.context()); - ((Application) registrar.context()) + ((Application) registrar.context().getApplicationContext()) .registerActivityLifecycleCallbacks(plugin.methodCallHandler); } diff --git a/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/InAppPurchasePluginTest.java b/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/InAppPurchasePluginTest.java new file mode 100644 index 000000000000..0befa87e1d05 --- /dev/null +++ b/packages/in_app_purchase/example/android/app/src/test/java/io/flutter/plugins/inapppurchase/InAppPurchasePluginTest.java @@ -0,0 +1,40 @@ +// Copyright 2019 The Chromium 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.inapppurchase; + +import static org.mockito.Mockito.when; + +import android.app.Activity; +import android.app.Application; +import android.content.Context; +import io.flutter.plugin.common.BinaryMessenger; +import io.flutter.plugin.common.PluginRegistry; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +public class InAppPurchasePluginTest { + @Mock Activity activity; + @Mock Context context; + @Mock PluginRegistry.Registrar mockRegistrar; // For v1 embedding + @Mock BinaryMessenger mockMessenger; + @Mock Application mockApplication; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + when(mockRegistrar.activity()).thenReturn(activity); + when(mockRegistrar.messenger()).thenReturn(mockMessenger); + when(mockRegistrar.context()).thenReturn(context); + } + + @Test + public void registerWith_doNotCrashWhenRegisterContextIsActivity_V1Embedding() { + when(mockRegistrar.context()).thenReturn(activity); + when(activity.getApplicationContext()).thenReturn(mockApplication); + InAppPurchasePlugin.registerWith(mockRegistrar); + } +} diff --git a/packages/in_app_purchase/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/in_app_purchase/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index 949b67898200..000000000000 --- a/packages/in_app_purchase/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - BuildSystemType - Original - - diff --git a/packages/in_app_purchase/pubspec.yaml b/packages/in_app_purchase/pubspec.yaml index ff1f40443b22..b2fd2304ae5c 100644 --- a/packages/in_app_purchase/pubspec.yaml +++ b/packages/in_app_purchase/pubspec.yaml @@ -1,7 +1,7 @@ name: in_app_purchase description: A Flutter plugin for in-app purchases. Exposes APIs for making in-app purchases through the App Store and Google Play. homepage: https://github.com/flutter/plugins/tree/master/packages/in_app_purchase -version: 0.3.1+1 +version: 0.3.1+2 dependencies: From 7d93486a344607d003e089b4cb4b978e6b3e147b Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Mon, 9 Mar 2020 13:20:59 -0700 Subject: [PATCH 27/37] [connectivity] remove ios workspace setting for example app. (#2592) --- packages/connectivity/connectivity/CHANGELOG.md | 4 ++++ .../xcshareddata/WorkspaceSettings.xcsettings | 8 -------- packages/connectivity/connectivity/pubspec.yaml | 2 +- packages/connectivity/connectivity_macos/CHANGELOG.md | 4 ++++ .../xcshareddata/WorkspaceSettings.xcsettings | 8 -------- packages/connectivity/connectivity_macos/pubspec.yaml | 2 +- 6 files changed, 10 insertions(+), 18 deletions(-) delete mode 100644 packages/connectivity/connectivity/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings delete mode 100644 packages/connectivity/connectivity_macos/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/packages/connectivity/connectivity/CHANGELOG.md b/packages/connectivity/connectivity/CHANGELOG.md index b297f38f275e..c62abb4fa591 100644 --- a/packages/connectivity/connectivity/CHANGELOG.md +++ b/packages/connectivity/connectivity/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.8+2 + +* Remove hard coded ios workspace setting of the example app. + ## 0.4.8+1 * Make the pedantic dev_dependency explicit. diff --git a/packages/connectivity/connectivity/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/connectivity/connectivity/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index 949b67898200..000000000000 --- a/packages/connectivity/connectivity/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - BuildSystemType - Original - - diff --git a/packages/connectivity/connectivity/pubspec.yaml b/packages/connectivity/connectivity/pubspec.yaml index ce90f75719fe..73cfc2a277e0 100644 --- a/packages/connectivity/connectivity/pubspec.yaml +++ b/packages/connectivity/connectivity/pubspec.yaml @@ -2,7 +2,7 @@ name: connectivity description: Flutter plugin for discovering the state of the network (WiFi & mobile/cellular) connectivity on Android and iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity -version: 0.4.8+1 +version: 0.4.8+2 flutter: plugin: diff --git a/packages/connectivity/connectivity_macos/CHANGELOG.md b/packages/connectivity/connectivity_macos/CHANGELOG.md index 43db2ff8b8bd..1d4bfd607d33 100644 --- a/packages/connectivity/connectivity_macos/CHANGELOG.md +++ b/packages/connectivity/connectivity_macos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.0+2 + +* Remove hard coded ios workspace setting of the example app. + ## 0.1.0+1 * Make the pedantic dev_dependency explicit. diff --git a/packages/connectivity/connectivity_macos/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/connectivity/connectivity_macos/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index 949b67898200..000000000000 --- a/packages/connectivity/connectivity_macos/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - BuildSystemType - Original - - diff --git a/packages/connectivity/connectivity_macos/pubspec.yaml b/packages/connectivity/connectivity_macos/pubspec.yaml index 70ba24793782..64e4846c5f4d 100644 --- a/packages/connectivity/connectivity_macos/pubspec.yaml +++ b/packages/connectivity/connectivity_macos/pubspec.yaml @@ -1,6 +1,6 @@ name: connectivity_macos description: macOS implementation of the connectivity plugin. -version: 0.1.0+1 +version: 0.1.0+2 homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_macos flutter: From 4dec6709a336b4511ef391def251cdab1a0b3428 Mon Sep 17 00:00:00 2001 From: Sebastian Roth Date: Tue, 10 Mar 2020 14:49:23 +0000 Subject: [PATCH 28/37] [device_info] Update Android embedding to match latest Flutter stable release (#2590) * Update V2 plugin migration to match current flutter stable * Bump AGP to 3.6.1 --- packages/device_info/CHANGELOG.md | 7 +++++ packages/device_info/android/build.gradle | 28 +------------------ .../plugins/deviceinfo/DeviceInfoPlugin.java | 3 +- .../android/app/src/main/AndroidManifest.xml | 25 ++++++++++------- .../EmbeddingV1Activity.java | 4 +-- .../deviceinfoexample/MainActivity.java | 20 ------------- .../deviceinfoexample/MainActivityTest.java | 15 ---------- .../device_info/example/android/build.gradle | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 4 +-- packages/device_info/example/pubspec.yaml | 5 ---- packages/device_info/pubspec.yaml | 4 +-- 11 files changed, 31 insertions(+), 86 deletions(-) delete mode 100644 packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/MainActivity.java delete mode 100644 packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/MainActivityTest.java diff --git a/packages/device_info/CHANGELOG.md b/packages/device_info/CHANGELOG.md index 68aeed8c2cbf..c6f8fb2d2616 100644 --- a/packages/device_info/CHANGELOG.md +++ b/packages/device_info/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.4.2+1 + +* Bump the minimum Flutter version to 1.12.13+hotfix.5. +* Remove deprecated API usage warning in AndroidIntentPlugin.java. +* Migrates the Android example to V2 embedding. +* Bumps AGP to 3.6.1. + ## 0.4.2 * Add systemFeatures to AndroidDeviceInfo. diff --git a/packages/device_info/android/build.gradle b/packages/device_info/android/build.gradle index d1dd790732f1..58bdfd327631 100644 --- a/packages/device_info/android/build.gradle +++ b/packages/device_info/android/build.gradle @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.3.0' + classpath 'com.android.tools.build:gradle:3.6.1' } } @@ -32,29 +32,3 @@ android { disable 'InvalidPackage' } } - -// TODO(cyanglaz): Remove this hack once androidx.lifecycle is included on stable. https://github.com/flutter/flutter/issues/42348 -afterEvaluate { - def containsEmbeddingDependencies = false - for (def configuration : configurations.all) { - for (def dependency : configuration.dependencies) { - if (dependency.group == 'io.flutter' && - dependency.name.startsWith('flutter_embedding') && - dependency.isTransitive()) - { - containsEmbeddingDependencies = true - break - } - } - } - if (!containsEmbeddingDependencies) { - android { - dependencies { - def lifecycle_version = "1.1.1" - compileOnly "android.arch.lifecycle:runtime:$lifecycle_version" - compileOnly "android.arch.lifecycle:common:$lifecycle_version" - compileOnly "android.arch.lifecycle:common-java8:$lifecycle_version" - } - } - } -} diff --git a/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java b/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java index a0435a46e837..8061959c2047 100644 --- a/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java +++ b/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java @@ -23,8 +23,7 @@ public static void registerWith(Registrar registrar) { @Override public void onAttachedToEngine(FlutterPlugin.FlutterPluginBinding binding) { - setupMethodChannel( - binding.getFlutterEngine().getDartExecutor(), binding.getApplicationContext()); + setupMethodChannel(binding.getBinaryMessenger(), binding.getApplicationContext()); } @Override diff --git a/packages/device_info/example/android/app/src/main/AndroidManifest.xml b/packages/device_info/example/android/app/src/main/AndroidManifest.xml index 45242ab08b69..f9f91fa39dae 100644 --- a/packages/device_info/example/android/app/src/main/AndroidManifest.xml +++ b/packages/device_info/example/android/app/src/main/AndroidManifest.xml @@ -12,15 +12,20 @@ android:exported="true" android:windowSoftInputMode="adjustResize"> - - - - - - + + + + + + + + + diff --git a/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1Activity.java b/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1Activity.java index 0bfaee848dbf..48678a7e6ad1 100644 --- a/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1Activity.java +++ b/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/EmbeddingV1Activity.java @@ -6,12 +6,12 @@ import android.os.Bundle; import io.flutter.app.FlutterActivity; -import io.flutter.plugins.GeneratedPluginRegistrant; +import io.flutter.plugins.deviceinfo.DeviceInfoPlugin; public class EmbeddingV1Activity extends FlutterActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - GeneratedPluginRegistrant.registerWith(this); + DeviceInfoPlugin.registerWith(registrarFor("io.flutter.plugins.deviceinfo.DeviceInfoPlugin")); } } diff --git a/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/MainActivity.java b/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/MainActivity.java deleted file mode 100644 index b820542706e0..000000000000 --- a/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/MainActivity.java +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2019 The Chromium 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.deviceinfoexample; - -import io.flutter.embedding.android.FlutterActivity; -import io.flutter.embedding.engine.FlutterEngine; -import io.flutter.plugins.deviceinfo.DeviceInfoPlugin; - -public class MainActivity extends FlutterActivity { - - // TODO(cyanglaz): Remove this once v2 of GeneratedPluginRegistrant rolls to stable. - // https://github.com/flutter/flutter/issues/42694 - @Override - public void configureFlutterEngine(FlutterEngine flutterEngine) { - super.configureFlutterEngine(flutterEngine); - flutterEngine.getPlugins().add(new DeviceInfoPlugin()); - } -} diff --git a/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/MainActivityTest.java b/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/MainActivityTest.java deleted file mode 100644 index 36967ebf4564..000000000000 --- a/packages/device_info/example/android/app/src/main/java/io/flutter/plugins/deviceinfoexample/MainActivityTest.java +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2019 The Chromium 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.deviceinfoexample; - -import androidx.test.rule.ActivityTestRule; -import dev.flutter.plugins.e2e.FlutterRunner; -import org.junit.Rule; -import org.junit.runner.RunWith; - -@RunWith(FlutterRunner.class) -public class MainActivityTest { - @Rule public ActivityTestRule rule = new ActivityTestRule<>(MainActivity.class); -} diff --git a/packages/device_info/example/android/build.gradle b/packages/device_info/example/android/build.gradle index 541636cc492a..83f114c21e31 100644 --- a/packages/device_info/example/android/build.gradle +++ b/packages/device_info/example/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.3.0' + classpath 'com.android.tools.build:gradle:3.6.1' } } diff --git a/packages/device_info/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/device_info/example/android/gradle/wrapper/gradle-wrapper.properties index 2819f022f1fd..c243e25a0fff 100644 --- a/packages/device_info/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/device_info/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Fri Jun 23 08:50:38 CEST 2017 +#Mon Mar 09 11:05:13 GMT 2020 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip diff --git a/packages/device_info/example/pubspec.yaml b/packages/device_info/example/pubspec.yaml index 89bf430d971c..dc63d8b66126 100644 --- a/packages/device_info/example/pubspec.yaml +++ b/packages/device_info/example/pubspec.yaml @@ -15,8 +15,3 @@ dev_dependencies: flutter: uses-material-design: true - -environment: - sdk: ">=2.0.0-dev.28.0 <3.0.0" - flutter: ">=1.9.1+hotfix.2 <2.0.0" - diff --git a/packages/device_info/pubspec.yaml b/packages/device_info/pubspec.yaml index 06a530bcaab7..0769f98c83c3 100644 --- a/packages/device_info/pubspec.yaml +++ b/packages/device_info/pubspec.yaml @@ -2,7 +2,7 @@ name: device_info description: Flutter plugin providing detailed information about the device (make, model, etc.), and Android or iOS version the app is running on. homepage: https://github.com/flutter/plugins/tree/master/packages/device_info -version: 0.4.2 +version: 0.4.2+1 flutter: plugin: @@ -26,4 +26,4 @@ dev_dependencies: environment: sdk: ">=2.0.0-dev.28.0 <3.0.0" - flutter: ">=1.10.0 <2.0.0" + flutter: ">=1.12.13+hotfix.5 <2.0.0" From 93f3f6efc7214867ab19a012debc56527a95a44c Mon Sep 17 00:00:00 2001 From: Cristian Zazo Date: Tue, 10 Mar 2020 17:58:53 +0100 Subject: [PATCH 29/37] [shared_preferences] Fix deprecated API call (#2536) --- packages/shared_preferences/shared_preferences/CHANGELOG.md | 4 ++++ .../plugins/sharedpreferences/SharedPreferencesPlugin.java | 2 +- packages/shared_preferences/shared_preferences/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/shared_preferences/shared_preferences/CHANGELOG.md b/packages/shared_preferences/shared_preferences/CHANGELOG.md index 6757f22bae08..256b084816e9 100644 --- a/packages/shared_preferences/shared_preferences/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.6+3 + +* Fix deprecated API usage warning. + ## 0.5.6+2 * Make the pedantic dev_dependency explicit. diff --git a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java index 90cc96494c34..859610e3d66a 100644 --- a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java +++ b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java @@ -22,7 +22,7 @@ public static void registerWith(PluginRegistry.Registrar registrar) { @Override public void onAttachedToEngine(FlutterPlugin.FlutterPluginBinding binding) { - setupChannel(binding.getFlutterEngine().getDartExecutor(), binding.getApplicationContext()); + setupChannel(binding.getBinaryMessenger(), binding.getApplicationContext()); } @Override diff --git a/packages/shared_preferences/shared_preferences/pubspec.yaml b/packages/shared_preferences/shared_preferences/pubspec.yaml index d0cb26c7c994..099c95220b7d 100644 --- a/packages/shared_preferences/shared_preferences/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/pubspec.yaml @@ -2,7 +2,7 @@ name: shared_preferences description: Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android. homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences -version: 0.5.6+2 +version: 0.5.6+3 flutter: plugin: From 3bb18edbcdc95a80e0fae3bc5c3fd76296ed9a06 Mon Sep 17 00:00:00 2001 From: Conner Kasten Date: Wed, 11 Mar 2020 12:38:38 -0700 Subject: [PATCH 30/37] [google_sign_in] Add new Oauth scope methods to google_sign_in_platform_interface. (#2547) --- .../google_sign_in_platform_interface/CHANGELOG.md | 5 +++++ .../lib/google_sign_in_platform_interface.dart | 8 ++++++++ .../lib/src/method_channel_google_sign_in.dart | 8 ++++++++ .../google_sign_in_platform_interface/pubspec.yaml | 2 +- .../test/method_channel_google_sign_in_test.dart | 5 +++++ 5 files changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/google_sign_in/google_sign_in_platform_interface/CHANGELOG.md b/packages/google_sign_in/google_sign_in_platform_interface/CHANGELOG.md index 7819e747ecd4..c0627df8c1da 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in_platform_interface/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.1.0 + +* Add hasRequestedScope method to determine if an Oauth scope has been granted. +* Add requestScope Method to request new Oauth scopes be granted by the user. + ## 1.0.4 * Make the pedantic dev_dependency explicit. diff --git a/packages/google_sign_in/google_sign_in_platform_interface/lib/google_sign_in_platform_interface.dart b/packages/google_sign_in/google_sign_in_platform_interface/lib/google_sign_in_platform_interface.dart index 01230150c1d0..966e93551086 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/lib/google_sign_in_platform_interface.dart +++ b/packages/google_sign_in/google_sign_in_platform_interface/lib/google_sign_in_platform_interface.dart @@ -121,4 +121,12 @@ abstract class GoogleSignInPlatform { Future clearAuthCache({@required String token}) async { throw UnimplementedError('clearAuthCache() has not been implemented.'); } + + /// Requests the user grants additional Oauth [scopes]. + /// + /// Scopes should come from the full list + /// [here](https://developers.google.com/identity/protocols/googlescopes). + Future requestScopes(List scopes) async { + throw UnimplementedError('requestScopes() has not been implmented.'); + } } diff --git a/packages/google_sign_in/google_sign_in_platform_interface/lib/src/method_channel_google_sign_in.dart b/packages/google_sign_in/google_sign_in_platform_interface/lib/src/method_channel_google_sign_in.dart index 1d1eb64edd92..4d2a34fe0fe7 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/lib/src/method_channel_google_sign_in.dart +++ b/packages/google_sign_in/google_sign_in_platform_interface/lib/src/method_channel_google_sign_in.dart @@ -78,4 +78,12 @@ class MethodChannelGoogleSignIn extends GoogleSignInPlatform { {'token': token}, ); } + + @override + Future requestScopes(List scopes) { + return channel.invokeMethod( + 'requestScopes', + >{'scopes': scopes}, + ); + } } diff --git a/packages/google_sign_in/google_sign_in_platform_interface/pubspec.yaml b/packages/google_sign_in/google_sign_in_platform_interface/pubspec.yaml index 23937e2511ef..d1f7abc291c4 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the google_sign_in plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/google_sign_in/google_sign_in_platform_interface # 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.4 +version: 1.1.0 dependencies: flutter: diff --git a/packages/google_sign_in/google_sign_in_platform_interface/test/method_channel_google_sign_in_test.dart b/packages/google_sign_in/google_sign_in_platform_interface/test/method_channel_google_sign_in_test.dart index 13de6acf0748..6a8f73736004 100644 --- a/packages/google_sign_in/google_sign_in_platform_interface/test/method_channel_google_sign_in_test.dart +++ b/packages/google_sign_in/google_sign_in_platform_interface/test/method_channel_google_sign_in_test.dart @@ -114,6 +114,11 @@ void main() { }: isMethodCall('clearAuthCache', arguments: { 'token': 'abc', }), + () { + googleSignIn.requestScopes(['newScope', 'anotherScope']); + }: isMethodCall('requestScopes', arguments: { + 'scopes': ['newScope', 'anotherScope'], + }), googleSignIn.signOut: isMethodCall('signOut', arguments: null), googleSignIn.disconnect: isMethodCall('disconnect', arguments: null), googleSignIn.isSignedIn: isMethodCall('isSignedIn', arguments: null), From 7cac56173e66b8daa56aafd65f8fd20c6a98df37 Mon Sep 17 00:00:00 2001 From: Conner Kasten Date: Mon, 10 Feb 2020 09:52:28 -0800 Subject: [PATCH 31/37] Add scope handling methods to google_sign_in_web. --- .../lib/google_sign_in_web.dart | 25 +++++++++++++++++++ .../google_sign_in_web/test/auth2_test.dart | 12 +++++++++ .../test/gapi_mocks/src/google_user.dart | 2 ++ 3 files changed, 39 insertions(+) diff --git a/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart b/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart index 4004d47d5551..cbef3c40892f 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart @@ -176,4 +176,29 @@ class GoogleSignInPlugin extends GoogleSignInPlatform { return auth2.getAuthInstance().disconnect(); } + + @override + Future hasGrantedScope(String scope) async { + await initialized; + + return auth2 + .getAuthInstance() + ?.currentUser + ?.get() + ?.getGrantedScopes() + ?.contains(scope) ?? + false; + } + + @override + Future requestScope(String scope) async { + await initialized; + + return auth2 + .getAuthInstance() + ?.currentUser + ?.get() + ?.grant(auth2.SigninOptions(scope: scope)) ?? + false; + } } diff --git a/packages/google_sign_in/google_sign_in_web/test/auth2_test.dart b/packages/google_sign_in/google_sign_in_web/test/auth2_test.dart index 7a3a01227169..2ba01dc8801a 100644 --- a/packages/google_sign_in/google_sign_in_web/test/auth2_test.dart +++ b/packages/google_sign_in/google_sign_in_web/test/auth2_test.dart @@ -73,5 +73,17 @@ void main() { expect(actualToken, expectedTokenData); }); + + test('hasGrantedScope', () async { + bool hasScope = await plugin.hasGrantedScope('scope'); + + expect(hasScope, isTrue); + }); + + test('requestScope', () async { + bool scopeGranted = await plugin.requestScope('newScope'); + + expect(scopeGranted, isTrue); + }); }); } diff --git a/packages/google_sign_in/google_sign_in_web/test/gapi_mocks/src/google_user.dart b/packages/google_sign_in/google_sign_in_web/test/gapi_mocks/src/google_user.dart index 9f2b7b9bf6fa..15993bb56d8a 100644 --- a/packages/google_sign_in/google_sign_in_web/test/gapi_mocks/src/google_user.dart +++ b/packages/google_sign_in/google_sign_in_web/test/gapi_mocks/src/google_user.dart @@ -21,5 +21,7 @@ String googleUser(GoogleSignInUserData data) => ''' access_token: 'access_${data.idToken}', } }, + getGrantedScopes: () => 'some scope', + grant: () => true, } '''; From 567b133ed30808ad5c83d8a6ffd2500e61823ea4 Mon Sep 17 00:00:00 2001 From: Conner Kasten Date: Mon, 10 Feb 2020 10:30:58 -0800 Subject: [PATCH 32/37] Update version and changelog for web plugin. --- packages/google_sign_in/google_sign_in_web/CHANGELOG.md | 4 ++++ packages/google_sign_in/google_sign_in_web/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/google_sign_in/google_sign_in_web/CHANGELOG.md b/packages/google_sign_in/google_sign_in_web/CHANGELOG.md index 7f1e88be166f..cc53a1aa50b9 100644 --- a/packages/google_sign_in/google_sign_in_web/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in_web/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.9.0 + +* Add support for methods introduced in `google_sign_in_platform_interface` 1.1.0. + ## 0.8.3+2 * Make the pedantic dev_dependency explicit. diff --git a/packages/google_sign_in/google_sign_in_web/pubspec.yaml b/packages/google_sign_in/google_sign_in_web/pubspec.yaml index 91a002bd6ad2..9f2ce2636b21 100644 --- a/packages/google_sign_in/google_sign_in_web/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in_web/pubspec.yaml @@ -2,7 +2,7 @@ name: google_sign_in_web description: Flutter plugin for Google Sign-In, a secure authentication system for signing in with a Google account on Android, iOS and Web. homepage: https://github.com/flutter/plugins/tree/master/packages/google_sign_in/google_sign_in_web -version: 0.8.3+2 +version: 0.9.0 flutter: plugin: @@ -12,7 +12,7 @@ flutter: fileName: google_sign_in_web.dart dependencies: - google_sign_in_platform_interface: ^1.0.0 + google_sign_in_platform_interface: ^1.1.0 flutter: sdk: flutter flutter_web_plugins: From 822b3360c7d93fa5586194a3f254d8bde29a8a3b Mon Sep 17 00:00:00 2001 From: Conner Kasten Date: Mon, 10 Feb 2020 09:54:03 -0800 Subject: [PATCH 33/37] Add scope handling methods to google_sign_in. --- .../googlesignin/GoogleSignInPlugin.java | 41 +++++++++++++++++ .../ios/Classes/FLTGoogleSignInPlugin.m | 10 +++++ .../google_sign_in/lib/google_sign_in.dart | 12 +++++ .../test/google_sign_in_test.dart | 44 +++++++++++++++++++ 4 files changed, 107 insertions(+) diff --git a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java index 6c9bedde1038..2407f794c21d 100755 --- a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java +++ b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java @@ -46,6 +46,8 @@ public class GoogleSignInPlugin implements MethodCallHandler { private static final String METHOD_DISCONNECT = "disconnect"; private static final String METHOD_IS_SIGNED_IN = "isSignedIn"; private static final String METHOD_CLEAR_AUTH_CACHE = "clearAuthCache"; + private static final String METHOD_HAS_GRANTED_SCOPE = "hasGrantedScope"; + private static final String METHOD_REQUEST_SCOPE = "requestScope"; private final IDelegate delegate; @@ -100,6 +102,16 @@ public void onMethodCall(MethodCall call, Result result) { delegate.isSignedIn(result); break; + case METHOD_HAS_GRANTED_SCOPE: + String scope = call.argument("scope"); + delegate.hasGrantedScope(result, scope); + break; + + case METHOD_REQUEST_SCOPE: + scope = call.argument("scope"); + delegate.requestScope(result, scope); + break; + default: result.notImplemented(); } @@ -153,6 +165,12 @@ public void init( /** Checks if there is a signed in user. */ public void isSignedIn(Result result); + + /** Checks to see if the passed Oauth scope has been granted by the user. */ + public void hasGrantedScope(final Result result, final String scope); + + /** Prompts the user to grant an additional Oauth scope. */ + public void requestScope(final Result result, final String scope); } /** @@ -167,6 +185,7 @@ public void init( public static final class Delegate implements IDelegate, PluginRegistry.ActivityResultListener { private static final int REQUEST_CODE_SIGNIN = 53293; private static final int REQUEST_CODE_RECOVER_AUTH = 53294; + private static final int REQUEST_CODE_REQUEST_SCOPE = 53295; private static final String ERROR_REASON_EXCEPTION = "exception"; private static final String ERROR_REASON_STATUS = "status"; @@ -343,6 +362,25 @@ public void isSignedIn(final Result result) { result.success(value); } + @Override + public void hasGrantedScope(Result result, String scope) { + GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(registrar.context()); + boolean value = account != null && GoogleSignIn.hasPermissions(account, new Scope(scope)); + result.success(value); + } + + @Override + public void requestScope(Result result, String scope) { + GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(registrar.context()); + if (account != null) { + GoogleSignIn.requestPermissions( + registrar.activity(), + REQUEST_CODE_REQUEST_SCOPE, + account, + new Scope(scope)); + } + } + private void onSignInResult(Task completedTask) { try { GoogleSignInAccount account = completedTask.getResult(ApiException.class); @@ -527,6 +565,9 @@ public boolean onActivityResult(int requestCode, int resultCode, Intent data) { finishWithError(ERROR_REASON_SIGN_IN_FAILED, "Signin failed"); } return true; + case REQUEST_CODE_REQUEST_SCOPE: + pendingOperation.result.success(resultCode == Activity.RESULT_OK); + return true; default: return false; } diff --git a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m index 0790c1b8cf65..5f31c5230efc 100644 --- a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m +++ b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m @@ -121,6 +121,16 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result // There's nothing to be done here on iOS since the expired/invalid // tokens are refreshed automatically by getTokensWithHandler. result(nil); + } else if ([call.method isEqualToString:@"hasGrantedScope"]) { + GIDGoogleUser *user = [GIDSignIn sharedInstance].currentUser; + NSString *scope = call.arguments[@"scope"]; + bool success = [user.grantedScopes containsObject:scope]; + result(@(success)); + } else if ([call.method isEqualToString:@"requestScope"]) { + NSArray *currentScopes = [GIDSignIn sharedInstance].scopes; + NSString *scope = call.arguments[@"scope"]; + [GIDSignIn sharedInstance].scopes = [currentScopes arrayByAddingObject:scope]; + [[GIDSignIn sharedInstance] signIn]; } else { result(FlutterMethodNotImplemented); } diff --git a/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart b/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart index 09753377ac76..0585115e6e89 100644 --- a/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart +++ b/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart @@ -367,4 +367,16 @@ class GoogleSignIn { /// authentication. Future disconnect() => _addMethodCall(GoogleSignInPlatform.instance.disconnect); + + /// Indicates whether this Oauth [scope] has been granted. + Future hasGrantedScope(String scope) async { + await _ensureInitialized(); + return GoogleSignInPlatform.instance.hasGrantedScope(scope); + } + + /// Requests the user grant an additional Oauth [scope]. + Future requestScope(String scope) async { + await _ensureInitialized(); + return GoogleSignInPlatform.instance.requestScope(scope); + } } diff --git a/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart b/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart index a85fb0f27e42..f0bc49f0f3f5 100755 --- a/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart +++ b/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart @@ -32,6 +32,8 @@ void main() { 'signOut': null, 'disconnect': null, 'isSignedIn': true, + 'hasGrantedScope': true, + 'requestScope': true, 'getTokens': { 'idToken': '123', 'accessToken': '456', @@ -379,6 +381,48 @@ void main() { ], ); }); + + test('hasGrantedScope returns true if scope is granted', () async { + await googleSignIn.signIn(); + final result = await googleSignIn.hasGrantedScope('testScope'); + + expect(result, isTrue); + expect( + log, + [ + isMethodCall('init', arguments: { + 'signInOption': 'SignInOption.standard', + 'scopes': [], + 'hostedDomain': null, + }), + isMethodCall('signIn', arguments: null), + isMethodCall('hasGrantedScope', arguments: { + 'scope': 'testScope', + }), + ], + ); + }); + + test('requestScope returns true once new scope is granted', () async { + await googleSignIn.signIn(); + final result = await googleSignIn.requestScope('testScope'); + + expect(result, isTrue); + expect( + log, + [ + isMethodCall('init', arguments: { + 'signInOption': 'SignInOption.standard', + 'scopes': [], + 'hostedDomain': null, + }), + isMethodCall('signIn', arguments: null), + isMethodCall('requestScope', arguments: { + 'scope': 'testScope', + }), + ], + ); + }); }); group('GoogleSignIn with fake backend', () { From 9a3f7907f013c162d5b274beb05178dd79ca6257 Mon Sep 17 00:00:00 2001 From: Conner Kasten Date: Mon, 10 Feb 2020 10:31:22 -0800 Subject: [PATCH 34/37] Update version for main plugin. --- packages/google_sign_in/google_sign_in/CHANGELOG.md | 4 ++++ packages/google_sign_in/google_sign_in/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/google_sign_in/google_sign_in/CHANGELOG.md b/packages/google_sign_in/google_sign_in/CHANGELOG.md index b5d7d8f02d56..831901e47ceb 100644 --- a/packages/google_sign_in/google_sign_in/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in/CHANGELOG.md @@ -1,3 +1,7 @@ +## 4.2.0 + +* Add support for method introduced in `google_sign_in_platform_interface` 1.1.0. + ## 4.1.5 * Remove unused variable. diff --git a/packages/google_sign_in/google_sign_in/pubspec.yaml b/packages/google_sign_in/google_sign_in/pubspec.yaml index 99cdef99e3a5..46d8b340a1c7 100644 --- a/packages/google_sign_in/google_sign_in/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in/pubspec.yaml @@ -2,7 +2,7 @@ name: google_sign_in description: Flutter plugin for Google Sign-In, a secure authentication system for signing in with a Google account on Android and iOS. homepage: https://github.com/flutter/plugins/tree/master/packages/google_sign_in/google_sign_in -version: 4.1.5 +version: 4.2.0 flutter: plugin: @@ -16,7 +16,7 @@ flutter: default_package: google_sign_in_web dependencies: - google_sign_in_platform_interface: ^1.0.0 + google_sign_in_platform_interface: ^1.1.0 flutter: sdk: flutter meta: ^1.0.4 From 647699e0d148b5bfad1a800a7647fee6ad2c5e04 Mon Sep 17 00:00:00 2001 From: Conner Kasten Date: Thu, 27 Feb 2020 08:34:11 -0800 Subject: [PATCH 35/37] Fix GoogleSignInPlugin.java formatting. --- .../io/flutter/plugins/googlesignin/GoogleSignInPlugin.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java index 2407f794c21d..17445df0e6d4 100755 --- a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java +++ b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java @@ -374,10 +374,7 @@ public void requestScope(Result result, String scope) { GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(registrar.context()); if (account != null) { GoogleSignIn.requestPermissions( - registrar.activity(), - REQUEST_CODE_REQUEST_SCOPE, - account, - new Scope(scope)); + registrar.activity(), REQUEST_CODE_REQUEST_SCOPE, account, new Scope(scope)); } } From c8306dde0a2e279f58804d961ccd3d68389825b4 Mon Sep 17 00:00:00 2001 From: Conner Kasten Date: Thu, 27 Feb 2020 13:45:24 -0800 Subject: [PATCH 36/37] Implement requesting multiple scopes on all platforms. --- .../googlesignin/GoogleSignInPlugin.java | 17 +++++++++++------ .../ios/Classes/FLTGoogleSignInPlugin.m | 6 +++--- .../google_sign_in/lib/google_sign_in.dart | 4 ++-- .../test/google_sign_in_test.dart | 4 ++-- .../lib/google_sign_in_web.dart | 4 ++-- .../google_sign_in_web/test/auth2_test.dart | 2 +- 6 files changed, 21 insertions(+), 16 deletions(-) diff --git a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java index 17445df0e6d4..bda0f5da8d02 100755 --- a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java +++ b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java @@ -108,8 +108,8 @@ public void onMethodCall(MethodCall call, Result result) { break; case METHOD_REQUEST_SCOPE: - scope = call.argument("scope"); - delegate.requestScope(result, scope); + List scopes = call.argument("scope"); + delegate.requestScopes(result, scopes); break; default: @@ -169,8 +169,8 @@ public void init( /** Checks to see if the passed Oauth scope has been granted by the user. */ public void hasGrantedScope(final Result result, final String scope); - /** Prompts the user to grant an additional Oauth scope. */ - public void requestScope(final Result result, final String scope); + /** Prompts the user to grant an additional Oauth scopes. */ + public void requestScopes(final Result result, final List scopes); } /** @@ -370,11 +370,16 @@ public void hasGrantedScope(Result result, String scope) { } @Override - public void requestScope(Result result, String scope) { + public void requestScopes(Result result, List scopes) { GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(registrar.context()); if (account != null) { + Scope[] wrappedScopes = new Scope[scopes.size()]; + for (int i = 0; i < scopes.size(); i++) { + wrappedScopes[i] = new Scope(scopes.get(i)); + } + GoogleSignIn.requestPermissions( - registrar.activity(), REQUEST_CODE_REQUEST_SCOPE, account, new Scope(scope)); + registrar.activity(), REQUEST_CODE_REQUEST_SCOPE, account, wrappedScopes); } } diff --git a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m index 5f31c5230efc..b107122ab83c 100644 --- a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m +++ b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m @@ -126,10 +126,10 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result NSString *scope = call.arguments[@"scope"]; bool success = [user.grantedScopes containsObject:scope]; result(@(success)); - } else if ([call.method isEqualToString:@"requestScope"]) { + } else if ([call.method isEqualToString:@"requestScopes"]) { NSArray *currentScopes = [GIDSignIn sharedInstance].scopes; - NSString *scope = call.arguments[@"scope"]; - [GIDSignIn sharedInstance].scopes = [currentScopes arrayByAddingObject:scope]; + NSArray *scope = call.arguments[@"scopes"]; + [GIDSignIn sharedInstance].scopes = [currentScopes arrayByAddingObjectsFromArray:scopes]; [[GIDSignIn sharedInstance] signIn]; } else { result(FlutterMethodNotImplemented); diff --git a/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart b/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart index 0585115e6e89..99d818525f7c 100644 --- a/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart +++ b/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart @@ -375,8 +375,8 @@ class GoogleSignIn { } /// Requests the user grant an additional Oauth [scope]. - Future requestScope(String scope) async { + Future requestScopes(List scopes) async { await _ensureInitialized(); - return GoogleSignInPlatform.instance.requestScope(scope); + return GoogleSignInPlatform.instance.requestScopes(scopes); } } diff --git a/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart b/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart index f0bc49f0f3f5..f43b8aa41f6f 100755 --- a/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart +++ b/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart @@ -405,7 +405,7 @@ void main() { test('requestScope returns true once new scope is granted', () async { await googleSignIn.signIn(); - final result = await googleSignIn.requestScope('testScope'); + final result = await googleSignIn.requestScopes(['testScope']); expect(result, isTrue); expect( @@ -418,7 +418,7 @@ void main() { }), isMethodCall('signIn', arguments: null), isMethodCall('requestScope', arguments: { - 'scope': 'testScope', + 'scopes': ['testScope'], }), ], ); diff --git a/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart b/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart index cbef3c40892f..3034e9eaf4b8 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart @@ -191,14 +191,14 @@ class GoogleSignInPlugin extends GoogleSignInPlatform { } @override - Future requestScope(String scope) async { + Future requestScopes(List scopes) async { await initialized; return auth2 .getAuthInstance() ?.currentUser ?.get() - ?.grant(auth2.SigninOptions(scope: scope)) ?? + ?.grant(auth2.SigninOptions(scope: scopes.join(" "))) ?? false; } } diff --git a/packages/google_sign_in/google_sign_in_web/test/auth2_test.dart b/packages/google_sign_in/google_sign_in_web/test/auth2_test.dart index 2ba01dc8801a..f2db090b6434 100644 --- a/packages/google_sign_in/google_sign_in_web/test/auth2_test.dart +++ b/packages/google_sign_in/google_sign_in_web/test/auth2_test.dart @@ -81,7 +81,7 @@ void main() { }); test('requestScope', () async { - bool scopeGranted = await plugin.requestScope('newScope'); + bool scopeGranted = await plugin.requestScopes(['newScope']); expect(scopeGranted, isTrue); }); From 517c0bd6fdc77b8062810588b5f0f2030010b905 Mon Sep 17 00:00:00 2001 From: Conner Kasten Date: Fri, 28 Feb 2020 13:13:24 -0800 Subject: [PATCH 37/37] Remove listMissingScopes from implementations. --- .../googlesignin/GoogleSignInPlugin.java | 51 ++++++++++--------- .../ios/Classes/FLTGoogleSignInPlugin.m | 14 ++--- .../google_sign_in/lib/google_sign_in.dart | 8 +-- .../test/google_sign_in_test.dart | 28 ++-------- .../lib/google_sign_in_web.dart | 28 ++++------ .../google_sign_in_web/test/auth2_test.dart | 8 +-- 6 files changed, 49 insertions(+), 88 deletions(-) diff --git a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java index bda0f5da8d02..bffc68465b7c 100755 --- a/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java +++ b/packages/google_sign_in/google_sign_in/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java @@ -27,6 +27,7 @@ import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugin.common.PluginRegistry; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -46,8 +47,8 @@ public class GoogleSignInPlugin implements MethodCallHandler { private static final String METHOD_DISCONNECT = "disconnect"; private static final String METHOD_IS_SIGNED_IN = "isSignedIn"; private static final String METHOD_CLEAR_AUTH_CACHE = "clearAuthCache"; - private static final String METHOD_HAS_GRANTED_SCOPE = "hasGrantedScope"; - private static final String METHOD_REQUEST_SCOPE = "requestScope"; + private static final String METHOD_LIST_MISSING_SCOPES = "listMissingScopes"; + private static final String METHOD_REQUEST_SCOPES = "requestScopes"; private final IDelegate delegate; @@ -102,13 +103,8 @@ public void onMethodCall(MethodCall call, Result result) { delegate.isSignedIn(result); break; - case METHOD_HAS_GRANTED_SCOPE: - String scope = call.argument("scope"); - delegate.hasGrantedScope(result, scope); - break; - - case METHOD_REQUEST_SCOPE: - List scopes = call.argument("scope"); + case METHOD_REQUEST_SCOPES: + List scopes = call.argument("scopes"); delegate.requestScopes(result, scopes); break; @@ -166,9 +162,6 @@ public void init( /** Checks if there is a signed in user. */ public void isSignedIn(Result result); - /** Checks to see if the passed Oauth scope has been granted by the user. */ - public void hasGrantedScope(final Result result, final String scope); - /** Prompts the user to grant an additional Oauth scopes. */ public void requestScopes(final Result result, final List scopes); } @@ -362,25 +355,33 @@ public void isSignedIn(final Result result) { result.success(value); } - @Override - public void hasGrantedScope(Result result, String scope) { - GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(registrar.context()); - boolean value = account != null && GoogleSignIn.hasPermissions(account, new Scope(scope)); - result.success(value); - } - @Override public void requestScopes(Result result, List scopes) { GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(registrar.context()); - if (account != null) { - Scope[] wrappedScopes = new Scope[scopes.size()]; - for (int i = 0; i < scopes.size(); i++) { - wrappedScopes[i] = new Scope(scopes.get(i)); + if (account == null) { + result.error(ERROR_REASON_SIGN_IN_REQUIRED, "No account to grant scopes.", null); + return; + } + + List wrappedScopes = new ArrayList<>(); + + for (String scope : scopes) { + Scope wrappedScope = new Scope(scope); + if (!GoogleSignIn.hasPermissions(account, wrappedScope)) { + wrappedScopes.add(wrappedScope); } + } - GoogleSignIn.requestPermissions( - registrar.activity(), REQUEST_CODE_REQUEST_SCOPE, account, wrappedScopes); + if (wrappedScopes.isEmpty()) { + result.success(true); + return; } + + GoogleSignIn.requestPermissions( + registrar.activity(), + REQUEST_CODE_REQUEST_SCOPE, + account, + wrappedScopes.toArray(new Scope[0])); } private void onSignInResult(Task completedTask) { diff --git a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m index b107122ab83c..20e80c520f44 100644 --- a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m +++ b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m @@ -121,15 +121,15 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result // There's nothing to be done here on iOS since the expired/invalid // tokens are refreshed automatically by getTokensWithHandler. result(nil); - } else if ([call.method isEqualToString:@"hasGrantedScope"]) { - GIDGoogleUser *user = [GIDSignIn sharedInstance].currentUser; - NSString *scope = call.arguments[@"scope"]; - bool success = [user.grantedScopes containsObject:scope]; - result(@(success)); } else if ([call.method isEqualToString:@"requestScopes"]) { NSArray *currentScopes = [GIDSignIn sharedInstance].scopes; - NSArray *scope = call.arguments[@"scopes"]; - [GIDSignIn sharedInstance].scopes = [currentScopes arrayByAddingObjectsFromArray:scopes]; + NSArray *scopes = call.arguments[@"scopes"]; + NSArray *missingScopes = [scopes + filteredArrayUsingPredicate:[NSPredicate + predicateWithBlock:^BOOL(id scope, NSDictionary *bindings) { + return ![user.grantedScopes containsObject:scope]; + }]]; + [GIDSignIn sharedInstance].scopes = [currentScopes arrayByAddingObjectsFromArray:missingScopes]; [[GIDSignIn sharedInstance] signIn]; } else { result(FlutterMethodNotImplemented); diff --git a/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart b/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart index 99d818525f7c..7402c7a69816 100644 --- a/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart +++ b/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart @@ -368,13 +368,7 @@ class GoogleSignIn { Future disconnect() => _addMethodCall(GoogleSignInPlatform.instance.disconnect); - /// Indicates whether this Oauth [scope] has been granted. - Future hasGrantedScope(String scope) async { - await _ensureInitialized(); - return GoogleSignInPlatform.instance.hasGrantedScope(scope); - } - - /// Requests the user grant an additional Oauth [scope]. + /// Requests the user grants additional Oauth [scopes]. Future requestScopes(List scopes) async { await _ensureInitialized(); return GoogleSignInPlatform.instance.requestScopes(scopes); diff --git a/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart b/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart index f43b8aa41f6f..898c27fd9f7e 100755 --- a/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart +++ b/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart @@ -32,8 +32,7 @@ void main() { 'signOut': null, 'disconnect': null, 'isSignedIn': true, - 'hasGrantedScope': true, - 'requestScope': true, + 'requestScopes': true, 'getTokens': { 'idToken': '123', 'accessToken': '456', @@ -382,28 +381,7 @@ void main() { ); }); - test('hasGrantedScope returns true if scope is granted', () async { - await googleSignIn.signIn(); - final result = await googleSignIn.hasGrantedScope('testScope'); - - expect(result, isTrue); - expect( - log, - [ - isMethodCall('init', arguments: { - 'signInOption': 'SignInOption.standard', - 'scopes': [], - 'hostedDomain': null, - }), - isMethodCall('signIn', arguments: null), - isMethodCall('hasGrantedScope', arguments: { - 'scope': 'testScope', - }), - ], - ); - }); - - test('requestScope returns true once new scope is granted', () async { + test('requestScopes returns true once new scope is granted', () async { await googleSignIn.signIn(); final result = await googleSignIn.requestScopes(['testScope']); @@ -417,7 +395,7 @@ void main() { 'hostedDomain': null, }), isMethodCall('signIn', arguments: null), - isMethodCall('requestScope', arguments: { + isMethodCall('requestScopes', arguments: { 'scopes': ['testScope'], }), ], diff --git a/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart b/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart index 3034e9eaf4b8..bb43ba100c5d 100644 --- a/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart +++ b/packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart @@ -178,27 +178,21 @@ class GoogleSignInPlugin extends GoogleSignInPlatform { } @override - Future hasGrantedScope(String scope) async { + Future requestScopes(List scopes) async { await initialized; - return auth2 - .getAuthInstance() - ?.currentUser - ?.get() - ?.getGrantedScopes() - ?.contains(scope) ?? - false; - } + final currentUser = auth2.getAuthInstance()?.currentUser?.get(); - @override - Future requestScopes(List scopes) async { - await initialized; + if (currentUser == null) return false; + + final grantedScopes = currentUser.getGrantedScopes(); + final missingScopes = + scopes.where((scope) => !grantedScopes.contains(scope)); + + if (missingScopes.isEmpty) return true; - return auth2 - .getAuthInstance() - ?.currentUser - ?.get() - ?.grant(auth2.SigninOptions(scope: scopes.join(" "))) ?? + return currentUser + .grant(auth2.SigninOptions(scope: missingScopes.join(" "))) ?? false; } } diff --git a/packages/google_sign_in/google_sign_in_web/test/auth2_test.dart b/packages/google_sign_in/google_sign_in_web/test/auth2_test.dart index f2db090b6434..40bc8a404d06 100644 --- a/packages/google_sign_in/google_sign_in_web/test/auth2_test.dart +++ b/packages/google_sign_in/google_sign_in_web/test/auth2_test.dart @@ -74,13 +74,7 @@ void main() { expect(actualToken, expectedTokenData); }); - test('hasGrantedScope', () async { - bool hasScope = await plugin.hasGrantedScope('scope'); - - expect(hasScope, isTrue); - }); - - test('requestScope', () async { + test('requestScopes', () async { bool scopeGranted = await plugin.requestScopes(['newScope']); expect(scopeGranted, isTrue);